refactor #2
| @ -2,6 +2,7 @@ | ||||
|  | ||||
| static const char *TAG = "https_client"; | ||||
|  | ||||
| //HTTP GET data | ||||
| static const char *REQUEST = "GET " CONFIG_OTA_HTTPS_URL " HTTP/1.1\r\n" | ||||
|                              "Host: "CONFIG_OTA_HTTPS_SERVER_COMMON_NAME"\r\n" | ||||
|                              "User-Agent: esp-idf/1.0 esp32\r\n" | ||||
|  | ||||
| @ -2,13 +2,29 @@ | ||||
| #include "Mesh_Network.h" | ||||
|  | ||||
| static const char *LOG_TAG = "mesh_network"; | ||||
| static uint8_t tx_buf[CONFIG_MESH_MESSAGE_SIZE] = { 0, }; | ||||
| static uint8_t rx_buf[CONFIG_MESH_MESSAGE_SIZE] = { 0, }; | ||||
|  | ||||
|  | ||||
| //w: errMeshNetworkInitialize | ||||
| //r: errMeshNetworkInitialize;vMeshNetworkGetOwnAddr;errMeshNetworkGetChildren | ||||
| uint8_t u8ownMAC[6]; | ||||
|  | ||||
| //w: errMeshNetworkInitialize; vMeshNetworkMeshEventHandler | ||||
| //r: vMeshNetworkMeshEventHandler | ||||
| esp_netif_t* netif_sta; | ||||
|  | ||||
| //w: errMeshNetworkInitialize; vMeshNetworkMeshEventHandler | ||||
| //r: errMeshNetworkInitialize; | ||||
| bool bIsMeshConnected; | ||||
|  | ||||
| //w: errMeshNetworkInitialize; vMeshNetworkMeshEventHandler | ||||
| //r: vMeshNetworkMeshEventHandler | ||||
| int32_t i32MeshLayer; | ||||
|  | ||||
| //w: errMeshNetworkInitialize; vMeshNetworkMeshEventHandler | ||||
| //r: vMeshNetworkMeshEventHandler | ||||
| mesh_addr_t meshParentAddr; | ||||
|  | ||||
| //function pointer for callbacks | ||||
| void (*pAppRxHandle)(uint8_t*, uint8_t* ); | ||||
| void (*pOTAChildConnectHandle)(uint8_t* ); | ||||
| void (*pOTAMessageHandle)(MESH_PACKET_t* ); | ||||
| @ -47,7 +63,7 @@ esp_err_t errMeshNetworkInitialize() | ||||
|     ERROR_CHECK(esp_mesh_init()); | ||||
|  | ||||
|     //mesh initialization | ||||
|     ERROR_CHECK(esp_event_handler_register(MESH_EVENT, ESP_EVENT_ANY_ID, &vMeshEventHandler, NULL)); | ||||
|     ERROR_CHECK(esp_event_handler_register(MESH_EVENT, ESP_EVENT_ANY_ID, &vMeshNetworkMeshEventHandler, NULL)); | ||||
|  | ||||
|     //set mesh topology | ||||
|     ERROR_CHECK(esp_mesh_set_topology(CONFIG_MESH_TOPOLOGY)); | ||||
| @ -97,7 +113,7 @@ esp_err_t errMeshNetworkInitializeWiFi() | ||||
|     esp_err_t err = ESP_OK; | ||||
|     wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT(); | ||||
|     ERROR_CHECK(esp_wifi_init(&config)); | ||||
|     ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &vIPEventHandler, NULL)); | ||||
|     ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &vMeshNetworkIpEventHandler, NULL)); | ||||
|     ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_FLASH)); | ||||
|     ERROR_CHECK(esp_wifi_start()); | ||||
|     return err; | ||||
| @ -115,8 +131,88 @@ esp_err_t errMeshNetworkInitializeRouter(mesh_cfg_t* cfg) | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| esp_err_t errMeshNetworkSetChildConnectedHandle(void (*pChildConnectHandleTmp)(uint8_t * pu8Data)) | ||||
| { | ||||
|     pOTAChildConnectHandle = pChildConnectHandleTmp; | ||||
|     return ESP_OK; | ||||
| } | ||||
|  | ||||
| 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 | ||||
|     return ESP_OK; | ||||
| } | ||||
|  | ||||
| esp_err_t errMeshNetworkSetOTAMessageHandleHandle(void (*pOTAMessageHandleTmp)(MESH_PACKET_t* puMeshPacket)) | ||||
| { | ||||
|     pOTAMessageHandle = pOTAMessageHandleTmp; | ||||
|     return ESP_OK; | ||||
| } | ||||
|  | ||||
| esp_err_t errMeshNetworkSetChangeStateOfServerWorkerHandle(void (*pChangeStateOfServerWorkerHandleTmp)(bool bState)) | ||||
| { | ||||
|     pChangeStateOfServerWorkerHandle = pChangeStateOfServerWorkerHandleTmp; | ||||
|     return ESP_OK; | ||||
| } | ||||
|  | ||||
| esp_err_t errMeshNetworkSendMeshPacket(mesh_addr_t* pAddrDest, MESH_PACKET_t* pPacket) | ||||
| { | ||||
|     esp_err_t err; | ||||
|     mesh_data_t data; | ||||
|     uint8_t tx_buf[CONFIG_MESH_MESSAGE_SIZE] = { 0, }; | ||||
|     data.data = tx_buf; | ||||
|     data.size = sizeof(tx_buf); | ||||
|     data.proto = MESH_PROTO_BIN; | ||||
|     data.tos = MESH_TOS_P2P; | ||||
|     memcpy(tx_buf, (uint8_t *)pPacket, sizeof(MESH_PACKET_t)); | ||||
|  | ||||
|     err = esp_mesh_send(pAddrDest, &data, MESH_DATA_P2P, NULL, 0); | ||||
|  | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| bool bMeshNetworkIsRootNode() | ||||
| { | ||||
|     return esp_mesh_is_root(); | ||||
| } | ||||
|  | ||||
| bool bMeshNetworkIsNodeNeighbour(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 = errMeshNetworkGetParentNode(&addrParent); | ||||
|  | ||||
|     if(err == ESP_OK) | ||||
|         { | ||||
|             if(bMeshNetworkCheckMACEquality(pNode->addr,  addrParent.addr) == true) | ||||
|                 { | ||||
|                     bReturn = true; //node was found | ||||
|                 } | ||||
|         } | ||||
|  | ||||
|     if(bReturn == false) | ||||
|         { | ||||
|             err = ESP_OK; //reset error code | ||||
|  | ||||
|             ERROR_CHECK(errMeshNetworkGetChildren(childrenAddr, &u16ChildrenSize)); //get all children | ||||
|  | ||||
|             for (uint16_t u16Index = 0; ((u16Index < u16ChildrenSize) && (err == ESP_OK) && (bReturn == false)); u16Index++) | ||||
|                 { | ||||
|                     if(bMeshNetworkCheckMACEquality(pNode->addr,  childrenAddr[u16Index].addr) == true) | ||||
|                         { | ||||
|                             bReturn = true; //node was found | ||||
|                         } | ||||
|                 } | ||||
|         } | ||||
|     return bReturn; | ||||
| } | ||||
|  | ||||
| //returns true if MAC address is equal | ||||
| bool bCheckMACEquality(uint8_t* pu8aMAC,  uint8_t* pu8bMAC) | ||||
| bool bMeshNetworkCheckMACEquality(uint8_t* pu8aMAC,  uint8_t* pu8bMAC) | ||||
| { | ||||
|     bool bRet = true; | ||||
|     uint8_t index = 0; | ||||
| @ -141,7 +237,27 @@ bool bCheckMACEquality(uint8_t* pu8aMAC,  uint8_t* pu8bMAC) | ||||
|     return bRet; | ||||
| } | ||||
|  | ||||
| esp_err_t errGetChildren(mesh_addr_t* pChildren, uint16_t* pu16ChildrenSize) | ||||
| esp_err_t errMeshNetworkStartReceiveTask() | ||||
| { | ||||
|     esp_err_t err = ESP_OK; | ||||
|     BaseType_t xReturned; | ||||
|  | ||||
|     xReturned = xTaskCreate(vMeshNetworkTaskReceiveMeshData, "ReceiveMeshData", 7000, NULL, 5, NULL); | ||||
|  | ||||
|     if(xReturned != pdPASS) | ||||
|         { | ||||
|             err = ESP_FAIL; | ||||
|         } | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| void vMeshNetworkGetOwnAddr(mesh_addr_t* pMeshOwnAddr) | ||||
| { | ||||
|     memcpy(pMeshOwnAddr->addr, u8ownMAC, 6); | ||||
| } | ||||
|  | ||||
|  | ||||
| esp_err_t errMeshNetworkGetChildren(mesh_addr_t* pChildren, uint16_t* pu16ChildrenSize) | ||||
| { | ||||
|     esp_err_t err = ESP_OK; | ||||
|     int route_table_size = 0; | ||||
| @ -153,7 +269,7 @@ esp_err_t errGetChildren(mesh_addr_t* pChildren, uint16_t* pu16ChildrenSize) | ||||
|         { | ||||
|             for(uint16_t index = 0; index < esp_mesh_get_routing_table_size(); index++) | ||||
|                 { | ||||
|                     if(! (bCheckMACEquality(u8ownMAC, route_table[index].addr))  ) | ||||
|                     if(! (bMeshNetworkCheckMACEquality(u8ownMAC, route_table[index].addr))  ) | ||||
|                         { | ||||
|                             //child node | ||||
|                             //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]); | ||||
| @ -165,126 +281,12 @@ esp_err_t errGetChildren(mesh_addr_t* pChildren, uint16_t* pu16ChildrenSize) | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| esp_err_t errGetParentNode(mesh_addr_t* pMeshParentAddr) | ||||
| { | ||||
|     esp_err_t err = ESP_OK; | ||||
|  | ||||
|     if((bIsMeshConnected == false) || (esp_mesh_is_root())) | ||||
|         { | ||||
|             //this node is not connected or is the root --> this node has no parent | ||||
|             err = ESP_FAIL; | ||||
|         } | ||||
|     else | ||||
|         { | ||||
|             //node has parent | ||||
|             memcpy(pMeshParentAddr, &meshParentAddr, sizeof(mesh_addr_t)); | ||||
|         } | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| void vGetOwnAddr(mesh_addr_t* pMeshOwnAddr) | ||||
| { | ||||
|     memcpy(pMeshOwnAddr->addr, u8ownMAC, 6); | ||||
| } | ||||
|  | ||||
| bool bIsRootNode() | ||||
| { | ||||
|     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)) | ||||
| { | ||||
|     pAppRxHandle = pAppRxHandleTmp; //set handle from app as receive handle if an app packet is received | ||||
|     return ESP_OK; | ||||
| } | ||||
|  | ||||
| esp_err_t errMeshNetworkSetChildConnectedHandle(void (*pChildConnectHandleTmp)(uint8_t * pu8Data)) | ||||
| { | ||||
|     pOTAChildConnectHandle = pChildConnectHandleTmp; | ||||
|     return ESP_OK; | ||||
| } | ||||
|  | ||||
| esp_err_t errMeshNetworkSetOTAMessageHandleHandle(void (*pOTAMessageHandleTmp)(MESH_PACKET_t* puMeshPacket)) | ||||
| { | ||||
|     pOTAMessageHandle = pOTAMessageHandleTmp; | ||||
|     return ESP_OK; | ||||
| } | ||||
|  | ||||
| esp_err_t errMeshNetworkSetChangeStateOfServerWorkerHandle(void (*pChangeStateOfServerWorkerHandleTmp)(bool bState)) | ||||
| { | ||||
|     pChangeStateOfServerWorkerHandle = pChangeStateOfServerWorkerHandleTmp; | ||||
|     return ESP_OK; | ||||
| } | ||||
|  | ||||
| esp_err_t errSendMeshPacket(mesh_addr_t* pAddrDest, MESH_PACKET_t* pPacket) | ||||
| { | ||||
|     esp_err_t err; | ||||
|     mesh_data_t data; | ||||
|     data.data = tx_buf; | ||||
|     data.size = sizeof(tx_buf); | ||||
|     data.proto = MESH_PROTO_BIN; | ||||
|     data.tos = MESH_TOS_P2P; | ||||
|     memcpy(tx_buf, (uint8_t *)pPacket, sizeof(MESH_PACKET_t)); | ||||
|  | ||||
|     err = esp_mesh_send(pAddrDest, &data, MESH_DATA_P2P, NULL, 0); | ||||
|  | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| esp_err_t errStartReceiveTask() | ||||
| { | ||||
|     esp_err_t err = ESP_OK; | ||||
|     BaseType_t xReturned; | ||||
|  | ||||
|     xReturned = xTaskCreate(vTaskReceiveMeshData, "ReceiveMeshData", 7000, NULL, 5, NULL); | ||||
|  | ||||
|     if(xReturned != pdPASS) | ||||
|         { | ||||
|             err = ESP_FAIL; | ||||
|         } | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| void vTaskReceiveMeshData(void *arg) | ||||
| void vMeshNetworkTaskReceiveMeshData(void *arg) | ||||
| { | ||||
|     esp_err_t err; | ||||
|     mesh_addr_t from; | ||||
|     mesh_data_t data; | ||||
|     uint8_t rx_buf[CONFIG_MESH_MESSAGE_SIZE] = { 0, }; | ||||
|     int flag = 0; | ||||
|     data.data = rx_buf; | ||||
|     data.size = CONFIG_MESH_MESSAGE_SIZE; | ||||
| @ -329,6 +331,23 @@ void vTaskReceiveMeshData(void *arg) | ||||
| } | ||||
|  | ||||
|  | ||||
| esp_err_t errMeshNetworkGetParentNode(mesh_addr_t* pMeshParentAddr) | ||||
| { | ||||
|     esp_err_t err = ESP_OK; | ||||
|  | ||||
|     if((bIsMeshConnected == false) || (esp_mesh_is_root())) | ||||
|         { | ||||
|             //this node is not connected or is the root --> this node has no parent | ||||
|             err = ESP_FAIL; | ||||
|         } | ||||
|     else | ||||
|         { | ||||
|             //node has parent | ||||
|             memcpy(pMeshParentAddr, &meshParentAddr, sizeof(mesh_addr_t)); | ||||
|         } | ||||
|     return err; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -3,7 +3,7 @@ | ||||
|  | ||||
| static const char *LOG_TAG = "mesh_network_handler"; | ||||
|  | ||||
| void vIPEventHandler(void *arg, esp_event_base_t event_base, int32_t i32EventID, void *vpEventData) | ||||
| void vMeshNetworkIpEventHandler(void *arg, esp_event_base_t event_base, int32_t i32EventID, void *vpEventData) | ||||
| { | ||||
|     ip_event_got_ip_t *event = (ip_event_got_ip_t *) vpEventData; | ||||
|     ESP_LOGI(LOG_TAG, "<IP_EVENT_STA_GOT_IP>IP:" IPSTR, IP2STR(&event->ip_info.ip)); | ||||
| @ -13,7 +13,7 @@ void vIPEventHandler(void *arg, esp_event_base_t event_base, int32_t i32EventID, | ||||
|         } | ||||
| } | ||||
|  | ||||
| void vMeshEventHandler(void *arg, esp_event_base_t event_base, int32_t i32EventID, void* vpEventData) | ||||
| void vMeshNetworkMeshEventHandler(void *arg, esp_event_base_t event_base, int32_t i32EventID, void* vpEventData) | ||||
| { | ||||
|     mesh_addr_t id = {0,}; | ||||
|     static uint16_t last_layer = 0; | ||||
| @ -95,7 +95,7 @@ if(esp_netif_dhcpc_start(netif_sta) == ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED) / | ||||
| if(pChangeStateOfServerWorkerHandle){pChangeStateOfServerWorkerHandle(true);}// signal reconnect | ||||
| }  | ||||
| } | ||||
| errStartReceiveTask();//start receiving | ||||
| errMeshNetworkStartReceiveTask();//start receiving | ||||
| } | ||||
| break; | ||||
|         case MESH_EVENT_PARENT_DISCONNECTED:  | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| #include "Mesh_OTA.h" | ||||
| #include "Mesh_OTA_Util.h" | ||||
| #include "Mesh_OTA_Globals.h" | ||||
| #include "Mesh_OTA_Access.h" | ||||
| #include "Mesh_OTA_Partition_Access.h" | ||||
|  | ||||
| static const char *LOG_TAG = "mesh_ota"; | ||||
|  | ||||
| @ -60,9 +60,9 @@ esp_err_t errMeshOTAInitialize() | ||||
|                 } | ||||
|         } | ||||
|  | ||||
|     ERROR_CHECK(errMeshNetworkSetChildConnectedHandle(vAddNodeToPossibleUpdatableQueue)); | ||||
|     ERROR_CHECK(errMeshNetworkSetOTAMessageHandleHandle(vAddOtaMessageToQueue)); | ||||
|     ERROR_CHECK(errMeshNetworkSetChangeStateOfServerWorkerHandle(vChangeStateOfServerWorker)); | ||||
|     ERROR_CHECK(errMeshNetworkSetChildConnectedHandle(vMeshOtaUtilAddNodeToPossibleUpdatableQueue)); | ||||
|     ERROR_CHECK(errMeshNetworkSetOTAMessageHandleHandle(vMeshOtaUtilAddOtaMessageToQueue)); | ||||
|     ERROR_CHECK(errMeshNetworkSetChangeStateOfServerWorkerHandle(vMeshOtaUtilChangeStateOfServerWorker)); | ||||
|  | ||||
|     if(err == ESP_OK) | ||||
|         { | ||||
| @ -77,7 +77,7 @@ esp_err_t errMeshOTAInitialize() | ||||
|  | ||||
|     if(err == ESP_OK) | ||||
|         { | ||||
|             xReturned = xTaskCreate(vTaskServerWorker, "vTaskServerWorker", 8192, NULL, 5, NULL); | ||||
|             xReturned = xTaskCreate(vMeshOtaTaskServerWorker, "vMeshOtaTaskServerWorker", 8192, NULL, 5, NULL); | ||||
|             if(xReturned != pdPASS) | ||||
|                 { | ||||
|                     ESP_LOGE(LOG_TAG, "Unable to create the server worker task"); | ||||
| @ -88,7 +88,7 @@ esp_err_t errMeshOTAInitialize() | ||||
|  | ||||
|     if(err == ESP_OK) | ||||
|         { | ||||
|             xReturned = xTaskCreate(vTaskOTAWorker, "vTaskOTAWorker", 8192, NULL, 5, NULL); | ||||
|             xReturned = xTaskCreate(vMeshOtaTaskOTAWorker, "vMeshOtaTaskOTAWorker", 8192, NULL, 5, NULL); | ||||
|             if(xReturned != pdPASS) | ||||
|                 { | ||||
|                     ESP_LOGE(LOG_TAG, "Unable to create the OTA worker task"); | ||||
| @ -99,7 +99,7 @@ esp_err_t errMeshOTAInitialize() | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| void vTaskServerWorker(void *arg) | ||||
| void vMeshOtaTaskServerWorker(void *arg) | ||||
| { | ||||
|     esp_err_t err; | ||||
|     bool bNewOTAImage; //true if a new ota image was downloaded and validated | ||||
| @ -126,7 +126,7 @@ void vTaskServerWorker(void *arg) | ||||
|                     ERROR_CHECK(errHTTPSClientValidateServer()); | ||||
|                     ERROR_CHECK(errHTTPSClientSendRequest()); | ||||
|  | ||||
|                     ERROR_CHECK(errOTAHTTPS(&bNewOTAImage)); | ||||
|                     ERROR_CHECK(errMeshOtaPartitionAccessHttps(&bNewOTAImage)); | ||||
|                     errHTTPSClientReset(); | ||||
|  | ||||
|                     if(bNewOTAImage == true) | ||||
| @ -134,14 +134,14 @@ void vTaskServerWorker(void *arg) | ||||
|                             //set want reboot | ||||
|                             ESP_LOGI(LOG_TAG, "Updated successfully via HTTPS, set pending reboot"); | ||||
|                             bWantReboot = true; | ||||
|                             vAddAllNeighboursToQueue(); //add all existing neighbours to queue (aparent will not be added because this node is the root) | ||||
|                             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 | ||||
|                 } | ||||
|         } | ||||
| } | ||||
|  | ||||
| void vTaskOTAWorker(void *arg) | ||||
| void vMeshOtaTaskOTAWorker(void *arg) | ||||
| { | ||||
|     esp_err_t err = ESP_OK; | ||||
|     bool bNewOTAImage; //true if a new ota image was downloaded and validated | ||||
| @ -164,7 +164,7 @@ void vTaskOTAWorker(void *arg) | ||||
|                             //esp_restart(); | ||||
|                         } | ||||
|  | ||||
|                     ERROR_CHECK(errOTAMeshSlave(&bNewOTAImage)); | ||||
|                     ERROR_CHECK(errMeshOtaSlaveEndpoint(&bNewOTAImage)); | ||||
|                 } | ||||
|             else | ||||
|                 { | ||||
| @ -177,12 +177,12 @@ void vTaskOTAWorker(void *arg) | ||||
|                             err = ESP_FAIL; | ||||
|                         } | ||||
|  | ||||
|                     ERROR_CHECK(errOTAMeshMaster(&bNewOTAImage, &meshNodeAddr)); | ||||
|                     ERROR_CHECK(errMeshOtaMasterEndpoint(&bNewOTAImage, &meshNodeAddr)); | ||||
|  | ||||
|                     if (err != ESP_OK) | ||||
|                         { | ||||
|                             //OTA process faild --> add back to queue | ||||
|                             vAddNodeToPossibleUpdatableQueue(meshNodeAddr.addr); | ||||
|                             vMeshOtaUtilAddNodeToPossibleUpdatableQueue(meshNodeAddr.addr); | ||||
|                         } | ||||
|                 } | ||||
|  | ||||
| @ -191,14 +191,13 @@ void vTaskOTAWorker(void *arg) | ||||
|                     //set want reboot | ||||
|                     ESP_LOGI(LOG_TAG, "Updated successfully via Mesh, set pending reboot"); | ||||
|                     bWantReboot = true; | ||||
|                     vAddAllNeighboursToQueue(); //add all existing neighbours to queue | ||||
|                     vMeshOtaUtilAddAllNeighboursToQueue(); //add all existing neighbours to queue | ||||
|                 } | ||||
|             vTaskDelay( (1000) / portTICK_PERIOD_MS); | ||||
|         } | ||||
| } | ||||
|  | ||||
|  | ||||
| esp_err_t errOTAMeshSlave(bool* pbNewOTAImage) | ||||
| esp_err_t errMeshOtaSlaveEndpoint(bool* pbNewOTAImage) | ||||
| { | ||||
|     esp_err_t err = ESP_OK; | ||||
|     MESH_PACKET_t sOTAMessage; | ||||
| @ -224,22 +223,22 @@ esp_err_t errOTAMeshSlave(bool* pbNewOTAImage) | ||||
|                     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 | ||||
|                     ERROR_CHECK(errSendOTAVersionResponse(&sOTAMessage.meshSenderAddr)); | ||||
|                     ERROR_CHECK(errMeshOtaUtilSendOTAVersionResponse(&sOTAMessage.meshSenderAddr)); | ||||
|  | ||||
|                     if((bNewerVersion((bootPartitionDesc).version, (char*) sOTAMessage.au8Payload)) && (err == ESP_OK)) //compare local and remote version | ||||
|                     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"); | ||||
|                             //  --> this version older --> start OTA_Rx --> set pbNewOTAImage true | ||||
|                             ERROR_CHECK(errOTAMeshReceive(pbNewOTAImage, &sOTAMessage.meshSenderAddr)); | ||||
|                             ERROR_CHECK(errMeshOtaPartitionAccessMeshReceive(pbNewOTAImage, &sOTAMessage.meshSenderAddr)); | ||||
|                         } | ||||
|  | ||||
|                     if((bNewerVersion((char*) sOTAMessage.au8Payload, (bootPartitionDesc).version)) && (err == ESP_OK)) //compare remote and local version | ||||
|                     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"); | ||||
|                             //  --> this version newer --> start OTA_Tx | ||||
|                             ERROR_CHECK(errOTAMeshTransmit(&sOTAMessage.meshSenderAddr)); | ||||
|                             ERROR_CHECK(errMeshOtaPartitionAccessMeshTransmit(&sOTAMessage.meshSenderAddr)); | ||||
|                         } | ||||
|                     xSemaphoreGive(bsOTAProcess); //free binary semaphore, this allows other tasks to start the OTA process | ||||
|                 } | ||||
| @ -247,7 +246,7 @@ esp_err_t errOTAMeshSlave(bool* pbNewOTAImage) | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| esp_err_t errOTAMeshMaster(bool* pbNewOTAImage, mesh_addr_t* pMeshNodeAddr) | ||||
| esp_err_t errMeshOtaMasterEndpoint(bool* pbNewOTAImage, mesh_addr_t* pMeshNodeAddr) | ||||
| { | ||||
|     esp_err_t err = ESP_OK; | ||||
|     MESH_PACKET_t sOTAMessage; | ||||
| @ -258,13 +257,13 @@ esp_err_t errOTAMeshMaster(bool* pbNewOTAImage, mesh_addr_t* pMeshNodeAddr) | ||||
|  | ||||
|     *pbNewOTAImage = false; //set default false | ||||
|  | ||||
|     if(bIsNodeNeighbour(pMeshNodeAddr) == true) //check if node is still connected | ||||
|     if(bMeshNetworkIsNodeNeighbour(pMeshNodeAddr) == true) //check if node is still connected | ||||
|         { | ||||
|             bNodeIsConnected = true; //node is one of the neighbours | ||||
|             xSemaphoreTake(bsOTAProcess, portMAX_DELAY); //wait for binary semaphore that allows to start the OTA process | ||||
|  | ||||
|             ESP_LOGI(LOG_TAG, "Mesh-Master: send Version_Request to 0x%x", pMeshNodeAddr->addr[5]); | ||||
|             ERROR_CHECK(errSendOTAVersionRequest(pMeshNodeAddr)); //send OTA_VERSION_REQUEST with local version in payload | ||||
|             ERROR_CHECK(errMeshOtaUtilSendOTAVersionRequest(pMeshNodeAddr)); //send OTA_VERSION_REQUEST with local version in payload | ||||
|  | ||||
|             for (uint32_t u32Index = 0; u32Index < QUEUE_MESSAGE_OTA_SIZE; u32Index++) //loop through all OTA messages | ||||
|                 { | ||||
| @ -277,32 +276,32 @@ esp_err_t errOTAMeshMaster(bool* pbNewOTAImage, mesh_addr_t* pMeshNodeAddr) | ||||
|                                     err = ESP_FAIL; | ||||
|                                 } | ||||
|  | ||||
|                             if((err == ESP_OK) && (sOTAMessage.type == OTA_Version_Response) && (bCheckMACEquality(sOTAMessage.meshSenderAddr.addr, pMeshNodeAddr->addr))) //if OTA_Version_Request | ||||
|                             if((err == ESP_OK) && (sOTAMessage.type == OTA_Version_Response) && (bMeshNetworkCheckMACEquality(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 | ||||
|                                     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"); | ||||
|                                             //  --> this version older --> start OTA_Rx --> set pbNewOTAImage true | ||||
|                                             ERROR_CHECK(errOTAMeshReceive(pbNewOTAImage, &sOTAMessage.meshSenderAddr)); | ||||
|                                             ERROR_CHECK(errMeshOtaPartitionAccessMeshReceive(pbNewOTAImage, &sOTAMessage.meshSenderAddr)); | ||||
|                                         } | ||||
|  | ||||
|                                     if((bNewerVersion((char*) sOTAMessage.au8Payload, (bootPartitionDesc).version)) && (err == ESP_OK)) //compare remote and local version | ||||
|                                     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"); | ||||
|                                             //  --> this version newer --> start OTA_Tx | ||||
|                                             ERROR_CHECK(errOTAMeshTransmit(&sOTAMessage.meshSenderAddr)); | ||||
|                                             ERROR_CHECK(errMeshOtaPartitionAccessMeshTransmit(&sOTAMessage.meshSenderAddr)); | ||||
|                                         } | ||||
|                                 } | ||||
|                             else if (err == ESP_OK) | ||||
|                                 { | ||||
|                                     //received from wrong node or type --> back to queue | ||||
|                                     vAddOtaMessageToQueue(&sOTAMessage); | ||||
|                                     vMeshOtaUtilAddOtaMessageToQueue(&sOTAMessage); | ||||
|                                 } | ||||
|                         } | ||||
|                     else | ||||
| @ -319,7 +318,7 @@ esp_err_t errOTAMeshMaster(bool* pbNewOTAImage, mesh_addr_t* pMeshNodeAddr) | ||||
|         { | ||||
|             //add node back to queue if connected and NOT responding | ||||
|             ESP_LOGI(LOG_TAG, "OTA-Master: connected and NOT responding --> add node back to queue "); | ||||
|             vAddNodeToPossibleUpdatableQueue(pMeshNodeAddr->addr); | ||||
|             vMeshOtaUtilAddNodeToPossibleUpdatableQueue(pMeshNodeAddr->addr); | ||||
|         } | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| @ -6,5 +6,10 @@ xQueueHandle queueMessageOTA; //mesh ota controll messages like "OTA_Version_Res | ||||
| SemaphoreHandle_t bsStartStopServerWorker; //binary semaphore | ||||
| SemaphoreHandle_t bsOTAProcess; //binary semaphore | ||||
|  | ||||
| //w: errMeshOTAInitialize; | ||||
| //r: errMeshOTAInitialize; errMeshOtaPartitionAccessHttps; errMeshOtaPartitionAccessMeshReceive;  | ||||
| const esp_partition_t* pOTAPartition; //pointer to ota partition | ||||
|  | ||||
| //w: errMeshOTAInitialize; vMeshOtaTaskOTAWorker; vMeshOtaTaskServerWorker | ||||
| //r: errMeshOTAInitialize; vMeshOtaTaskOTAWorker; vMeshOtaTaskServerWorker | ||||
| bool bWantReboot; //flag to signal pending reboot | ||||
|  | ||||
| @ -1,249 +1,11 @@ | ||||
| #include "Mesh_OTA.h" | ||||
| #include "Mesh_OTA_Util.h" | ||||
| #include "Mesh_OTA_Globals.h" | ||||
| #include "Mesh_OTA_Access.h" | ||||
| #include "Mesh_OTA_Partition_Access.h" | ||||
|  | ||||
| static const char *LOG_TAG = "mesh_ota_access"; | ||||
| static const char *LOG_TAG = "mesh_ota_partition_access"; | ||||
|  | ||||
| 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) | ||||
|     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 u32SegmentCounter = 0U; | ||||
|  | ||||
|     pBootPartition = esp_ota_get_boot_partition(); //get boot partition (that will booted after reset), not the running partition | ||||
|  | ||||
|     //loop through partition to read in segmensts until end or error or abort called | ||||
|     while( ((OTA_MESH_SEGMENT_SIZE * u32SegmentCounter) < pBootPartition->size) && (err == ESP_OK) && (bAbort == false)) | ||||
|         { | ||||
|             bNodeIsResponding = false; //reset to default | ||||
|  | ||||
|             // read partition with offset based in index | ||||
|             ERROR_CHECK(esp_partition_read(pBootPartition, (OTA_MESH_SEGMENT_SIZE * u32SegmentCounter), sMeshPacket.au8Payload, OTA_MESH_SEGMENT_SIZE)); | ||||
|             u32OTABytesWritten = ((u32SegmentCounter+1) * OTA_MESH_SEGMENT_SIZE); | ||||
|             vPrintOTAProgress(&(pBootPartition->size), &u32OTABytesWritten, Transmitter); | ||||
|  | ||||
|             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 | ||||
|                         { | ||||
|                             //last partition image segment --> send OTA_Complete | ||||
|                             ESP_LOGI(LOG_TAG, "OTA-TX: last segment--> send Complete"); | ||||
|                             sMeshPacket.type = OTA_Complete; | ||||
|                         } | ||||
|                     //ESP_LOGI(LOG_TAG, "OTA-TX: send packet"); | ||||
|                     err = errSendMeshPacket(pMeshNodeAddr, &sMeshPacket); | ||||
|                 } | ||||
|             else | ||||
|                 { | ||||
|                     // error while read --> send OTA_ABORT and abort this OTA process | ||||
|                     sMeshPacket.type = OTA_Abort; | ||||
|                     bAbort = true; | ||||
|                     ESP_LOGI(LOG_TAG, "OTA-TX: error while read --> send ABORT"); | ||||
|                     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) && (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, ((OTA_MESH_TIMEOUT) / portTICK_PERIOD_MS)) != pdTRUE) | ||||
|                         { | ||||
|                             ESP_LOGE(LOG_TAG, "Unable to receive OTA Messages from queue"); | ||||
|                             err = ESP_FAIL; | ||||
|                         } | ||||
|  | ||||
|                     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; | ||||
|                                     u32Index = QUEUE_MESSAGE_OTA_SIZE;//this will end the loop through all OTA messages | ||||
|                                     break; | ||||
|                                 case OTA_Abort: //abort this OTA process | ||||
|                                     bAbort = true; | ||||
|                                     bNodeIsResponding = true; | ||||
|                                     break; | ||||
|                                 default: | ||||
|                                     //receives wrong OTA message type from node --> back to queue | ||||
|                                     //vAddOtaMessageToQueue(&sMeshPacket); | ||||
|                                     break; | ||||
|                                 } | ||||
|                         } | ||||
|                     else if (err == ESP_OK) | ||||
|                         { | ||||
|                             //received from wrong node --> back to queue | ||||
|                             vAddOtaMessageToQueue(&sMeshPacket); | ||||
|                         } | ||||
|                     /* | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         // OTA Message queue is empty --> wait some time | ||||
|                         ESP_LOGI(LOG_TAG, "OTA-TX: ota message queue empty --> wait"); | ||||
|                         vTaskDelay( (OTA_MESH_TIMEOUT) / portTICK_PERIOD_MS); | ||||
|                     } | ||||
|                     */ | ||||
|  | ||||
|                 }//end OTA message loop | ||||
|  | ||||
|             if(bNodeIsResponding == false) | ||||
|                 { | ||||
|                     //no abort was called but node didn’t responded | ||||
|                     ESP_LOGE(LOG_TAG, "OTA-TX: no abort was called but node didn’t responded --> error"); | ||||
|                     bAbort = true; | ||||
|                     err = ESP_FAIL; //this OTA process failed with error | ||||
|                 } | ||||
|             u32SegmentCounter++; | ||||
|         }//end of partition segment loop | ||||
|     vClearOtaMessageQueue(pMeshNodeAddr); | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| 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; | ||||
|  | ||||
|     ERROR_CHECK(esp_ota_begin(pOTAPartition, OTA_SIZE_UNKNOWN, &otaHandle)); //start ota update process | ||||
|  | ||||
|     //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 | ||||
|  | ||||
|             // 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; | ||||
|                         } | ||||
|  | ||||
|                     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; | ||||
|                                     ESP_LOGI(LOG_TAG, "OTA-RX: rec Complete --> last segment"); | ||||
|                                 //fall through | ||||
|                                 case OTA_Data: //data segement received | ||||
|                                     bNodeIsResponding = true; | ||||
|                                     ERROR_CHECK(esp_ota_write(otaHandle, sMeshPacket.au8Payload, OTA_MESH_SEGMENT_SIZE)); | ||||
|                                     u32OTABytesWritten = ((u32SegmentCounter+1) * OTA_MESH_SEGMENT_SIZE); | ||||
|                                     vPrintOTAProgress(&(pOTAPartition->size), &u32OTABytesWritten, Receiver); | ||||
|                                     u32Index = QUEUE_MESSAGE_OTA_SIZE; //this will end the loop through all OTA messages | ||||
|                                     break; | ||||
|                                 case OTA_Abort: //abort this OTA process | ||||
|                                     bAbort = true; | ||||
|                                     bNodeIsResponding = true; | ||||
|                                     ESP_LOGI(LOG_TAG, "OTA-RX: rec Abort"); | ||||
|                                     //this will end the loop through all OTA messages | ||||
|                                     break; | ||||
|                                 default: | ||||
|                                     //receives wrong OTA message type from node --> back to queue | ||||
|                                     //vAddOtaMessageToQueue(&sMeshPacket); | ||||
|                                     break; | ||||
|                                 } | ||||
|                         } | ||||
|                     else if (err == ESP_OK) | ||||
|                         { | ||||
|                             //received from wrong node --> back to queue | ||||
|                             vAddOtaMessageToQueue(&sMeshPacket); | ||||
|                         } | ||||
|  | ||||
|                     /*  } | ||||
|                     else | ||||
|                       { | ||||
|                           ESP_LOGI(LOG_TAG, "OTA-RX: ota message queue empty --> wait"); | ||||
|                           // OTA Message queue is empty --> wait some time | ||||
|                           vTaskDelay( (OTA_MESH_TIMEOUT) / portTICK_PERIOD_MS); | ||||
|                       } | ||||
|                       */ | ||||
|  | ||||
|                 }//end of OTA message loop | ||||
|  | ||||
|             if(bNodeIsResponding == false) | ||||
|                 { | ||||
|                     //no abort was called but node didn’t responded --> error | ||||
|                     ESP_LOGI(LOG_TAG, "OTA-RX: 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(bAbort == false) | ||||
|                                 { | ||||
|                                     //no error while ota write --> send OTA_ACK packet | ||||
|                                     //ESP_LOGI(LOG_TAG, "OTA-RX: 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; | ||||
|                             ESP_LOGI(LOG_TAG, "OTA-RX: abort --> send ABORT"); | ||||
|                             errSendMeshPacket(pMeshNodeAddr, &sMeshPacket); | ||||
|                         } | ||||
|                 } | ||||
|             u32SegmentCounter++; | ||||
|         }//end of partition segement loop | ||||
|  | ||||
|     if(bComplete == true) | ||||
|         { | ||||
|             //all OTA segments received --> validate | ||||
|             ESP_LOGI(LOG_TAG, "OTA-RX: validate image "); | ||||
|             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)); | ||||
|         } | ||||
|     vClearOtaMessageQueue(pMeshNodeAddr); | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| esp_err_t errOTAHTTPS(bool* pbNewOTAImage) | ||||
| esp_err_t errMeshOtaPartitionAccessHttps(bool* pbNewOTAImage) | ||||
| { | ||||
|     esp_err_t err = ESP_OK; | ||||
|     char u8OTABuffer[OTA_HTTPS_SEGMENT_SIZE]; //store image segment from server before ota write | ||||
| @ -258,7 +20,7 @@ esp_err_t errOTAHTTPS(bool* pbNewOTAImage) | ||||
|  | ||||
|     ERROR_CHECK(errHTTPSClientRetrieveData(u8OTABuffer, &u32BufferLenght, &u32BytesRead)); //read first bytes if image, including the version | ||||
|  | ||||
|     ERROR_CHECK(errExtractVersionNumber(u8OTABuffer, &u32BytesRead, pcRemoteVersionNumber)); //extract version numbers | ||||
|     ERROR_CHECK(errMeshOtaUtilExtractVersionNumber(u8OTABuffer, &u32BytesRead, pcRemoteVersionNumber)); //extract version numbers | ||||
|  | ||||
|     if(err == ESP_OK) //check if version number is found | ||||
|         { | ||||
| @ -267,12 +29,12 @@ esp_err_t errOTAHTTPS(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 | ||||
|  | ||||
|             if(bNewerVersion((bootPartitionDesc).version, pcRemoteVersionNumber)) //compare local and remote version | ||||
|             if(bMeshOtaUtilNewerVersion((bootPartitionDesc).version, pcRemoteVersionNumber)) //compare local and remote version | ||||
|                 { | ||||
|                     // 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(errMeshOtaUtilFindImageStart(u8OTABuffer, &u32BufferLenght, &u32StartOffset)); //get image start offset | ||||
|  | ||||
|                     ERROR_CHECK(esp_ota_begin(pOTAPartition, OTA_SIZE_UNKNOWN, &otaHandle)); //start ota update process | ||||
|                     if(err == ESP_OK) | ||||
| @ -281,7 +43,7 @@ esp_err_t errOTAHTTPS(bool* pbNewOTAImage) | ||||
|                             ESP_LOGI(LOG_TAG, "start OTA download via HTTPS"); | ||||
|                             do | ||||
|                                 { | ||||
|                                     vPrintOTAProgress(&(pOTAPartition->size), &u32OTABytesWritten, Receiver); | ||||
|                                     vMeshOtaUtilPrintOTAProgress(&(pOTAPartition->size), &u32OTABytesWritten, Receiver); | ||||
|                                     ERROR_CHECK(esp_ota_write(otaHandle, (const void*) u8OTABuffer+u32StartOffset, (u32BytesRead-u32StartOffset))); | ||||
|  | ||||
|                                     if(err == ESP_OK) | ||||
| @ -320,4 +82,243 @@ esp_err_t errOTAHTTPS(bool* pbNewOTAImage) | ||||
|             xSemaphoreGive(bsOTAProcess); //free binary semaphore, this allows other tasks to start the OTA process | ||||
|         } //end version number extracted | ||||
|     return err; | ||||
| } | ||||
| } | ||||
|  | ||||
| esp_err_t errMeshOtaPartitionAccessMeshTransmit(mesh_addr_t* pMeshNodeAddr) | ||||
| { | ||||
|     esp_err_t err = ESP_OK; | ||||
|     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 u32SegmentCounter = 0U; | ||||
|  | ||||
|     pBootPartition = esp_ota_get_boot_partition(); //get boot partition (that will booted after reset), not the running partition | ||||
|  | ||||
|     //loop through partition to read in segmensts until end or error or abort called | ||||
|     while( ((OTA_MESH_SEGMENT_SIZE * u32SegmentCounter) < pBootPartition->size) && (err == ESP_OK) && (bAbort == false)) | ||||
|         { | ||||
|             bNodeIsResponding = false; //reset to default | ||||
|  | ||||
|             // read partition with offset based in index | ||||
|             ERROR_CHECK(esp_partition_read(pBootPartition, (OTA_MESH_SEGMENT_SIZE * u32SegmentCounter), sMeshPacket.au8Payload, OTA_MESH_SEGMENT_SIZE)); | ||||
|             u32OTABytesWritten = ((u32SegmentCounter+1) * OTA_MESH_SEGMENT_SIZE); | ||||
|             vMeshOtaUtilPrintOTAProgress(&(pBootPartition->size), &u32OTABytesWritten, Transmitter); | ||||
|  | ||||
|             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 | ||||
|                         { | ||||
|                             //last partition image segment --> send OTA_Complete | ||||
|                             ESP_LOGI(LOG_TAG, "OTA-TX: last segment--> send Complete"); | ||||
|                             sMeshPacket.type = OTA_Complete; | ||||
|                         } | ||||
|                     //ESP_LOGI(LOG_TAG, "OTA-TX: send packet"); | ||||
|                     err = errMeshNetworkSendMeshPacket(pMeshNodeAddr, &sMeshPacket); | ||||
|                 } | ||||
|             else | ||||
|                 { | ||||
|                     // error while read --> send OTA_ABORT and abort this OTA process | ||||
|                     sMeshPacket.type = OTA_Abort; | ||||
|                     bAbort = true; | ||||
|                     ESP_LOGI(LOG_TAG, "OTA-TX: error while read --> send ABORT"); | ||||
|                     errMeshNetworkSendMeshPacket(pMeshNodeAddr, &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, ((OTA_MESH_TIMEOUT) / portTICK_PERIOD_MS)) != pdTRUE) | ||||
|                         { | ||||
|                             ESP_LOGE(LOG_TAG, "Unable to receive OTA Messages from queue"); | ||||
|                             err = ESP_FAIL; | ||||
|                         } | ||||
|  | ||||
|                     if((err == ESP_OK) && (bMeshNetworkCheckMACEquality(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; | ||||
|                                     u32Index = QUEUE_MESSAGE_OTA_SIZE;//this will end the loop through all OTA messages | ||||
|                                     break; | ||||
|                                 case OTA_Abort: //abort this OTA process | ||||
|                                     bAbort = true; | ||||
|                                     bNodeIsResponding = true; | ||||
|                                     break; | ||||
|                                 default: | ||||
|                                     //receives wrong OTA message type from node --> back to queue | ||||
|                                     //vMeshOtaUtilAddOtaMessageToQueue(&sMeshPacket); | ||||
|                                     break; | ||||
|                                 } | ||||
|                         } | ||||
|                     else if (err == ESP_OK) | ||||
|                         { | ||||
|                             //received from wrong node --> back to queue | ||||
|                             vMeshOtaUtilAddOtaMessageToQueue(&sMeshPacket); | ||||
|                         } | ||||
|                     /* | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         // OTA Message queue is empty --> wait some time | ||||
|                         ESP_LOGI(LOG_TAG, "OTA-TX: ota message queue empty --> wait"); | ||||
|                         vTaskDelay( (OTA_MESH_TIMEOUT) / portTICK_PERIOD_MS); | ||||
|                     } | ||||
|                     */ | ||||
|  | ||||
|                 }//end OTA message loop | ||||
|  | ||||
|             if(bNodeIsResponding == false) | ||||
|                 { | ||||
|                     //no abort was called but node didn’t responded | ||||
|                     ESP_LOGE(LOG_TAG, "OTA-TX: no abort was called but node didn’t responded --> error"); | ||||
|                     bAbort = true; | ||||
|                     err = ESP_FAIL; //this OTA process failed with error | ||||
|                 } | ||||
|             u32SegmentCounter++; | ||||
|         }//end of partition segment loop | ||||
|     vMeshOtaUtilClearOtaMessageQueue(pMeshNodeAddr); | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| esp_err_t errMeshOtaPartitionAccessMeshReceive(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; | ||||
|  | ||||
|     ERROR_CHECK(esp_ota_begin(pOTAPartition, OTA_SIZE_UNKNOWN, &otaHandle)); //start ota update process | ||||
|  | ||||
|     //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 | ||||
|  | ||||
|             // 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; | ||||
|                         } | ||||
|  | ||||
|                     if((err == ESP_OK) && (bMeshNetworkCheckMACEquality(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; | ||||
|                                     ESP_LOGI(LOG_TAG, "OTA-RX: rec Complete --> last segment"); | ||||
|                                 //fall through | ||||
|                                 case OTA_Data: //data segement received | ||||
|                                     bNodeIsResponding = true; | ||||
|                                     ERROR_CHECK(esp_ota_write(otaHandle, sMeshPacket.au8Payload, OTA_MESH_SEGMENT_SIZE)); | ||||
|                                     u32OTABytesWritten = ((u32SegmentCounter+1) * OTA_MESH_SEGMENT_SIZE); | ||||
|                                     vMeshOtaUtilPrintOTAProgress(&(pOTAPartition->size), &u32OTABytesWritten, Receiver); | ||||
|                                     u32Index = QUEUE_MESSAGE_OTA_SIZE; //this will end the loop through all OTA messages | ||||
|                                     break; | ||||
|                                 case OTA_Abort: //abort this OTA process | ||||
|                                     bAbort = true; | ||||
|                                     bNodeIsResponding = true; | ||||
|                                     ESP_LOGI(LOG_TAG, "OTA-RX: rec Abort"); | ||||
|                                     //this will end the loop through all OTA messages | ||||
|                                     break; | ||||
|                                 default: | ||||
|                                     //receives wrong OTA message type from node --> back to queue | ||||
|                                     //vMeshOtaUtilAddOtaMessageToQueue(&sMeshPacket); | ||||
|                                     break; | ||||
|                                 } | ||||
|                         } | ||||
|                     else if (err == ESP_OK) | ||||
|                         { | ||||
|                             //received from wrong node --> back to queue | ||||
|                             vMeshOtaUtilAddOtaMessageToQueue(&sMeshPacket); | ||||
|                         } | ||||
|  | ||||
|                     /*  } | ||||
|                     else | ||||
|                       { | ||||
|                           ESP_LOGI(LOG_TAG, "OTA-RX: ota message queue empty --> wait"); | ||||
|                           // OTA Message queue is empty --> wait some time | ||||
|                           vTaskDelay( (OTA_MESH_TIMEOUT) / portTICK_PERIOD_MS); | ||||
|                       } | ||||
|                       */ | ||||
|  | ||||
|                 }//end of OTA message loop | ||||
|  | ||||
|             if(bNodeIsResponding == false) | ||||
|                 { | ||||
|                     //no abort was called but node didn’t responded --> error | ||||
|                     ESP_LOGI(LOG_TAG, "OTA-RX: 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(bAbort == false) | ||||
|                                 { | ||||
|                                     //no error while ota write --> send OTA_ACK packet | ||||
|                                     //ESP_LOGI(LOG_TAG, "OTA-RX: no error while ota write --> send OTA_ACK packet"); | ||||
|                                     sMeshPacket.type = OTA_ACK; | ||||
|                                     err = errMeshNetworkSendMeshPacket(pMeshNodeAddr, &sMeshPacket); | ||||
|                                 } | ||||
|                         } | ||||
|                     else | ||||
|                         { | ||||
|                             // error while read --> send OTA_ABORT and abort this OTA process | ||||
|                             sMeshPacket.type = OTA_Abort; | ||||
|                             bAbort = true; | ||||
|                             ESP_LOGI(LOG_TAG, "OTA-RX: abort --> send ABORT"); | ||||
|                             errMeshNetworkSendMeshPacket(pMeshNodeAddr, &sMeshPacket); | ||||
|                         } | ||||
|                 } | ||||
|             u32SegmentCounter++; | ||||
|         }//end of partition segement loop | ||||
|  | ||||
|     if(bComplete == true) | ||||
|         { | ||||
|             //all OTA segments received --> validate | ||||
|             ESP_LOGI(LOG_TAG, "OTA-RX: validate image "); | ||||
|             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)); | ||||
|         } | ||||
|     vMeshOtaUtilClearOtaMessageQueue(pMeshNodeAddr); | ||||
|     return err; | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -3,76 +3,7 @@ | ||||
|  | ||||
| static const char *LOG_TAG = "mesh_ota"; | ||||
|  | ||||
| void vAddNodeToPossibleUpdatableQueue(uint8_t* pu8MAC) | ||||
| { | ||||
|     //send payload to node queues | ||||
|     mesh_addr_t addrNode; | ||||
|     memcpy(&addrNode.addr, (uint8_t *)pu8MAC, 6); //copy MAC | ||||
|  | ||||
|     if (xQueueSend(queueNodes, &addrNode, portMAX_DELAY) != pdPASS) | ||||
|         { | ||||
|             ESP_LOGE(LOG_TAG, "Unable to push node into node queue"); | ||||
|         } | ||||
|     else | ||||
|         { | ||||
|             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]); | ||||
|         } | ||||
| } | ||||
|  | ||||
| void vAddOtaMessageToQueue(MESH_PACKET_t* puMeshPacket) | ||||
| { | ||||
|     //send ota packet to packet queue | ||||
|     if (xQueueSend(queueMessageOTA, puMeshPacket, portMAX_DELAY) != pdPASS) | ||||
|         { | ||||
|             ESP_LOGE(LOG_TAG, "Unable to push ota packet into packet queue"); | ||||
|         } | ||||
|     else | ||||
|         { | ||||
|             switch (puMeshPacket->type) | ||||
|                 { | ||||
|                 case OTA_Abort: | ||||
|                     ESP_LOGI(LOG_TAG, "added ota message to queue: OTA_Abort from 0x%x", puMeshPacket->meshSenderAddr.addr[5]); | ||||
|                     break; | ||||
|                 case OTA_Version_Request: | ||||
|                     ESP_LOGI(LOG_TAG, "added ota message to queue: OTA_Version_Request from 0x%x", puMeshPacket->meshSenderAddr.addr[5]); | ||||
|                     break; | ||||
|  | ||||
|                 case OTA_Version_Response: | ||||
|                     ESP_LOGI(LOG_TAG, "added ota message to queue: OTA_Version Response from 0x%x", puMeshPacket->meshSenderAddr.addr[5]); | ||||
|                     break; | ||||
|                 default: | ||||
|                     break; | ||||
|                 } | ||||
|         } | ||||
| } | ||||
|  | ||||
| void vChangeStateOfServerWorker(bool bState) //allow access via function ptn to networl_handler | ||||
| { | ||||
|     static bool bLastState = false; | ||||
|  | ||||
|     if(bState != bLastState) //change only if necessary | ||||
|         { | ||||
|             ESP_LOGI(LOG_TAG, "server worker change handler"); | ||||
|  | ||||
|             if(bState == true) | ||||
|                 { | ||||
|                     if (xSemaphoreGive(bsStartStopServerWorker)  != pdTRUE) | ||||
|                         { | ||||
|                             ESP_LOGE(LOG_TAG, "Unable to give mutex to activate the server worker"); | ||||
|                         } | ||||
|                 } | ||||
|             else | ||||
|                 { | ||||
|                     if (xSemaphoreTake(bsStartStopServerWorker,( TickType_t ) 10 )  != pdTRUE) | ||||
|                         { | ||||
|                             ESP_LOGE(LOG_TAG, "Unable to obtain mutex to deactivate the server worker"); | ||||
|                         } | ||||
|                 } | ||||
|             bLastState = bState; | ||||
|         } | ||||
| } | ||||
|  | ||||
| bool bNewerVersion(const char* pu8Local, const  char* pu8Remote) | ||||
| bool bMeshOtaUtilNewerVersion(const char* pu8Local, const  char* pu8Remote) | ||||
| { | ||||
|     /* | ||||
|      * Return true if remote version is newer (higher) than local version | ||||
| @ -103,7 +34,24 @@ bool bNewerVersion(const char* pu8Local, const  char* pu8Remote) | ||||
|     return bReturn; | ||||
| } | ||||
|  | ||||
| esp_err_t errFindImageStart(const char* pu8Data, uint32_t* pu32DataLenght, uint32_t* pu32StartOffset) | ||||
| esp_err_t errMeshOtaUtilExtractVersionNumber(const char* pu8Data, uint32_t* pu32DataLenght, char* pc8RemoteVersionNumber) | ||||
| { | ||||
|     uint32_t u32StartOffset; | ||||
|     esp_err_t err = ESP_OK; | ||||
|  | ||||
|     strcpy(pc8RemoteVersionNumber, "999.999.999"); //init value | ||||
|     err = errMeshOtaUtilFindImageStart(pu8Data, pu32DataLenght, &u32StartOffset); //get image start offset | ||||
|  | ||||
|     if(err == ESP_OK) | ||||
|         { | ||||
|             //image found | ||||
|             strncpy(pc8RemoteVersionNumber, pu8Data+(u32StartOffset+48), 11); //copy version number | ||||
|             pc8RemoteVersionNumber[12] = '\0'; | ||||
|         } | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| esp_err_t errMeshOtaUtilFindImageStart(const char* pu8Data, uint32_t* pu32DataLenght, uint32_t* pu32StartOffset) | ||||
| { | ||||
|     /* | ||||
|     Offset  value | ||||
| @ -181,24 +129,42 @@ esp_err_t errFindImageStart(const char* pu8Data, uint32_t* pu32DataLenght, uint3 | ||||
|     return errReturn; | ||||
| } | ||||
|  | ||||
| esp_err_t errExtractVersionNumber(const char* pu8Data, uint32_t* pu32DataLenght, char* pc8RemoteVersionNumber) | ||||
| esp_err_t errMeshOtaUtilSendOTAVersionRequest(mesh_addr_t* pMeshReceiverAddr) | ||||
| { | ||||
|     uint32_t u32StartOffset; | ||||
|     esp_err_t err = ESP_OK; | ||||
|     MESH_PACKET_t packet; | ||||
|     packet.type = OTA_Version_Request; | ||||
|  | ||||
|     strcpy(pc8RemoteVersionNumber, "999.999.999"); //init value | ||||
|     err = errFindImageStart(pu8Data, pu32DataLenght, &u32StartOffset); //get image start offset | ||||
|     const esp_partition_t* pBootPartition; //pointer to boot partition (that will booted after reset) | ||||
|     esp_app_desc_t bootPartitionDesc; //Metadata from boot partition | ||||
|  | ||||
|     if(err == ESP_OK) | ||||
|         { | ||||
|             //image found | ||||
|             strncpy(pc8RemoteVersionNumber, pu8Data+(u32StartOffset+48), 11); //copy version number | ||||
|             pc8RemoteVersionNumber[12] = '\0'; | ||||
|         } | ||||
|     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 = errMeshNetworkSendMeshPacket(pMeshReceiverAddr, &packet); | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| void vPrintOTAProgress(const uint32_t* const pu32TotalImageSize, const uint32_t* const pu32BytesWritten, OTA_MESH_ROLE_t eRole) | ||||
| esp_err_t errMeshOtaUtilSendOTAVersionResponse(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 | ||||
|  | ||||
|     ESP_LOGI(LOG_TAG, "Send OTA_Version_Response to 0x%x", pMeshReceiverAddr->addr[5]); | ||||
|  | ||||
|     err = errMeshNetworkSendMeshPacket(pMeshReceiverAddr, &packet); | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| void vMeshOtaUtilPrintOTAProgress(const uint32_t* const pu32TotalImageSize, const uint32_t* const pu32BytesWritten, OTA_MESH_ROLE_t eRole) | ||||
| { | ||||
|     uint32_t u32Percentage = 0U; | ||||
|     static uint32_t u32LastPercentage = 0U; | ||||
| @ -230,7 +196,7 @@ void vPrintOTAProgress(const uint32_t* const pu32TotalImageSize, const uint32_t* | ||||
|         } | ||||
| } | ||||
|  | ||||
| void vAddAllNeighboursToQueue(void) | ||||
| void vMeshOtaUtilAddAllNeighboursToQueue(void) | ||||
| { | ||||
|     esp_err_t err = ESP_OK; | ||||
|  | ||||
| @ -238,55 +204,36 @@ void vAddAllNeighboursToQueue(void) | ||||
|     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); | ||||
|     err = errMeshNetworkGetParentNode(&addrParent); | ||||
|  | ||||
|     if(err == ESP_OK) | ||||
|         { | ||||
|             vAddNodeToPossibleUpdatableQueue(addrParent.addr); | ||||
|             vMeshOtaUtilAddNodeToPossibleUpdatableQueue(addrParent.addr); | ||||
|             ESP_LOGI(LOG_TAG, "added parent"); | ||||
|         } | ||||
|  | ||||
|     err = ESP_OK; //reset error code | ||||
|  | ||||
|     ERROR_CHECK(errGetChildren(childrenAddr, &u16ChildrenSize)); //get all children | ||||
|     ERROR_CHECK(errMeshNetworkGetChildren(childrenAddr, &u16ChildrenSize)); //get all children | ||||
|  | ||||
|     for (uint16_t u16Index = 0; ((u16Index < u16ChildrenSize) && (err == ESP_OK)); u16Index++) | ||||
|         { | ||||
|             vAddNodeToPossibleUpdatableQueue(childrenAddr[u16Index].addr); | ||||
|             vMeshOtaUtilAddNodeToPossibleUpdatableQueue(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 | ||||
|  | ||||
|     ESP_LOGI(LOG_TAG, "Send OTA_Version_Response to 0x%x", pMeshReceiverAddr->addr[5]); | ||||
|  | ||||
|     err = errSendMeshPacket(pMeshReceiverAddr, &packet); | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| void vClearOtaMessageQueue(mesh_addr_t* pMeshNodeAddr) | ||||
| void vMeshOtaUtilClearOtaMessageQueue(mesh_addr_t* pMeshNodeAddr) | ||||
| { | ||||
|     MESH_PACKET_t sMeshPacket; //packet for sending and receiving | ||||
|     for (uint32_t u32Index = 0; (u32Index < QUEUE_MESSAGE_OTA_SIZE); u32Index++) //loop through all OTA messages | ||||
|         { | ||||
|             if (xQueueReceive(queueMessageOTA, &sMeshPacket, 0) == pdTRUE) | ||||
|                 { | ||||
|                     if(!(bCheckMACEquality(sMeshPacket.meshSenderAddr.addr, pMeshNodeAddr->addr))) | ||||
|                     if(!(bMeshNetworkCheckMACEquality(sMeshPacket.meshSenderAddr.addr, pMeshNodeAddr->addr))) | ||||
|                         { | ||||
|                             //received OTA message is NOT from pMeshNodeAddr --> keep it in queue | ||||
|                             vAddOtaMessageToQueue(&sMeshPacket); | ||||
|                             vMeshOtaUtilAddOtaMessageToQueue(&sMeshPacket); | ||||
|                         } | ||||
|                     else | ||||
|                         { | ||||
| @ -296,19 +243,71 @@ void vClearOtaMessageQueue(mesh_addr_t* pMeshNodeAddr) | ||||
|         }//end OTA message loop | ||||
| } | ||||
|  | ||||
| esp_err_t errSendOTAVersionRequest(mesh_addr_t* pMeshReceiverAddr) | ||||
| void vMeshOtaUtilAddNodeToPossibleUpdatableQueue(uint8_t* pu8MAC) | ||||
| { | ||||
|     esp_err_t err = ESP_OK; | ||||
|     MESH_PACKET_t packet; | ||||
|     packet.type = OTA_Version_Request; | ||||
|     //send payload to node queues | ||||
|     mesh_addr_t addrNode; | ||||
|     memcpy(&addrNode.addr, (uint8_t *)pu8MAC, 6); //copy MAC | ||||
|  | ||||
|     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; | ||||
|     if (xQueueSend(queueNodes, &addrNode, portMAX_DELAY) != pdPASS) | ||||
|         { | ||||
|             ESP_LOGE(LOG_TAG, "Unable to push node into node queue"); | ||||
|         } | ||||
|     else | ||||
|         { | ||||
|             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]); | ||||
|         } | ||||
| } | ||||
|  | ||||
| void vMeshOtaUtilAddOtaMessageToQueue(MESH_PACKET_t* puMeshPacket) | ||||
| { | ||||
|     //send ota packet to packet queue | ||||
|     if (xQueueSend(queueMessageOTA, puMeshPacket, portMAX_DELAY) != pdPASS) | ||||
|         { | ||||
|             ESP_LOGE(LOG_TAG, "Unable to push ota packet into packet queue"); | ||||
|         } | ||||
|     else | ||||
|         { | ||||
|             switch (puMeshPacket->type) | ||||
|                 { | ||||
|                 case OTA_Abort: | ||||
|                     ESP_LOGI(LOG_TAG, "added ota message to queue: OTA_Abort from 0x%x", puMeshPacket->meshSenderAddr.addr[5]); | ||||
|                     break; | ||||
|                 case OTA_Version_Request: | ||||
|                     ESP_LOGI(LOG_TAG, "added ota message to queue: OTA_Version_Request from 0x%x", puMeshPacket->meshSenderAddr.addr[5]); | ||||
|                     break; | ||||
|  | ||||
|                 case OTA_Version_Response: | ||||
|                     ESP_LOGI(LOG_TAG, "added ota message to queue: OTA_Version Response from 0x%x", puMeshPacket->meshSenderAddr.addr[5]); | ||||
|                     break; | ||||
|                 default: | ||||
|                     break; | ||||
|                 } | ||||
|         } | ||||
| } | ||||
|  | ||||
| void vMeshOtaUtilChangeStateOfServerWorker(bool bState) //allow access via function ptn to networl_handler | ||||
| { | ||||
|     static bool bLastState = false; | ||||
|  | ||||
|     if(bState != bLastState) //change only if necessary | ||||
|         { | ||||
|             ESP_LOGI(LOG_TAG, "server worker change handler"); | ||||
|  | ||||
|             if(bState == true) | ||||
|                 { | ||||
|                     if (xSemaphoreGive(bsStartStopServerWorker)  != pdTRUE) | ||||
|                         { | ||||
|                             ESP_LOGE(LOG_TAG, "Unable to give mutex to activate the server worker"); | ||||
|                         } | ||||
|                 } | ||||
|             else | ||||
|                 { | ||||
|                     if (xSemaphoreTake(bsStartStopServerWorker,( TickType_t ) 10 )  != pdTRUE) | ||||
|                         { | ||||
|                             ESP_LOGE(LOG_TAG, "Unable to obtain mutex to deactivate the server worker"); | ||||
|                         } | ||||
|                 } | ||||
|             bLastState = bState; | ||||
|         } | ||||
| } | ||||
|  | ||||
| @ -84,32 +84,28 @@ extern uint8_t u8ownMAC[6]; | ||||
| extern void (*pOTAChildConnectHandle)(uint8_t* ); | ||||
| extern void (*pChangeStateOfServerWorkerHandle)(bool ); | ||||
|  | ||||
| esp_err_t errMeshNetworkInitialize(); | ||||
| esp_err_t errMeshNetworkInitializeWiFi(); | ||||
| esp_err_t errMeshNetworkInitialize(void); | ||||
| esp_err_t errMeshNetworkInitializeWiFi(void); | ||||
| 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 errMeshNetworkSetAppReceiveHandle(void (*pAppRxHandleTmp)(uint8_t * pu8Data, uint8_t* pu8Sender)); | ||||
| esp_err_t errMeshNetworkSetOTAMessageHandleHandle(void (*pOTAMessageHandleTmp)(MESH_PACKET_t* puMeshPacket)); | ||||
|  | ||||
| esp_err_t errMeshNetworkSetChangeStateOfServerWorkerHandle(void (*pChangeStateOfServerWorkerHandleTmp)(bool bState)); | ||||
|  | ||||
| bool bCheckMACEquality(uint8_t* pu8aMAC,  uint8_t* pu8bMAC); | ||||
| void vGetOwnAddr(mesh_addr_t* pMeshOwnAddr); | ||||
| esp_err_t errGetParentNode(mesh_addr_t* pMeshParentAddr); | ||||
| esp_err_t errGetChildren(mesh_addr_t* pChildren, uint16_t* pu16ChildrenSize); | ||||
| bool bIsRootNode(); | ||||
| bool bIsNodeNeighbour(mesh_addr_t* pNode); | ||||
|  | ||||
| esp_err_t errStartReceiveTask(); | ||||
| void vTaskReceiveMeshData(void *arg); | ||||
| void vMeshEventHandler(void *arg, esp_event_base_t event_base, int32_t i32EventID, void* vpEventData); | ||||
| void vIPEventHandler(void *arg, esp_event_base_t event_base, int32_t i32EventID, void *event_data); | ||||
|  | ||||
| esp_err_t errSendMeshPacket(mesh_addr_t* pAddrDest, MESH_PACKET_t* pPacket); | ||||
|  | ||||
| bool bMeshNetworkIsRootNode(void); | ||||
| bool bMeshNetworkIsNodeNeighbour(mesh_addr_t* pNode); | ||||
| bool bMeshNetworkCheckMACEquality(uint8_t* pu8aMAC,  uint8_t* pu8bMAC); | ||||
|  | ||||
| esp_err_t errMeshNetworkStartReceiveTask(void); | ||||
| esp_err_t errMeshNetworkGetParentNode(mesh_addr_t* pMeshParentAddr); | ||||
| esp_err_t errMeshNetworkGetChildren(mesh_addr_t* pChildren, uint16_t* pu16ChildrenSize); | ||||
| esp_err_t errMeshNetworkSendMeshPacket(mesh_addr_t* pAddrDest, MESH_PACKET_t* pPacket); | ||||
|  | ||||
| void vMeshNetworkTaskReceiveMeshData(void *arg); | ||||
| void vMeshNetworkGetOwnAddr(mesh_addr_t* pMeshOwnAddr); | ||||
| void vMeshNetworkIpEventHandler(void *arg, esp_event_base_t event_base, int32_t i32EventID, void *vpEventData); | ||||
| void vMeshNetworkMeshEventHandler(void *arg, esp_event_base_t event_base, int32_t i32EventID, void* vpEventData); | ||||
|  | ||||
| #endif /* H_MESH_NETWORK */ | ||||
|  | ||||
|  | ||||
| @ -28,15 +28,14 @@ | ||||
|             }                                                                                           \ | ||||
|     }                                                                                                   \ | ||||
|  | ||||
| esp_err_t errMeshOTAInitialize(); | ||||
|  | ||||
|  | ||||
| esp_err_t errOTAMeshSlave(bool* pbNewOTAImage); | ||||
| esp_err_t errOTAMeshMaster(bool* pbNewOTAImage, mesh_addr_t* pMeshNodeAddr); | ||||
|  | ||||
| esp_err_t errMeshOTAInitialize(void); | ||||
|  | ||||
| //Tasks | ||||
| void vTaskServerWorker(void *arg); | ||||
| void vTaskOTAWorker(void *arg); | ||||
| void vMeshOtaTaskServerWorker(void *arg); | ||||
| void vMeshOtaTaskOTAWorker(void *arg); | ||||
|  | ||||
| //OTA process endpoints | ||||
| esp_err_t errMeshOtaSlaveEndpoint(bool* pbNewOTAImage); | ||||
| esp_err_t errMeshOtaMasterEndpoint(bool* pbNewOTAImage, mesh_addr_t* pMeshNodeAddr); | ||||
|  | ||||
| #endif /* H_MESH_OTA */ | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| #ifndef H_MESH_OTA_ACCESS | ||||
| #define H_MESH_OTA_ACCESS | ||||
| #ifndef H_MESH_OTA_PARTITION_ACCESS | ||||
| #define H_MESH_OTA_PARTITION_ACCESS | ||||
| 
 | ||||
