refactor #2
| @ -22,47 +22,10 @@ https_client_ret_t https_clientInitialize() | ||||
|  | ||||
|     i32RetHTTPClient = https_clientInitEmbedTLS(); | ||||
|  | ||||
|     if(i32RetHTTPClient == HTTPS_CLIENT_OK) | ||||
|     if (i32RetHTTPClient == HTTPS_CLIENT_ERROR_INIT_EMBEDTLS) | ||||
|         { | ||||
|             i32RetHTTPClient = https_clientConnectToServer(); | ||||
|         } | ||||
|  | ||||
|     if(i32RetHTTPClient == HTTPS_CLIENT_OK) | ||||
|         { | ||||
|             i32RetHTTPClient = https_clientValidateServer(); | ||||
|         } | ||||
|  | ||||
|     if(i32RetHTTPClient == HTTPS_CLIENT_OK) | ||||
|         { | ||||
|             i32RetHTTPClient = https_clientSendRequest(); | ||||
|         } | ||||
|  | ||||
|     switch (i32RetHTTPClient) | ||||
|         { | ||||
|         case HTTPS_CLIENT_ERROR_INIT_EMBEDTLS: | ||||
|             ESP_LOGE(TAG, "Unable to initialize EmbedTLS"); | ||||
|             i32RetHTTPClient = HTTPS_CLIENT_ERROR; | ||||
|             break; | ||||
|         case HTTPS_CLIENT_ERROR_INIT_CONNECT_TWO_SERVER: | ||||
|             ESP_LOGE(TAG, "Unable to connect to server"); | ||||
|             i32RetHTTPClient = HTTPS_CLIENT_ERROR; | ||||
|             break; | ||||
|         case HTTPS_CLIENT_ERROR_INIT_VALIDATE_SERVER: | ||||
|             ESP_LOGE(TAG, "Unable to validate the server"); | ||||
|             i32RetHTTPClient = HTTPS_CLIENT_ERROR; | ||||
|             break; | ||||
|         case HTTPS_CLIENT_ERROR_INIT_SEND_REQUEST: | ||||
|             ESP_LOGE(TAG, "Unable to send request to server"); | ||||
|             i32RetHTTPClient = HTTPS_CLIENT_ERROR; | ||||
|             break; | ||||
|         case HTTPS_CLIENT_OK: | ||||
|             ESP_LOGI(TAG, "HTTPS Client successfully initialized"); | ||||
|             i32RetHTTPClient = HTTPS_CLIENT_OK; | ||||
|             break; | ||||
|         default: | ||||
|             i32RetHTTPClient = HTTPS_CLIENT_ERROR; | ||||
|             ESP_LOGE(TAG, "Unknown error while init https client"); | ||||
|             break; | ||||
|         } | ||||
|     return i32RetHTTPClient; | ||||
| } | ||||
| @ -78,6 +41,7 @@ https_client_ret_t https_clientRetrieveData(char* pu8Data, uint32_t* pu32DataLen | ||||
|  | ||||
|     while (bRetriveData) | ||||
|         { | ||||
|             mbedtls_ssl_conf_read_timeout(&sHTTPS_ClientConfig.conf, HTTPS_READ_TIMEOUT); //set timeout | ||||
|             //Reading HTTP response | ||||
|             i32RetRetrieveData = mbedtls_ssl_read(&sHTTPS_ClientConfig.ssl, (unsigned char *)(pu8Data+(*pu32BytesRead)), ((*pu32DataLenght)-(*pu32BytesRead))); | ||||
|  | ||||
| @ -105,13 +69,18 @@ https_client_ret_t https_clientRetrieveData(char* pu8Data, uint32_t* pu32DataLen | ||||
|                     pu32BytesRead = 0; | ||||
|                 } | ||||
|  | ||||
|             if(i32RetRetrieveData == MBEDTLS_ERR_SSL_TIMEOUT ) | ||||
|                 { | ||||
|                     //timeout --> stop reading | ||||
|                     bRetriveData = false; | ||||
|                 } | ||||
|  | ||||
|             if(i32RetRetrieveData == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) | ||||
|                 { | ||||
|                     //connection is going to be closed | ||||
|                     i32RetHTTPClient = HTTPS_CLIENT_ERROR; | ||||
|                     bRetriveData = false; | ||||
|                 } | ||||
|  | ||||
|         } | ||||
|     return i32RetHTTPClient; | ||||
| } | ||||
| @ -120,15 +89,6 @@ https_client_ret_t https_clientReset() | ||||
| { | ||||
|     https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK; | ||||
|  | ||||
|     i32RetHTTPClient = https_clientSendRequest(); | ||||
|  | ||||
|     return i32RetHTTPClient; | ||||
| } | ||||
|  | ||||
| https_client_ret_t https_clientDeinitialize() | ||||
| { | ||||
|     https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK; | ||||
|  | ||||
|     i32RetHTTPClient = mbedtls_ssl_close_notify(&sHTTPS_ClientConfig.ssl); //close session | ||||
|  | ||||
|     if(i32RetHTTPClient != ESP_OK) | ||||
| @ -250,7 +210,7 @@ https_client_ret_t https_clientConnectToServer() | ||||
|  | ||||
|     if(i32RetServerConnect == ESP_OK) | ||||
|         { | ||||
|             mbedtls_ssl_set_bio(&sHTTPS_ClientConfig.ssl, &sHTTPS_ClientConfig.server_fd, mbedtls_net_send, mbedtls_net_recv, NULL); | ||||
|             mbedtls_ssl_set_bio(&sHTTPS_ClientConfig.ssl, &sHTTPS_ClientConfig.server_fd, mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout); | ||||
|  | ||||
|             //Performing the SSL/TLS handshake | ||||
|             while ((i32RetServerConnect = mbedtls_ssl_handshake(&sHTTPS_ClientConfig.ssl)) != 0) | ||||
|  | ||||
| @ -8,6 +8,8 @@ xQueueHandle queueMessageOTA; //mesh ota controll messages like "OTA_Version_Res | ||||
|  | ||||
| SemaphoreHandle_t bsStartStopServerWorker; //binary semaphore | ||||
|  | ||||
| const esp_partition_t* pOTAPartition; //pointer to ota partition | ||||
|  | ||||
| esp_err_t errMeshOTAInitialize() | ||||
| { | ||||
|     esp_err_t err = ESP_OK; | ||||
| @ -46,6 +48,17 @@ esp_err_t errMeshOTAInitialize() | ||||
|     ERROR_CHECK(errMeshNetworkSetOTAMessageHandleHandle(vAddOTAControllMessageToQueue)); | ||||
|     ERROR_CHECK(errMeshNetworkSetChangeStateOfServerWorkerHandle(vChangeStateOfServerWorker)); | ||||
|  | ||||
|     if(err == ESP_OK) | ||||
|         { | ||||
|             pOTAPartition =  esp_ota_get_next_update_partition(NULL); //get ota partition | ||||
|  | ||||
|             if(pOTAPartition == NULL) | ||||
|                 { | ||||
|                     err = ESP_FAIL; | ||||
|                     ESP_LOGE(LOG_TAG, "unable to get next ota partition"); | ||||
|                 } | ||||
|         } | ||||
|  | ||||
|     if(err == ESP_OK) | ||||
|         { | ||||
|             xReturned = xTaskCreate(vTaskServerWorker, "vTaskServerWorker", 8192, NULL, 5, NULL); | ||||
| @ -130,7 +143,7 @@ void vTaskServerWorker(void *arg) | ||||
| { | ||||
|     esp_err_t err; | ||||
|     bool bNewOTAImage = false; // true if a new ota image was downloaded and validated | ||||
|    // bool bFirstRun = true; | ||||
|     bool bFirstRun = true; | ||||
|  | ||||
|     while(true) | ||||
|         { | ||||
| @ -140,16 +153,18 @@ void vTaskServerWorker(void *arg) | ||||
|  | ||||
|             if (esp_mesh_is_root()) //check again that this node is the root node | ||||
|                 { | ||||
|                    // if(bFirstRun == true) | ||||
|                        // { | ||||
|                     if(bFirstRun == true) | ||||
|                         { | ||||
|                             ERROR_CHECK(https_clientInitialize()); | ||||
|                            // bFirstRun = false; | ||||
|                         //} | ||||
|                             bFirstRun = false; | ||||
|                         } | ||||
|  | ||||
|                     ERROR_CHECK(https_clientConnectToServer()); | ||||
|                     ERROR_CHECK(https_clientValidateServer()); | ||||
|                     ERROR_CHECK(https_clientSendRequest()); | ||||
|  | ||||
|                     ERROR_CHECK(errOTAHTTPS(&bNewOTAImage)); | ||||
|                      https_clientDeinitialize(); | ||||
|  | ||||
|                    // https_clientReset(); | ||||
|                     https_clientReset(); | ||||
|  | ||||
|                     if(bNewOTAImage == true) | ||||
|                         { | ||||
| @ -167,85 +182,58 @@ void vTaskServerWorker(void *arg) | ||||
| esp_err_t errOTAHTTPS(bool* pbNewOTAImage) | ||||
| { | ||||
|     esp_err_t err = ESP_OK; | ||||
|     char buffer[1024U]; | ||||
|     uint32_t u32BufferLenght = 1024U; | ||||
|     uint32_t u32BytesRead = 0; | ||||
|     char pcRemoteVersionNumber[12]; | ||||
|     const esp_partition_t * currentPartition; | ||||
|     const esp_partition_t * otaPartition; | ||||
|     static esp_ota_handle_t otaHandle; | ||||
|     uint32_t u32StartOffset; | ||||
|     //esp_app_desc_t otaPartitionDesc; | ||||
|     esp_app_desc_t curPartitionDesc; | ||||
|     char u8OTABuffer[OTA_HTTPS_SEGMENT_SIZE]; //store image segment from server before ota write | ||||
|     uint32_t u32BufferLenght = OTA_HTTPS_SEGMENT_SIZE; //size of buffer | ||||
|     uint32_t u32BytesRead = 0; //number of bytes that are read from server, <= u32BufferLenght | ||||
|     char pcRemoteVersionNumber[12]; //string for version number in server image | ||||
|     const esp_partition_t* pBootPartition; //pointer to boot partition (that will booted after reset) | ||||
|     static esp_ota_handle_t otaHandle; //OTA process handle | ||||
|     uint32_t u32StartOffset = 0U; //start offset for image (exclude the http response data) | ||||
|     esp_app_desc_t bootPartitionDesc; //Metadate 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 | ||||
|  | ||||
|     currentPartition = esp_ota_get_boot_partition(); | ||||
|     ESP_LOGI(LOG_TAG, "Type: %d",  (*currentPartition).subtype); | ||||
|     ESP_LOGI(LOG_TAG, "Start address: %d",  (*currentPartition).address); | ||||
|     ESP_LOGI(LOG_TAG, "Size: %d",  (*currentPartition).size); | ||||
|     ESP_LOGI(LOG_TAG, "Encrypted: %d",  (*currentPartition).encrypted); | ||||
|     ERROR_CHECK(https_clientRetrieveData(u8OTABuffer, &u32BufferLenght, &u32BytesRead)); //read first bytes if image, including the version | ||||
|  | ||||
|     ERROR_CHECK(errExtractVersionNumber(u8OTABuffer, &u32BytesRead, pcRemoteVersionNumber)); //extract version numbers | ||||
|  | ||||
|     ERROR_CHECK(esp_ota_get_partition_description(currentPartition, &curPartitionDesc)); | ||||
|     //ESP_LOGI(LOG_TAG, "currentPartition project_name: %s",  (curPartitionDesc).project_name); | ||||
|     //ESP_LOGI(LOG_TAG, "currentPartition version: %s",  (curPartitionDesc).version); | ||||
|     //ESP_LOGI(LOG_TAG, "currentPartition Timestamp: %s %s",  (curPartitionDesc).date, (curPartitionDesc).time); | ||||
|  | ||||
|  | ||||
|  | ||||
|     ERROR_CHECK(https_clientRetrieveData(buffer, &u32BufferLenght, &u32BytesRead)); //read first bytes if image, including the version | ||||
|  | ||||
|     //ESP_LOGI(LOG_TAG, "Data received: %i", u32BytesRead); | ||||
|  | ||||
|     ERROR_CHECK(errExtractVersionNumber(buffer, &u32BytesRead, pcRemoteVersionNumber)); | ||||
|  | ||||
|     if(err == ESP_OK) | ||||
|     if(err == ESP_OK) //check if version number is found | ||||
|         { | ||||
|             if(bNewerVersion((curPartitionDesc).version, pcRemoteVersionNumber)) //compare local and remote version | ||||
|             if(bNewerVersion((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"); | ||||
|  | ||||
|                     otaPartition =  esp_ota_get_next_update_partition(currentPartition); | ||||
|  | ||||
|                     if(otaPartition == NULL) | ||||
|                         { | ||||
|                             err = ESP_FAIL; | ||||
|                             ESP_LOGE(LOG_TAG, "unable to get next ota partition"); | ||||
|                         } | ||||
|  | ||||
|                     ERROR_CHECK(errFindImageStart(buffer, &u32BufferLenght, &u32StartOffset)); //get image start offset | ||||
|  | ||||
|                     //ESP_LOGI(LOG_TAG, "first byte offset: %i", u32StartOffset); | ||||
|                     //ESP_LOGI(LOG_TAG, "first byte: %x", buffer[u32StartOffset]); | ||||
|                     ERROR_CHECK(errFindImageStart(u8OTABuffer, &u32BufferLenght, &u32StartOffset)); //get image start offset | ||||
|  | ||||
|                     //TODO lock ota mutex | ||||
|  | ||||
|                     ERROR_CHECK(esp_ota_begin(otaPartition, OTA_SIZE_UNKNOWN, &otaHandle)); | ||||
|  | ||||
|                     ERROR_CHECK(esp_ota_begin(pOTAPartition, OTA_SIZE_UNKNOWN, &otaHandle)); //start ota update process | ||||
|                     if(err == ESP_OK) | ||||
|                         { | ||||
|                             //image download and ota partition write | ||||
|                             ESP_LOGI(LOG_TAG, "start ota https download"); | ||||
|                             do | ||||
|                                 { | ||||
|                                     ESP_LOGI(LOG_TAG, "OTA-Data written: %i", u32BytesRead); | ||||
|                                     ERROR_CHECK(esp_ota_write(otaHandle, (const void*) buffer+u32StartOffset, (u32BytesRead-u32StartOffset))); | ||||
|                                     //TODO progress log | ||||
|                                     ERROR_CHECK(esp_ota_write(otaHandle, (const void*) u8OTABuffer+u32StartOffset, (u32BytesRead-u32StartOffset))); | ||||
|  | ||||
|                                     if(err == ESP_OK) | ||||
|                                         { | ||||
|                                             //write was succsesfull | ||||
|                                             u32StartOffset = 0U; //reset the offset for next download | ||||
|                                             https_clientRetrieveData(buffer, &u32BufferLenght, &u32BytesRead); //download next data segment | ||||
|                                             ERROR_CHECK(https_clientRetrieveData(u8OTABuffer, &u32BufferLenght, &u32BytesRead)); //download next data segment | ||||
|                                         } | ||||
|                                 } | ||||
|                             while ((u32BytesRead > 0) && (err == ESP_OK)); | ||||
|                             while ((u32BytesRead > 0) && (err == ESP_OK)); //loop until error or complete image downloaded | ||||
|                         } | ||||
|  | ||||
|                     if(err == ESP_OK) | ||||
|                         { | ||||
|                             //no error occurred --> finish ota update process | ||||
|                             ERROR_CHECK(esp_ota_end(otaHandle)); //finish process | ||||
|                             ERROR_CHECK(esp_ota_set_boot_partition(otaPartition)); //set new image as boot | ||||
|                             ERROR_CHECK(esp_ota_set_boot_partition(pOTAPartition)); //set new image as boot | ||||
|                             if(err == ESP_OK) | ||||
|                                 { | ||||
|                                     *pbNewOTAImage = true; //image validated | ||||
| @ -253,23 +241,17 @@ esp_err_t errOTAHTTPS(bool* pbNewOTAImage) | ||||
|                         } | ||||
|                     else | ||||
|                         { | ||||
|                             // error occurred --> abort ota update process | ||||
|                             ESP_LOGE(LOG_TAG, "abort ota process"); | ||||
|                             //error occurred --> abort ota update process | ||||
|                             ESP_LOGE(LOG_TAG, "abort ota process due to error 0x%x -> %s", err, esp_err_to_name(err)); | ||||
|                             ERROR_CHECK(esp_ota_abort(otaHandle)); | ||||
|                             *pbNewOTAImage = false; //ota update failed | ||||
|                         } | ||||
|  | ||||
|                     //TODO unlock ota mutex | ||||
|  | ||||
|                 } //end newer version on server | ||||
|         } //end version number extracted | ||||
|  | ||||
|  | ||||
|  | ||||
|     return err; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Return true if remote version is newer (higher) than local version | ||||
| */ | ||||
| @ -403,9 +385,9 @@ esp_err_t esp_mesh_ota_send(mesh_addr_t* dest) | ||||
|  | ||||
|     static uint32_t u32index; | ||||
|  | ||||
|     const esp_partition_t * currentPartition = esp_ota_get_boot_partition(); | ||||
|     const esp_partition_t * pBootPartition = esp_ota_get_boot_partition(); | ||||
|  | ||||
|     if((*currentPartition).subtype == 0) | ||||
|     if((*pBootPartition).subtype == 0) | ||||
|     { | ||||
|  | ||||
|         int data_read = 0; | ||||
| @ -422,7 +404,7 @@ esp_err_t esp_mesh_ota_send(mesh_addr_t* dest) | ||||
|         else | ||||
|         { | ||||
|             ESP_LOGI(MESH_TAG, "OTA-Data read: %i", u32index); | ||||
|             err =  esp_partition_read(currentPartition, (1024*u32index), packet.au8Payload, 1024 ); | ||||
|             err =  esp_partition_read(pBootPartition, (1024*u32index), packet.au8Payload, 1024 ); | ||||
|             ESP_ERROR_CHECK(err); | ||||
|             data_read = 1024; | ||||
|             u32index++; | ||||
| @ -438,7 +420,7 @@ esp_err_t esp_mesh_ota_send(mesh_addr_t* dest) | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         ESP_LOGI(MESH_TAG, "Subtype: %d",  (*currentPartition).subtype); | ||||
|         ESP_LOGI(MESH_TAG, "Subtype: %d",  (*pBootPartition).subtype); | ||||
|     } | ||||
|     return err; | ||||
| } | ||||
| @ -449,14 +431,14 @@ esp_err_t esp_mesh_ota_receive(mesh_addr_t* dest, struct ota_mesh_packet* packet | ||||
|     static esp_ota_handle_t otaHandle; | ||||
|     static uint32_t u32index; | ||||
|  | ||||
|     const esp_partition_t * currentPartition = esp_ota_get_boot_partition(); | ||||
|     const esp_partition_t * otaPartition =  esp_ota_get_next_update_partition(currentPartition); | ||||
|     const esp_partition_t * pBootPartition = esp_ota_get_boot_partition(); | ||||
|     const esp_partition_t * pOTAPartition =  esp_ota_get_next_update_partition(pBootPartition); | ||||
|  | ||||
|     if(u32index == 0) | ||||
|     { | ||||
|         //first run | ||||
|  | ||||
|         err = esp_ota_begin(otaPartition, OTA_SIZE_UNKNOWN, &otaHandle); | ||||
|         err = esp_ota_begin(pOTAPartition, OTA_SIZE_UNKNOWN, &otaHandle); | ||||
|         ESP_ERROR_CHECK(err); | ||||
|     } | ||||
|  | ||||
| @ -480,11 +462,11 @@ esp_err_t esp_mesh_ota_receive(mesh_addr_t* dest, struct ota_mesh_packet* packet | ||||
|         err = esp_ota_end(otaHandle); | ||||
|         ESP_ERROR_CHECK(err); | ||||
|         esp_app_desc_t otaPartitionDesc; | ||||
|         err = esp_ota_get_partition_description(otaPartition, &otaPartitionDesc); | ||||
|         err = esp_ota_get_partition_description(pOTAPartition, &otaPartitionDesc); | ||||
|         ESP_ERROR_CHECK(err); | ||||
|         ESP_LOGI(MESH_TAG, "otaPartition project_name: %s",  (otaPartitionDesc).project_name); | ||||
|         ESP_LOGI(MESH_TAG, "pOTAPartition project_name: %s",  (otaPartitionDesc).project_name); | ||||
|  | ||||
|         err = esp_ota_set_boot_partition(otaPartition); | ||||
|         err = esp_ota_set_boot_partition(pOTAPartition); | ||||
|         ESP_ERROR_CHECK(err); | ||||
|  | ||||
|         struct ota_mesh_packet retPacket; | ||||
|  | ||||
| @ -51,6 +51,8 @@ | ||||
| #define HTTPS_CLIENT_ERROR_INIT_VALIDATE_SERVER -4 | ||||
| #define HTTPS_CLIENT_ERROR_INIT_SEND_REQUEST -5 | ||||
|  | ||||
| #define HTTPS_READ_TIMEOUT 1000 //ms | ||||
|  | ||||
| struct HTTPS_Client | ||||
| { | ||||
|     mbedtls_entropy_context entropy; | ||||
| @ -65,9 +67,11 @@ typedef int32_t https_client_ret_t; | ||||
| typedef struct HTTPS_Client HTTPS_Client_t; | ||||
|  | ||||
| https_client_ret_t https_clientInitialize(); | ||||
| https_client_ret_t https_clientConnectToServer(); | ||||
| https_client_ret_t https_clientValidateServer(); | ||||
| https_client_ret_t https_clientSendRequest(); | ||||
| https_client_ret_t https_clientRetrieveData(char* pu8Data, uint32_t* pu32DataLenght, uint32_t* pu32BytesRead); | ||||
| https_client_ret_t https_clientReset(); | ||||
| https_client_ret_t https_clientDeinitialize(); | ||||
|  | ||||
| #endif /* H_HTTPS_CLIENT */ | ||||
|  | ||||
|  | ||||
| @ -20,6 +20,7 @@ | ||||
| #define QUEUE_NODES_SIZE 10 | ||||
| #define QUEUE_MESSAGE_OTA_SIZE 10 | ||||
| #define SERVER_CHECK_INTERVAL 30 //in seconds | ||||
| #define OTA_HTTPS_SEGMENT_SIZE 2048U | ||||
|  | ||||
| #define ERROR_CHECK(x) if (err == ESP_OK)                                                               \ | ||||
|     {                                                                                                   \ | ||||
|  | ||||
		Reference in New Issue
	
	Block a user