diff --git a/components/cmd_system/cmd_system.c b/components/cmd_system/cmd_system.c index 2928bf61..12337782 100644 --- a/components/cmd_system/cmd_system.c +++ b/components/cmd_system/cmd_system.c @@ -6,14 +6,13 @@ software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ -#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE +//#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE #include #include #include #include "esp_log.h" #include "esp_console.h" #include "esp_system.h" -#include "esp_sleep.h" #include "esp_spi_flash.h" #include "driver/rtc_io.h" #include "driver/uart.h" @@ -28,13 +27,15 @@ #include "esp_ota_ops.h" #include "platform_esp32.h" #include "nvs_utilities.h" +#include "esp_sleep.h" +#include "driver/uart.h" // for the uart driver access #ifdef CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS #define WITH_TASKS_INFO 1 #endif -static const char * TAG = "platform_esp32"; +static const char * TAG = "cmd_system"; static void register_free(); static void register_heap(); @@ -43,6 +44,7 @@ static void register_restart(); static void register_deep_sleep(); static void register_light_sleep(); static void register_factory_boot(); +static void register_restart_ota(); #if WITH_TASKS_INFO static void register_tasks(); #endif @@ -56,6 +58,7 @@ void register_system() register_deep_sleep(); register_light_sleep(); register_factory_boot(); + register_restart_ota(); #if WITH_TASKS_INFO register_tasks(); #endif @@ -99,6 +102,17 @@ esp_err_t guided_boot(esp_partition_subtype_t partition_subtype) #if RECOVERY_APPLICATION if(partition_subtype ==ESP_PARTITION_SUBTYPE_APP_FACTORY){ ESP_LOGW(TAG,"RECOVERY application is already active"); + ESP_LOGW(TAG, "Restarting after tx complete"); + uart_wait_tx_done(UART_NUM_1, 500 / portTICK_RATE_MS); + esp_restart(); + return ESP_OK; + } +#else + if(partition_subtype !=ESP_PARTITION_SUBTYPE_APP_FACTORY){ + ESP_LOGW(TAG,"SQUEEZELITE application is already active"); + ESP_LOGW(TAG, "Restarting after tx complete"); + uart_wait_tx_done(UART_NUM_1, 500 / portTICK_RATE_MS); + esp_restart(); return ESP_OK; } #endif @@ -115,30 +129,36 @@ esp_err_t guided_boot(esp_partition_subtype_t partition_subtype) else { partition = (esp_partition_t *) esp_partition_get(it); + ESP_LOGD(TAG, "Releasing partition iterator"); + esp_partition_iterator_release(it); if(partition != NULL){ ESP_LOGI(TAG, "Found application partition %s sub type %u", partition->label,partition_subtype); err=esp_ota_set_boot_partition(partition); if(err!=ESP_OK){ ESP_LOGE(TAG,"Unable to set partition as active for next boot. %s",esp_err_to_name(err)); + bFound=false; set_status_message(ERROR, "Unable to select partition for reboot."); } else{ + ESP_LOGW(TAG, "Application partition %s sub type %u is selected for boot", partition->label,partition_subtype); bFound=true; set_status_message(WARNING, "Rebooting!"); } - } else { ESP_LOGE(TAG,"partition type %u not found! Unable to reboot to recovery.",partition_subtype); set_status_message(ERROR, "Partition not found."); } - esp_partition_iterator_release(it); + ESP_LOGD(TAG, "Yielding to other processes"); + taskYIELD(); if(bFound) { + ESP_LOGW(TAG,"Configuration %s changes. ",config_has_changes()?"has":"does not have"); if(!wait_for_commit()){ ESP_LOGW(TAG,"Unable to commit configuration. "); } - ESP_LOGI(TAG, "Restarting!."); + ESP_LOGW(TAG, "Restarting after tx complete"); + uart_wait_tx_done(UART_NUM_1, 500 / portTICK_RATE_MS); esp_restart(); } } @@ -148,39 +168,50 @@ esp_err_t guided_boot(esp_partition_subtype_t partition_subtype) static int restart(int argc, char **argv) { + ESP_LOGW(TAG, "\n\nPerforming a simple restart to the currently active partition."); if(!wait_for_commit()){ ESP_LOGW(TAG,"Unable to commit configuration. "); } - ESP_LOGW(TAG, "Restarting"); + ESP_LOGW(TAG, "Restarting after tx complete"); + uart_wait_tx_done(UART_NUM_1, 500 / portTICK_RATE_MS); esp_restart(); return 0; } void simple_restart() { + ESP_LOGW(TAG,"\n\n Called to perform a simple system reboot."); if(!wait_for_commit()){ ESP_LOGW(TAG,"Unable to commit configuration. "); } - ESP_LOGW(TAG, "Restarting"); + ESP_LOGW(TAG, "Restarting after tx complete"); + uart_wait_tx_done(UART_NUM_1, 500 / portTICK_RATE_MS); esp_restart(); } esp_err_t guided_restart_ota(){ + ESP_LOGW(TAG,"\n\nCalled for a reboot to OTA Application"); guided_boot(ESP_PARTITION_SUBTYPE_APP_OTA_0); - // If we're still alive, then there may not be an ota partition to boot from - guided_boot(ESP_PARTITION_SUBTYPE_APP_FACTORY); return ESP_FAIL; // return fail. This should never return... we're rebooting! } esp_err_t guided_factory(){ + ESP_LOGW(TAG,"\n\nCalled for a reboot to recovery application"); guided_boot(ESP_PARTITION_SUBTYPE_APP_FACTORY); return ESP_FAIL; // return fail. This should never return... we're rebooting! } static int restart_factory(int argc, char **argv) { + ESP_LOGW(TAG, "Executing guided boot into recovery"); guided_boot(ESP_PARTITION_SUBTYPE_APP_FACTORY); return 0; // return fail. This should never return... we're rebooting! } +static int restart_ota(int argc, char **argv) +{ + ESP_LOGW(TAG, "Executing guided boot into ota app 0"); + guided_boot(ESP_PARTITION_SUBTYPE_APP_OTA_0); + return 0; // return fail. This should never return... we're rebooting! +} static void register_restart() { const esp_console_cmd_t cmd = { @@ -191,6 +222,16 @@ static void register_restart() }; ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) ); } +static void register_restart_ota() +{ + const esp_console_cmd_t cmd = { + .command = "restart_ota", + .help = "Selects the ota app partition to boot from and performa a software reset of the chip", + .hint = NULL, + .func = &restart_ota, + }; + ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) ); +} static void register_factory_boot() { diff --git a/components/squeezelite-ota/squeezelite-ota.c b/components/squeezelite-ota/squeezelite-ota.c index 8001250e..9cde13c8 100644 --- a/components/squeezelite-ota/squeezelite-ota.c +++ b/components/squeezelite-ota/squeezelite-ota.c @@ -6,7 +6,7 @@ software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ -#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE +//#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_system.h" @@ -175,8 +175,10 @@ esp_err_t _http_event_handler(esp_http_client_event_t *evt) uint32_t elapsed_ms= (tv.tv_sec-ota_status.OTA_start.tv_sec )*1000+(tv.tv_usec-ota_status.OTA_start.tv_usec)/1000; ESP_LOGI(TAG,"OTA progress : %d/%d (%d pct), %d KB/s", ota_status.ota_actual_len, ota_status.ota_total_len, ota_status.newpct, elapsed_ms>0?ota_status.ota_actual_len*1000/elapsed_ms/1024:0); wifi_manager_refresh_ota_json(); + ota_status.lastpct=ota_status.newpct; } + taskYIELD(); } break; case HTTP_EVENT_ON_FINISH: diff --git a/components/wifi-manager/http_server.c b/components/wifi-manager/http_server.c index 2c7324de..f32abcd0 100644 --- a/components/wifi-manager/http_server.c +++ b/components/wifi-manager/http_server.c @@ -474,11 +474,8 @@ void http_server_netconn_serve(struct netconn *conn) { ESP_LOGW(TAG, "Starting process OTA for url %s",otaURL); #else ESP_LOGW(TAG, "Restarting system to process OTA for url %s",otaURL); - // close the connection cleanly - netconn_close(conn); - netconn_delete(conn); #endif - start_ota(otaURL,false); + wifi_manager_reboot_ota(otaURL); free(otaURL); } } @@ -537,23 +534,23 @@ void http_server_netconn_serve(struct netconn *conn) { netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); /* 200 ok */ netconn_close(conn); netconn_delete(conn); - guided_restart_ota(); + wifi_manager_reboot(OTA); ESP_LOGI(TAG, "http_server_netconn_serve: done serving POST reboot.json"); } else if(strstr(line, "POST /reboot.json ")) { - ESP_LOGI(TAG, "http_server_netconn_serve: POST restart.json"); + ESP_LOGI(TAG, "http_server_netconn_serve: POST reboot.json"); netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); /* 200 ok */ netconn_close(conn); netconn_delete(conn); - simple_restart(); - ESP_LOGI(TAG, "http_server_netconn_serve: done serving POST restart.json"); + wifi_manager_reboot(RESTART); + ESP_LOGI(TAG, "http_server_netconn_serve: done serving POST reboot.json"); } else if(strstr(line, "POST /recovery.json ")) { ESP_LOGI(TAG, "http_server_netconn_serve: POST recovery.json"); netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); /* 200 ok */ netconn_close(conn); netconn_delete(conn); - guided_factory(); + wifi_manager_reboot(RECOVERY); ESP_LOGI(TAG, "http_server_netconn_serve: done serving POST recovery.json"); } else if(strstr(line, "GET /status.json ")) { diff --git a/components/wifi-manager/wifi_manager.c b/components/wifi-manager/wifi_manager.c index ae82721f..f2d1a345 100644 --- a/components/wifi-manager/wifi_manager.c +++ b/components/wifi-manager/wifi_manager.c @@ -61,6 +61,7 @@ Contains the freeRTOS task and all necessary support #include "driver/adc.h" #include "cJSON.h" #include "nvs_utilities.h" +#include "cmd_system.h" #ifndef RECOVERY_APPLICATION #define RECOVERY_APPLICATION 0 @@ -222,6 +223,35 @@ void wifi_manager_disconnect_async(){ //xEventGroupSetBits(wifi_manager_event_group, WIFI_MANAGER_REQUEST_WIFI_DISCONNECT_BIT); TODO: delete } +void wifi_manager_reboot_ota(char * url){ + if(url == NULL){ + wifi_manager_send_message(ORDER_RESTART_OTA, NULL); + } + else { + wifi_manager_send_message(ORDER_RESTART_OTA_URL,strdup(url) ); + } + +} + +void wifi_manager_reboot(reboot_type_t rtype){ + switch (rtype) { + case OTA: + wifi_manager_send_message(ORDER_RESTART_OTA, NULL); + break; + case RECOVERY: + wifi_manager_send_message(ORDER_RESTART_RECOVERY, NULL); + break; + case RESTART: + wifi_manager_send_message(ORDER_RESTART, NULL); + break; + default: + ESP_LOGE(TAG,"Unknown reboot type %d", rtype); + break; + } + wifi_manager_send_message(ORDER_DISCONNECT_STA, NULL); + //xEventGroupSetBits(wifi_manager_event_group, WIFI_MANAGER_REQUEST_WIFI_DISCONNECT_BIT); TODO: delete +} + void wifi_manager_init_wifi(){ /* event handler and event group for the wifi driver */ ESP_LOGD(TAG, "Initializing wifi. Creating event group"); @@ -1432,6 +1462,20 @@ void wifi_manager( void * pvParameters ){ /* callback */ if(cb_ptr_arr[msg.code]) (*cb_ptr_arr[msg.code])(NULL); + break; + case ORDER_RESTART_OTA: + guided_restart_ota(); + break; + case ORDER_RESTART_OTA_URL: + start_ota(msg.param,false); + free(msg.param); + break; + + case ORDER_RESTART_RECOVERY: + guided_factory(); + break; + case ORDER_RESTART: + simple_restart(); break; default: break; diff --git a/components/wifi-manager/wifi_manager.h b/components/wifi-manager/wifi_manager.h index 8490d70f..5b260e1c 100644 --- a/components/wifi-manager/wifi_manager.h +++ b/components/wifi-manager/wifi_manager.h @@ -200,10 +200,24 @@ typedef enum message_code_t { EVENT_SCAN_DONE = 13, EVENT_STA_GOT_IP = 14, EVENT_REFRESH_OTA = 15, - MESSAGE_CODE_COUNT = 16 /* important for the callback array */ + ORDER_RESTART_OTA = 16, + ORDER_RESTART_RECOVERY = 17, + ORDER_RESTART_OTA_URL = 18, + ORDER_RESTART = 19, + MESSAGE_CODE_COUNT = 20 /* important for the callback array */ }message_code_t; +typedef enum reboot_type_t{ + OTA, + RECOVERY, + RESTART, +} reboot_type_t; +void wifi_manager_reboot(reboot_type_t rtype); +void wifi_manager_reboot_ota(char * url); + + + /** * @brief simplified reason codes for a lost connection. * diff --git a/main/config.c b/main/config.c index 8b1d89e2..51635c61 100644 --- a/main/config.c +++ b/main/config.c @@ -18,7 +18,7 @@ * along with this program. If not, see . * */ -#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE +//#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE #include "config.h" #include "nvs_utilities.h" @@ -565,7 +565,7 @@ void config_delete_key(const char *key){ ESP_LOGV(TAG, "Structure before delete \n%s", struc_str); free(struc_str); } - cJSON * entry = cJSON_GetObjectItemCaseSensitive(nvs_json, key); + cJSON * entry = cJSON_DetachItemFromObjectCaseSensitive(nvs_json, key); if(entry !=NULL){ ESP_LOGI(TAG, "Removing config key [%s]", entry->string); cJSON_Delete(entry); @@ -574,7 +574,6 @@ void config_delete_key(const char *key){ ESP_LOGV(TAG, "Structure after delete \n%s", struc_str); free(struc_str); } - } else { ESP_LOGW(TAG, "Unable to remove config key [%s]: not found.", key); diff --git a/main/config.h b/main/config.h index 809bde58..2d2e8bcb 100644 --- a/main/config.h +++ b/main/config.h @@ -10,7 +10,7 @@ extern "C" { #ifdef __cplusplus } #endif -bool config_has_uncommitted(); +bool config_has_changes(); void config_commit_to_nvs(); void config_start_timer(); void config_init(); diff --git a/main/esp_app_main.c b/main/esp_app_main.c index 1c30c23a..5bd86c13 100644 --- a/main/esp_app_main.c +++ b/main/esp_app_main.c @@ -18,7 +18,7 @@ * along with this program. If not, see . * */ -#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE +//#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE #include "platform_esp32.h" #include "led.h" #include