| #include "esp_system.h" | ||||
| #include "esp_event.h" | ||||
| @ -20,9 +20,8 @@ | ||||
|             }                                                                                           \ | ||||
|     }                                                                                                   \ | ||||
| 
 | ||||
| esp_err_t errOTAMeshTransmit(mesh_addr_t* pMeshNodeAddr); | ||||
| esp_err_t errOTAMeshReceive(bool* pbNewOTAImage, mesh_addr_t* pMeshNodeAddr); | ||||
| esp_err_t errMeshOtaPartitionAccessHttps(bool* pbNewOTAImage); | ||||
| esp_err_t errMeshOtaPartitionAccessMeshTransmit(mesh_addr_t* pMeshNodeAddr); | ||||
| esp_err_t errMeshOtaPartitionAccessMeshReceive(bool* pbNewOTAImage, mesh_addr_t* pMeshNodeAddr); | ||||
| 
 | ||||
| esp_err_t errOTAHTTPS(bool* pbNewOTAImage); | ||||
| 
 | ||||
| #endif /* H_MESH_OTA_ACCESS */ | ||||
| #endif /* H_MESH_OTA_PARTITION_ACCESS */ | ||||
| @ -18,18 +18,18 @@ enum otaMeshRole | ||||
| typedef  enum otaMeshRole OTA_MESH_ROLE_t; | ||||
|  | ||||
| //helper functions | ||||
| bool bNewerVersion(const char* pu8Local, const char* pu8Remote); | ||||
| esp_err_t errExtractVersionNumber(const  char* pu8Data, uint32_t* pu32DataLenght, char* pc8RemoteVersionNumber); | ||||
| 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, OTA_MESH_ROLE_t eRole); | ||||
| void vAddAllNeighboursToQueue(void); | ||||
| esp_err_t errSendOTAVersionResponse(mesh_addr_t* meshReceiverAddr); | ||||
| esp_err_t errSendOTAVersionRequest(mesh_addr_t* meshReceiverAddr); | ||||
| void vClearOtaMessageQueue(mesh_addr_t* pMeshNodeAddr); | ||||
| bool bMeshOtaUtilNewerVersion(const char* pu8Local, const char* pu8Remote); | ||||
| esp_err_t errMeshOtaUtilExtractVersionNumber(const  char* pu8Data, uint32_t* pu32DataLenght, char* pc8RemoteVersionNumber); | ||||
| esp_err_t errMeshOtaUtilFindImageStart(const  char* pu8Data, uint32_t* pu32DataLenght, uint32_t* pu32StartOffset); | ||||
| esp_err_t errMeshOtaUtilSendOTAVersionRequest(mesh_addr_t* pMeshReceiverAddr); | ||||
| esp_err_t errMeshOtaUtilSendOTAVersionResponse(mesh_addr_t* pMeshReceiverAddr); | ||||
| void vMeshOtaUtilPrintOTAProgress(const uint32_t* const cpcu32TotalImageSize, const uint32_t* const cpcu32BytesWritten, OTA_MESH_ROLE_t eRole); | ||||
| void vMeshOtaUtilAddAllNeighboursToQueue(void); | ||||
| void vMeshOtaUtilClearOtaMessageQueue(mesh_addr_t* pMeshNodeAddr); | ||||
|  | ||||
| //Handler | ||||
| void vAddNodeToPossibleUpdatableQueue(uint8_t* pu8MAC); | ||||
| void vAddOtaMessageToQueue(MESH_PACKET_t* puMeshPacket); | ||||
| void vChangeStateOfServerWorker(bool state); | ||||
| void vMeshOtaUtilAddNodeToPossibleUpdatableQueue(uint8_t* pu8MAC); | ||||
| void vMeshOtaUtilAddOtaMessageToQueue(MESH_PACKET_t* puMeshPacket); | ||||
| void vMeshOtaUtilChangeStateOfServerWorker(bool bState); | ||||
|  | ||||
| #endif /* H_MESH_OTA_UTIL */ | ||||
|  | ||||
| @ -10,56 +10,56 @@ TEST_CASE("Remote got patch", "[distinguish newer image version]") | ||||
| { | ||||
|     char versionLocal[] = "1.2.3";  //current running image | ||||
|     char versionRemote[] = "1.2.4"; //image from server | ||||
|     TEST_ASSERT_TRUE( bNewerVersion(versionLocal, versionRemote)  ); | ||||
|     TEST_ASSERT_TRUE( bMeshOtaUtilNewerVersion(versionLocal, versionRemote)  ); | ||||
| } | ||||
|  | ||||
| TEST_CASE("Remote got minor", "[distinguish newer image version]") | ||||
| { | ||||
|     char versionLocal[] = "1.2.3";  //current running image | ||||
|     char versionRemote[] = "1.3.3"; //image from server | ||||
|     TEST_ASSERT_TRUE( bNewerVersion(versionLocal, versionRemote)  ); | ||||
|     TEST_ASSERT_TRUE( bMeshOtaUtilNewerVersion(versionLocal, versionRemote)  ); | ||||
| } | ||||
|  | ||||
| TEST_CASE("Remote got major", "[distinguish newer image version]") | ||||
| { | ||||
|     char versionLocal[] = "1.2.3";  //current running image | ||||
|     char versionRemote[] = "2.2.3"; //image from server | ||||
|     TEST_ASSERT_TRUE( bNewerVersion(versionLocal, versionRemote)  ); | ||||
|     TEST_ASSERT_TRUE( bMeshOtaUtilNewerVersion(versionLocal, versionRemote)  ); | ||||
| } | ||||
|  | ||||
| TEST_CASE("Local got patch", "[distinguish newer image version]") | ||||
| { | ||||
|     char versionLocal[] = "1.2.4";  //current running image | ||||
|     char versionRemote[] = "1.2.3"; //image from server | ||||
|     TEST_ASSERT_FALSE( bNewerVersion(versionLocal, versionRemote)  ); | ||||
|     TEST_ASSERT_FALSE( bMeshOtaUtilNewerVersion(versionLocal, versionRemote)  ); | ||||
| } | ||||
|  | ||||
| TEST_CASE("Local got minor", "[distinguish newer image version]") | ||||
| { | ||||
|     char versionLocal[] = "1.3.3";  //current running image | ||||
|     char versionRemote[] = "1.2.3"; //image from server | ||||
|     TEST_ASSERT_FALSE( bNewerVersion(versionLocal, versionRemote)  ); | ||||
|     TEST_ASSERT_FALSE( bMeshOtaUtilNewerVersion(versionLocal, versionRemote)  ); | ||||
| } | ||||
|  | ||||
| TEST_CASE("Local got major", "[distinguish newer image version]") | ||||
| { | ||||
|     char versionLocal[] = "2.2.3";  //current running image | ||||
|     char versionRemote[] = "1.2.3"; //image from server | ||||
|     TEST_ASSERT_FALSE( bNewerVersion(versionLocal, versionRemote)  ); | ||||
|     TEST_ASSERT_FALSE( bMeshOtaUtilNewerVersion(versionLocal, versionRemote)  ); | ||||
| } | ||||
|  | ||||
| TEST_CASE("Remote got alpha and patch", "[distinguish newer image version]") | ||||
| { | ||||
|     char versionLocal[] = "2.2.3";  //current running image | ||||
|     char versionRemote[] = "a2.2.4"; //image from server | ||||
|     TEST_ASSERT_TRUE( bNewerVersion(versionLocal, versionRemote)  ); | ||||
|     TEST_ASSERT_TRUE( bMeshOtaUtilNewerVersion(versionLocal, versionRemote)  ); | ||||
| } | ||||
|  | ||||
| TEST_CASE("Remote got max", "[distinguish newer image version]") | ||||
| { | ||||
|     char versionLocal[] = "2.2.3";  //current running image | ||||
|     char versionRemote[] = "999.999.999"; //image from server | ||||
|     TEST_ASSERT_TRUE( bNewerVersion(versionLocal, versionRemote)  ); | ||||
|     TEST_ASSERT_TRUE( bMeshOtaUtilNewerVersion(versionLocal, versionRemote)  ); | ||||
| } | ||||
|  | ||||
| // ### ### ###  find start offset in firmware image ### ### ### | ||||
| @ -68,7 +68,7 @@ TEST_CASE("with http response +  0.0.1", "[find start offset in firmware image]" | ||||
| { | ||||
|     uint32_t u32StartOffset; | ||||
|     uint32_t u32DataLenght = sizeof(dataWithHttpRespone0_0_1)/sizeof(dataWithHttpRespone0_0_1[0]); | ||||
|     esp_err_t err = errFindImageStart(dataWithHttpRespone0_0_1, &u32DataLenght, &u32StartOffset); | ||||
|     esp_err_t err = errMeshOtaUtilFindImageStart(dataWithHttpRespone0_0_1, &u32DataLenght, &u32StartOffset); | ||||
|     if(err == ESP_OK) | ||||
|     { | ||||
|         TEST_ASSERT_EQUAL_INT(305, u32StartOffset); | ||||
| @ -83,7 +83,7 @@ TEST_CASE("without http response +  0.0.1", "[find start offset in firmware imag | ||||
| { | ||||
|     uint32_t u32StartOffset; | ||||
|     uint32_t u32DataLenght = sizeof(dataWithoutHttpRespone0_0_1)/sizeof(dataWithoutHttpRespone0_0_1[0]); | ||||
|     esp_err_t err =  errFindImageStart(dataWithoutHttpRespone0_0_1, &u32DataLenght, &u32StartOffset); | ||||
|     esp_err_t err =  errMeshOtaUtilFindImageStart(dataWithoutHttpRespone0_0_1, &u32DataLenght, &u32StartOffset); | ||||
|     if(err == ESP_OK) | ||||
|     { | ||||
|         TEST_ASSERT_EQUAL_INT(0, u32StartOffset); | ||||
| @ -99,7 +99,7 @@ TEST_CASE("with http response +  999.999.999", "[find start offset in firmware i | ||||
| { | ||||
|     uint32_t u32StartOffset; | ||||
|     uint32_t u32DataLenght = sizeof(dataWithHttpRespone999_999_999)/sizeof(dataWithHttpRespone999_999_999[0]); | ||||
|     esp_err_t err = errFindImageStart(dataWithHttpRespone999_999_999, &u32DataLenght, &u32StartOffset); | ||||
|     esp_err_t err = errMeshOtaUtilFindImageStart(dataWithHttpRespone999_999_999, &u32DataLenght, &u32StartOffset); | ||||
|     if(err == ESP_OK) | ||||
|     { | ||||
|         TEST_ASSERT_EQUAL_INT(305, u32StartOffset); | ||||
| @ -114,7 +114,7 @@ TEST_CASE("without http response +  999.999.999", "[find start offset in firmwar | ||||
| { | ||||
|     uint32_t u32StartOffset; | ||||
|     uint32_t u32DataLenght = sizeof(dataWithoutHttpRespone999_999_999)/sizeof(dataWithoutHttpRespone999_999_999[0]); | ||||
|     esp_err_t err = errFindImageStart(dataWithoutHttpRespone999_999_999, &u32DataLenght, &u32StartOffset); | ||||
|     esp_err_t err = errMeshOtaUtilFindImageStart(dataWithoutHttpRespone999_999_999, &u32DataLenght, &u32StartOffset); | ||||
|     if(err == ESP_OK) | ||||
|     { | ||||
|         TEST_ASSERT_EQUAL_INT(0, u32StartOffset); | ||||
| @ -129,7 +129,7 @@ TEST_CASE("with http response +  999.9.999", "[find start offset in firmware ima | ||||
| { | ||||
|     uint32_t u32StartOffset; | ||||
|     uint32_t u32DataLenght = sizeof(dataWithHttpRespone999_9_999)/sizeof(dataWithHttpRespone999_9_999[0]); | ||||
|     esp_err_t err = errFindImageStart(dataWithHttpRespone999_9_999, &u32DataLenght, &u32StartOffset); | ||||
|     esp_err_t err = errMeshOtaUtilFindImageStart(dataWithHttpRespone999_9_999, &u32DataLenght, &u32StartOffset); | ||||
|     if(err == ESP_OK) | ||||
|     { | ||||
|         TEST_ASSERT_EQUAL_INT(302, u32StartOffset); | ||||
| @ -144,7 +144,7 @@ TEST_CASE("with http response +  999.99.999", "[find start offset in firmware im | ||||
| { | ||||
|     uint32_t u32StartOffset; | ||||
|     uint32_t u32DataLenght = sizeof(dataWithHttpRespone999_99_999)/sizeof(dataWithHttpRespone999_99_999[0]); | ||||
|     esp_err_t err = errFindImageStart(dataWithHttpRespone999_99_999, &u32DataLenght, &u32StartOffset); | ||||
|     esp_err_t err = errMeshOtaUtilFindImageStart(dataWithHttpRespone999_99_999, &u32DataLenght, &u32StartOffset); | ||||
|     if(err == ESP_OK) | ||||
|     { | ||||
|         TEST_ASSERT_EQUAL_INT(299, u32StartOffset); | ||||
| @ -162,10 +162,10 @@ TEST_CASE("extract version 0.0.1", "[extract image version number]") | ||||
|     char versionLocal[] = "0.0.0";  //current running image | ||||
|     char versionRemote[12];//image from server | ||||
|     uint32_t u32DataLenght = sizeof(dataWithHttpRespone0_0_1)/sizeof(dataWithHttpRespone0_0_1[0]); | ||||
|     esp_err_t err = errExtractVersionNumber(dataWithHttpRespone0_0_1, &u32DataLenght, versionRemote); | ||||
|     esp_err_t err = errMeshOtaUtilExtractVersionNumber(dataWithHttpRespone0_0_1, &u32DataLenght, versionRemote); | ||||
|     if(err == ESP_OK) | ||||
|     { | ||||
|         TEST_ASSERT_TRUE( bNewerVersion(versionLocal, versionRemote)  ); | ||||
|         TEST_ASSERT_TRUE( bMeshOtaUtilNewerVersion(versionLocal, versionRemote)  ); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
| @ -178,10 +178,10 @@ TEST_CASE("extract version 999.999.999", "[extract image version number]") | ||||
|     char versionLocal[] = "0.0.0";  //current running image | ||||
|     char versionRemote[12];//image from server | ||||
|     uint32_t u32DataLenght = sizeof(dataWithHttpRespone999_999_999)/sizeof(dataWithHttpRespone999_999_999[0]); | ||||
|     esp_err_t err = errExtractVersionNumber(dataWithHttpRespone999_999_999, &u32DataLenght, versionRemote); | ||||
|     esp_err_t err = errMeshOtaUtilExtractVersionNumber(dataWithHttpRespone999_999_999, &u32DataLenght, versionRemote); | ||||
|     if(err == ESP_OK) | ||||
|     { | ||||
|         TEST_ASSERT_TRUE( bNewerVersion(versionLocal, versionRemote)  ); | ||||
|         TEST_ASSERT_TRUE( bMeshOtaUtilNewerVersion(versionLocal, versionRemote)  ); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
| @ -194,10 +194,10 @@ TEST_CASE("extract version 999.99.999", "[extract image version number]") | ||||
|     char versionLocal[] = "999.100.999";  //current running image | ||||
|     char versionRemote[12];//image from server | ||||
|     uint32_t u32DataLenght = sizeof(dataWithHttpRespone999_99_999)/sizeof(dataWithHttpRespone999_99_999[0]); | ||||
|     esp_err_t err = errExtractVersionNumber(dataWithHttpRespone999_99_999, &u32DataLenght, versionRemote); | ||||
|     esp_err_t err = errMeshOtaUtilExtractVersionNumber(dataWithHttpRespone999_99_999, &u32DataLenght, versionRemote); | ||||
|     if(err == ESP_OK) | ||||
|     { | ||||
|         TEST_ASSERT_FALSE( bNewerVersion(versionLocal, versionRemote)  ); | ||||
|         TEST_ASSERT_FALSE( bMeshOtaUtilNewerVersion(versionLocal, versionRemote)  ); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|  | ||||
| @ -107,20 +107,20 @@ void vTaskReadUserInput(void *arg) | ||||
|  | ||||
|                     memcpy(meshPacket.au8Payload, &bTmpPacket, sizeof(BLINKY_PACKET_t)); | ||||
|  | ||||
|                     if(bIsRootNode() == false) | ||||
|                     if(bMeshNetworkIsRootNode() == false) | ||||
|                         { | ||||
|                             //this node is not root --> send led action to parent | ||||
|                             ERROR_CHECK(errGetParentNode(&addrParent)); | ||||
|                             ERROR_CHECK(errSendMeshPacket(&addrParent, &meshPacket)); | ||||
|                             ERROR_CHECK(errMeshNetworkGetParentNode(&addrParent)); | ||||
|                             ERROR_CHECK(errMeshNetworkSendMeshPacket(&addrParent, &meshPacket)); | ||||
|                         } | ||||
|                     else | ||||
|                         { | ||||
|                             //this node is root --> send led action to children | ||||
|                             ERROR_CHECK(errGetChildren(childrenAddr, &u16ChildrenSize)); | ||||
|                             ERROR_CHECK(errMeshNetworkGetChildren(childrenAddr, &u16ChildrenSize)); | ||||
|  | ||||
|                             for (uint16_t u16Index = 0; u16Index < u16ChildrenSize; u16Index++) | ||||
|                                 { | ||||
|                                     ERROR_CHECK (errSendMeshPacket(&childrenAddr[u16Index], &meshPacket)); | ||||
|                                     ERROR_CHECK (errMeshNetworkSendMeshPacket(&childrenAddr[u16Index], &meshPacket)); | ||||
|                                 } | ||||
|                         } | ||||
|                     vTaskDelay(200 / portTICK_PERIOD_MS); | ||||
| @ -170,15 +170,15 @@ void vTaskReceiveData(void *arg) | ||||
|                         } | ||||
|                 } | ||||
|  | ||||
|             ERROR_CHECK(errGetChildren(childrenAddr, &u16ChildrenSize)); //get all children attached to this node | ||||
|             ERROR_CHECK(errMeshNetworkGetChildren(childrenAddr, &u16ChildrenSize)); //get all children attached to this node | ||||
|             memcpy(meshPacket.au8Payload, &bTmpPacket, sizeof(BLINKY_PACKET_t)); //copy led action in mesh packet payload | ||||
|  | ||||
|             for (uint16_t u16Index = 0; u16Index < u16ChildrenSize; u16Index++) | ||||
|                 { | ||||
|                     //loop through children | ||||
|                     if(bCheckMACEquality(bTmpPacket.meshSenderAddr.addr,  childrenAddr[u16Index].addr) == false) //exclude the sender node | ||||
|                     if(bMeshNetworkCheckMACEquality(bTmpPacket.meshSenderAddr.addr,  childrenAddr[u16Index].addr) == false) //exclude the sender node | ||||
|                         { | ||||
|                             ERROR_CHECK (errSendMeshPacket(&childrenAddr[u16Index], &meshPacket)); //send to child | ||||
|                             ERROR_CHECK (errMeshNetworkSendMeshPacket(&childrenAddr[u16Index], &meshPacket)); //send to child | ||||
|                         } | ||||
|                 } | ||||
|             vTaskDelay(200 / portTICK_PERIOD_MS); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user