diff --git a/README.md b/README.md index 88608d41..74e2d3b4 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ The squeezelite options are very similar to the regular Linux ones. Differences To add options that require quotes ("), escape them with \". For example, so use a BT speaker named MySpeaker and resample everything to 44100 (which is needed with Bluetooth) and use 16 bits resample with medium quality, the command line is: -nvs_set autoexec2 str -v "squeezelite -o \"BT -n 'MySpeaker'\" -b 500:2000 -R -u m -Z 192000 -r \"44100-44100\"" +nvs_set autoexec1 str -v "squeezelite -o \"BT -n 'MySpeaker'\" -b 500:2000 -R -u m -Z 192000 -r \"44100-44100\"" # Additional misc notes to do your owm build MOST IMPORTANT: create the right default config file diff --git a/components/squeezelite-ota/squeezelite-ota.c b/components/squeezelite-ota/squeezelite-ota.c index 33de4628..77618d30 100644 --- a/components/squeezelite-ota/squeezelite-ota.c +++ b/components/squeezelite-ota/squeezelite-ota.c @@ -26,6 +26,18 @@ #include #include + + + +#include "esp_image_format.h" +#include "esp_secure_boot.h" +#include "esp_flash_encrypt.h" +#include "esp_spi_flash.h" +#include "sdkconfig.h" + +#include "esp_ota_ops.h" + +#define OTA_FLASH_ERASE_BLOCK (1024*100) static const char *TAG = "squeezelite-ota"; extern const uint8_t server_cert_pem_start[] asm("_binary_github_pem_start"); extern const uint8_t server_cert_pem_end[] asm("_binary_github_pem_end"); @@ -49,10 +61,10 @@ static struct { struct timeval tv; static esp_http_client_config_t ota_config; -extern void CODE_RAM_LOCATION wifi_manager_refresh_ota_json(); +extern void wifi_manager_refresh_ota_json(); -void CODE_RAM_LOCATION _printMemStats(){ - ESP_LOGI(TAG,"Heap internal:%zu (min:%zu) external:%zu (min:%zu)\n", +void _printMemStats(){ + ESP_LOGI(TAG,"Heap internal:%zu (min:%zu) external:%zu (min:%zu)", heap_caps_get_free_size(MALLOC_CAP_INTERNAL), heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL), heap_caps_get_free_size(MALLOC_CAP_SPIRAM), @@ -66,7 +78,7 @@ void triggerStatusJsonRefresh(const char * status, ...){ _printMemStats(); wifi_manager_refresh_ota_json(); } -const char * CODE_RAM_LOCATION ota_get_status(){ +const char * ota_get_status(){ if(!ota_status.bInitialized) { memset(ota_status.status_text, 0x00,sizeof(ota_status.status_text)); @@ -74,7 +86,7 @@ const char * CODE_RAM_LOCATION ota_get_status(){ } return ota_status.status_text; } -uint8_t CODE_RAM_LOCATION ota_get_pct_complete(){ +uint8_t ota_get_pct_complete(){ return ota_status.ota_total_len==0?0: (uint8_t)((float)ota_status.ota_actual_len/(float)ota_status.ota_total_len*100.0f); } @@ -89,7 +101,7 @@ static void __attribute__((noreturn)) task_fatal_error(void) } } #define FREE_RESET(p) if(p!=NULL) { free(p); p=NULL; } -esp_err_t CODE_RAM_LOCATION _http_event_handler(esp_http_client_event_t *evt) +esp_err_t _http_event_handler(esp_http_client_event_t *evt) { // -------------- // Received parameters @@ -151,27 +163,15 @@ esp_err_t CODE_RAM_LOCATION _http_event_handler(esp_http_client_event_t *evt) if(ota_status.lastpct!=ota_status.newpct ) { gettimeofday(&tv, NULL); - 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 chunk : %d bytes (%d of %d) (%d pct), %d KB/s", evt->data_len, 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; - ESP_LOGI(TAG,"OTA chunk : %d bytes (%d of %d) (%d pct), %d KB/s", evt->data_len, 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); - ESP_LOGD(TAG,"Heap internal:%zu (min:%zu) external:%zu (min:%zu)\n", - heap_caps_get_free_size(MALLOC_CAP_INTERNAL), - heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL), - heap_caps_get_free_size(MALLOC_CAP_SPIRAM), - heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM)); } } break; case HTTP_EVENT_ON_FINISH: ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH"); - ESP_LOGD(TAG,"Heap internal:%zu (min:%zu) external:%zu (min:%zu)\n", - heap_caps_get_free_size(MALLOC_CAP_INTERNAL), - heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL), - heap_caps_get_free_size(MALLOC_CAP_SPIRAM), - heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM)); break; case HTTP_EVENT_DISCONNECTED: ESP_LOGD(TAG, "HTTP_EVENT_DISCONNECTED"); @@ -180,11 +180,11 @@ esp_err_t CODE_RAM_LOCATION _http_event_handler(esp_http_client_event_t *evt) return ESP_OK; } -esp_err_t CODE_RAM_LOCATION init_config(esp_http_client_config_t * conf, const char * url){ +esp_err_t init_config(esp_http_client_config_t * conf, const char * url){ memset(conf, 0x00, sizeof(esp_http_client_config_t)); conf->cert_pem = (char *)server_cert_pem_start; conf->event_handler = _http_event_handler; - conf->buffer_size = 4096; + conf->buffer_size = 2048; conf->disable_auto_redirect=true; conf->skip_cert_common_name_check = false; conf->url = strdup(url); @@ -192,7 +192,71 @@ esp_err_t CODE_RAM_LOCATION init_config(esp_http_client_config_t * conf, const c return ESP_OK; } -void CODE_RAM_LOCATION ota_task(void *pvParameter) +esp_err_t _erase_last_boot_app_partition(void) +{ + uint16_t num_passes=0; + uint16_t remain_size=0; + const esp_partition_t *ota_partition=NULL; + const esp_partition_t *ota_data_partition=NULL; + float erase_percent=0; + esp_err_t err=ESP_OK; + + ESP_LOGI(TAG, "Looking for OTA partition."); + esp_partition_iterator_t it = esp_partition_find(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_0 , NULL); + if(it == NULL){ + ESP_LOGE(TAG,"Unable initialize partition iterator!"); + } + else { + ota_partition = (esp_partition_t *) esp_partition_get(it); + if(ota_partition != NULL){ + ESP_LOGI(TAG, "Found OTA partition."); + } + else { + ESP_LOGE(TAG,"OTA partition not found! Unable update application."); + } + esp_partition_iterator_release(it); + } + + it = esp_partition_find(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA , NULL); + if(it == NULL){ + ESP_LOGE(TAG,"Unable initialize partition iterator!"); + } + else { + ota_data_partition = (esp_partition_t *) esp_partition_get(it); + + if(ota_data_partition != NULL){ + ESP_LOGI(TAG, "Found OTA data partition."); + } + else { + ESP_LOGE(TAG,"OTA data partition not found! Unable update application."); + } + esp_partition_iterator_release(it); + } + + if(ota_data_partition==NULL || ota_partition==NULL){ + return ESP_FAIL; + } + ESP_LOGI(TAG,"Erasing OTA partition"); + num_passes=ota_partition->size/OTA_FLASH_ERASE_BLOCK; + remain_size=ota_partition->size-(num_passes*OTA_FLASH_ERASE_BLOCK); + + for(uint16_t i=0;isize); + erase_percent=100.0f*(float)i/num_passes; + triggerStatusJsonRefresh("Erasing OTA partition. %.1f%%",erase_percent); + taskYIELD(); + if(err!=ESP_OK) return err; + } + if(remain_size>0){ + err=esp_partition_erase_range(ota_partition, ota_partition->size-remain_size, remain_size); + if(err!=ESP_OK) return err; + } + triggerStatusJsonRefresh("Erasing OTA partition. 100%%"); + taskYIELD(); + return ESP_OK; +} + +void ota_task(void *pvParameter) { char * passedURL=(char *)pvParameter; @@ -208,11 +272,23 @@ void CODE_RAM_LOCATION ota_task(void *pvParameter) } ota_status.current_url= strdup(passedURL); FREE_RESET(pvParameter); - ESP_LOGD(TAG,"Calling esp_https_ota"); + + ESP_LOGW(TAG,"**************** Expecting WATCHDOG errors below during flash erase. This is OK and not to worry about **************** "); + triggerStatusJsonRefresh("Erasing OTA partition"); + esp_err_t err=_erase_last_boot_app_partition(); + if(err!=ESP_OK){ + ESP_LOGE(TAG,"Unable to erase last APP partition. Error: %s",esp_err_to_name(err)); + FREE_RESET(ota_status.current_url); + FREE_RESET(ota_status.redirected_url); + + vTaskDelete(NULL); + } + + ESP_LOGI(TAG,"Calling esp_https_ota"); init_config(&ota_config,ota_status.bRedirectFound?ota_status.redirected_url:ota_status.current_url); ota_status.bOTAStarted = true; triggerStatusJsonRefresh("Starting OTA..."); - esp_err_t err = esp_https_ota(&ota_config); + err = esp_https_ota(&ota_config); if (err == ESP_OK) { triggerStatusJsonRefresh("Success!"); esp_restart(); @@ -232,7 +308,6 @@ esp_err_t process_recovery_ota(const char * bin_url){ #if RECOVERY_APPLICATION // Initialize NVS. int ret=0; - nvs_handle nvs; esp_err_t err = nvs_flash_init(); if(ota_status.bOTAThreadStarted){ @@ -266,7 +341,7 @@ esp_err_t process_recovery_ota(const char * bin_url){ #endif ESP_LOGI(TAG, "Starting ota on core %u for : %s", OTA_CORE,urlPtr); - ret=xTaskCreatePinnedToCore(&ota_task, "ota_task", 1024*20, (void *)urlPtr, ESP_TASK_MAIN_PRIO+4, NULL, OTA_CORE); + ret=xTaskCreatePinnedToCore(&ota_task, "ota_task", 1024*20, (void *)urlPtr, ESP_TASK_MAIN_PRIO+1, NULL, OTA_CORE); if (ret != pdPASS) { ESP_LOGI(TAG, "create thread %s failed", "ota_task"); return ESP_FAIL; diff --git a/components/squeezelite-ota/squeezelite-ota.h b/components/squeezelite-ota/squeezelite-ota.h index d0927d37..246ef794 100644 --- a/components/squeezelite-ota/squeezelite-ota.h +++ b/components/squeezelite-ota/squeezelite-ota.h @@ -13,8 +13,8 @@ #define CODE_RAM_LOCATION #endif -esp_err_t CODE_RAM_LOCATION start_ota(const char * bin_url, bool bFromAppMain); -const char * CODE_RAM_LOCATION ota_get_status(); -uint8_t CODE_RAM_LOCATION ota_get_pct_complete(); +esp_err_t start_ota(const char * bin_url, bool bFromAppMain); +const char * ota_get_status(); +uint8_t ota_get_pct_complete(); diff --git a/components/wifi-manager/component.mk b/components/wifi-manager/component.mk index 91b23d2b..d951e503 100644 --- a/components/wifi-manager/component.mk +++ b/components/wifi-manager/component.mk @@ -11,3 +11,6 @@ CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_DEBUG \ -I$(COMPONENT_PATH)/../tools COMPONENT_ADD_INCLUDEDIRS := . COMPONENT_ADD_INCLUDEDIRS += $(COMPONENT_PATH)/../tools +COMPONENT_ADD_INCLUDEDIRS += $(COMPONENT_PATH)/../squeezelite-ota +COMPONENT_EXTRA_INCLUDES += $(PROJECT_PATH)/main/ + diff --git a/components/wifi-manager/http_server.c b/components/wifi-manager/http_server.c index fe7e26da..bc6d3101 100644 --- a/components/wifi-manager/http_server.c +++ b/components/wifi-manager/http_server.c @@ -33,16 +33,19 @@ function to process requests, decode URLs, serve files, etc. etc. #include "http_server.h" #include "cmd_system.h" -#include "../squeezelite-ota/squeezelite-ota.h" - +#include +#include "squeezelite-ota.h" +#include "nvs_utilities.h" #define NVS_PARTITION_NAME "nvs" /* @brief tag used for ESP serial console messages */ static const char TAG[] = "http_server"; -static const char json_start[] = "{ \"autoexec\": %u, \"list\": ["; -static const char json_end[] = "]}"; -static const char template[] = "{ \"%s\": \"%s\" }"; -static const char array_separator[]=","; +static const char json_start[] = "{\n"; +static const char json_end[] = "\n}"; +static const char template[] = " \"%s\": \"%s\" "; +static const char template_u[] = " \"%s\": %u "; +static const char template_i[] = " \"%s\": %i "; +static const char array_separator[]=",\n"; static char *s = "\""; static char *r = "\\\""; /* @brief task handle for the http server */ @@ -86,13 +89,13 @@ const static char http_redirect_hdr_end[] = "/\n\n"; -void CODE_RAM_LOCATION http_server_start(){ +void http_server_start(){ if(task_http_server == NULL){ xTaskCreate(&http_server, "http_server", 1024*5, NULL, WIFI_MANAGER_TASK_PRIORITY-1, &task_http_server); } } -void CODE_RAM_LOCATION http_server(void *pvParameters) { +void http_server(void *pvParameters) { struct netconn *conn, *newconn; err_t err; @@ -120,7 +123,7 @@ void CODE_RAM_LOCATION http_server(void *pvParameters) { } -char* CODE_RAM_LOCATION http_server_get_header(char *request, char *header_name, int *len) { +char* http_server_get_header(char *request, char *header_name, int *len) { *len = 0; char *ret = NULL; char *ptr = NULL; @@ -137,7 +140,7 @@ char* CODE_RAM_LOCATION http_server_get_header(char *request, char *header_name, } return NULL; } -char* CODE_RAM_LOCATION http_server_search_header(char *request, char *header_name, int *len, char ** parm_name, char ** next_position, char * bufEnd) { +char* http_server_search_header(char *request, char *header_name, int *len, char ** parm_name, char ** next_position, char * bufEnd) { *len = 0; char *ret = NULL; char *ptr = NULL; @@ -190,7 +193,7 @@ char* CODE_RAM_LOCATION http_server_search_header(char *request, char *header_na ESP_LOGD(TAG, "No more match for : %s", header_name); return NULL; } -void CODE_RAM_LOCATION http_server_send_resource_file(struct netconn *conn,const uint8_t * start, const uint8_t * end, char * content_type,char * encoding){ +void http_server_send_resource_file(struct netconn *conn,const uint8_t * start, const uint8_t * end, char * content_type,char * encoding){ uint16_t len=end - start; size_t buff_length= sizeof(http_hdr_template)+strlen(content_type)+strlen(encoding); char * http_hdr=malloc(buff_length); @@ -209,7 +212,80 @@ void CODE_RAM_LOCATION http_server_send_resource_file(struct netconn *conn,const } } -void CODE_RAM_LOCATION http_server_netconn_serve(struct netconn *conn) { +err_t http_server_nvs_dump(struct netconn *conn, nvs_type_t nvs_type, bool * bFirst){ + nvs_entry_info_t info; + + int locbuflen=1024+strlen(template)+1; + char * config_buffer = malloc(locbuflen); + memset(config_buffer, 0x00,locbuflen); + + if(!config_buffer) + { + ESP_LOGE(TAG,"Unable to allocate buffer for config.json!"); + netconn_write(conn, http_503_hdr, sizeof(http_503_hdr) - 1, NETCONN_NOCOPY); + return ESP_FAIL; + } + + nvs_iterator_t it = nvs_entry_find(NVS_PARTITION_NAME, NULL, nvs_type); + if (it == NULL) { + ESP_LOGW(TAG, "No nvs entry found in %s",NVS_PARTITION_NAME ); + } + while (it != NULL){ + nvs_entry_info(it, &info); + if(strstr(info.namespace_name, current_namespace)){ + if(!*bFirst){ + netconn_write(conn, array_separator, strlen(array_separator), NETCONN_NOCOPY); + *bFirst=true; + } + void * value = get_nvs_value_alloc(nvs_type,info.key); + if(value==NULL) + { + ESP_LOGE(TAG,"nvs read failed."); + free(config_buffer); + return ESP_FAIL; + } + switch (nvs_type) { + case NVS_TYPE_I8: + snprintf(config_buffer, locbuflen-1, template_i, info.key, *(int8_t*)value); + break; + case NVS_TYPE_I16: + snprintf(config_buffer, locbuflen-1, template_i, info.key, *(int16_t*)value); + break; + case NVS_TYPE_I32: + snprintf(config_buffer, locbuflen-1, template_i, info.key, *(int32_t*)value); + break; + case NVS_TYPE_U8: + snprintf(config_buffer, locbuflen-1, template_u, info.key, *(uint8_t*)value); + break; + case NVS_TYPE_U16: + snprintf(config_buffer, locbuflen-1, template_u, info.key, *(uint16_t*)value); + break; + case NVS_TYPE_U32: + snprintf(config_buffer, locbuflen-1, template_u, info.key, *(uint32_t*)value); + break; + case NVS_TYPE_STR: + strreplace((char *)value, s, r); + snprintf(config_buffer, locbuflen-1, template, info.key, (char *)value); + break; + case NVS_TYPE_I64: + case NVS_TYPE_U64: + default: + ESP_LOGE(TAG, "nvs type %u not supported", nvs_type); + break; + } + + ESP_LOGD(TAG,"Namespace %s, json chunk: %s", info.namespace_name, config_buffer); + netconn_write(conn, config_buffer, strlen(config_buffer), NETCONN_NOCOPY); + free(value ); + } + it = nvs_entry_next(it); + } + free(config_buffer); + return ESP_OK; +} + + +void http_server_netconn_serve(struct netconn *conn) { struct netbuf *inbuf; char *buf = NULL; @@ -292,56 +368,12 @@ void CODE_RAM_LOCATION http_server_netconn_serve(struct netconn *conn) { } else if(strstr(line, "GET /config.json ")){ ESP_LOGI(TAG,"Serving config.json"); - - char * autoexec_value=NULL; - uint8_t autoexec_flag=0; - int locbuflen=MAX_COMMAND_LINE_SIZE*4+strlen(template)+1; - char * config_buffer = malloc(locbuflen); - - if(!config_buffer) - { - ESP_LOGE(TAG,"Unable to allocate buffer for config.json!"); - netconn_write(conn, http_503_hdr, sizeof(http_503_hdr) - 1, NETCONN_NOCOPY); - } - else - { - int i=1; - size_t l = 0; - nvs_entry_info_t info; - - netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); - autoexec_flag = wifi_manager_get_flag(); - snprintf(config_buffer,locbuflen-1, json_start, autoexec_flag); - netconn_write(conn, config_buffer, strlen(config_buffer), NETCONN_NOCOPY); - - ESP_LOGI(TAG, "About to get config from flash"); - nvs_iterator_t it = nvs_entry_find(NVS_PARTITION_NAME, NULL, NVS_TYPE_STR); - if (it == NULL) { - ESP_LOGW(TAG, "No nvs entry found in %s",NVS_PARTITION_NAME ); - } - while (it != NULL){ - nvs_entry_info(it, &info); - if(strstr(info.namespace_name, current_namespace)){ - if(i>1) - { - netconn_write(conn, array_separator, strlen(array_separator), NETCONN_NOCOPY); - ESP_LOGD(TAG,"%s", array_separator); - } - - autoexec_value = wifi_manager_alloc_get_config(info.key, &l); - strreplace(autoexec_value, s, r); - ESP_LOGI(TAG,"Namespace %s, key=%s, value=%s", info.namespace_name, info.key,autoexec_value ); - snprintf(config_buffer, locbuflen-1, template, info.key, autoexec_value); - netconn_write(conn, config_buffer, strlen(config_buffer), NETCONN_NOCOPY); - ESP_LOGD(TAG,"Freeing memory for command [%s] value [%s]", info.key, autoexec_value); - free(autoexec_value ); - i++; - } - it = nvs_entry_next(it); - } - free(config_buffer); - netconn_write(conn, json_end, strlen(json_end), NETCONN_NOCOPY); - } + netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); + netconn_write(conn, json_start, strlen(json_start), NETCONN_NOCOPY); + ESP_LOGI(TAG, "About to get config from flash"); + bool bFirst=true; + http_server_nvs_dump(conn,NVS_TYPE_STR , &bFirst); + netconn_write(conn, json_end, strlen(json_end), NETCONN_NOCOPY); ESP_LOGD(TAG,"Done serving config.json"); } else if(strstr(line, "POST /config.json ")){ @@ -351,7 +383,6 @@ void CODE_RAM_LOCATION http_server_netconn_serve(struct netconn *conn) { char * last_parm=save_ptr; char * next_parm=save_ptr; char * last_parm_name=NULL; - uint8_t autoexec_flag=0; bool bErrorFound=false; bool bOTA=false; char * otaURL=NULL; @@ -367,14 +398,11 @@ void CODE_RAM_LOCATION http_server_netconn_serve(struct netconn *conn) { ESP_LOGI(TAG, "OTA parameter found!"); otaURL=strdup(last_parm); bOTA=true; - }else if(strcmp(last_parm_name, "autoexec")==0){ - autoexec_flag = atoi(last_parm); - wifi_manager_save_autoexec_flag(autoexec_flag); } else { if(lenA < MAX_COMMAND_LINE_SIZE ){ ESP_LOGD(TAG, "http_server_netconn_serve: config.json/ Storing parameter"); - wifi_manager_save_autoexec_config(last_parm,last_parm_name,lenA); + wifi_manager_save_config(last_parm,last_parm_name,lenA); } else { @@ -474,7 +502,7 @@ void CODE_RAM_LOCATION http_server_netconn_serve(struct netconn *conn) { netbuf_delete(inbuf); } -void CODE_RAM_LOCATION strreplace(char *src, char *str, char *rep) +void strreplace(char *src, char *str, char *rep) { char *p = strstr(src, str); if (p) diff --git a/components/wifi-manager/wifi_manager.c b/components/wifi-manager/wifi_manager.c index 78182785..5a069d5a 100644 --- a/components/wifi-manager/wifi_manager.c +++ b/components/wifi-manager/wifi_manager.c @@ -130,21 +130,21 @@ const int WIFI_MANAGER_SCAN_BIT = BIT7; const int WIFI_MANAGER_REQUEST_DISCONNECT_BIT = BIT8; -void CODE_RAM_LOCATION wifi_manager_refresh_ota_json(){ +void wifi_manager_refresh_ota_json(){ wifi_manager_send_message(EVENT_REFRESH_OTA, NULL); } -void CODE_RAM_LOCATION wifi_manager_scan_async(){ +void wifi_manager_scan_async(){ wifi_manager_send_message(ORDER_START_WIFI_SCAN, NULL); } -void CODE_RAM_LOCATION wifi_manager_disconnect_async(){ +void wifi_manager_disconnect_async(){ wifi_manager_send_message(ORDER_DISCONNECT_STA, NULL); //xEventGroupSetBits(wifi_manager_event_group, WIFI_MANAGER_REQUEST_WIFI_DISCONNECT_BIT); TODO: delete } -void CODE_RAM_LOCATION wifi_manager_start(){ +void wifi_manager_start(){ /* disable the default wifi logging */ esp_log_level_set("wifi", ESP_LOG_NONE); @@ -175,22 +175,8 @@ void CODE_RAM_LOCATION wifi_manager_start(){ xTaskCreate(&wifi_manager, "wifi_manager", 4096, NULL, WIFI_MANAGER_TASK_PRIORITY, &task_wifi_manager); } -uint8_t CODE_RAM_LOCATION wifi_manager_get_flag(){ - uint8_t value=0; - nvs_handle handle; - esp_err_t esp_err; - ESP_LOGI(TAG, "About to get config from flash"); - esp_err = nvs_open(current_namespace, NVS_READWRITE, &handle); - if (esp_err != ESP_OK) return 0; - - esp_err= nvs_get_u8(handle, "autoexec", &value); - nvs_close(handle); - return value; - -} - -char * CODE_RAM_LOCATION wifi_manager_alloc_get_config(char * name, size_t * l){ +char * wifi_manager_alloc_get_config(char * name, size_t * l){ size_t len=0; char * value=NULL; @@ -223,40 +209,8 @@ char * CODE_RAM_LOCATION wifi_manager_alloc_get_config(char * name, size_t * l){ } -esp_err_t CODE_RAM_LOCATION wifi_manager_save_autoexec_flag(uint8_t flag){ - nvs_handle handle; - esp_err_t esp_err; - ESP_LOGI(TAG, "About to save autoexec flag to flash"); - esp_err=nvs_open(current_namespace, NVS_READWRITE, &handle); - if(esp_err==ESP_ERR_NVS_NOT_INITIALIZED){ - ESP_LOGE(TAG,"Unable to open nvs namespace %s. nvs is not initialized.",wifi_manager_nvs_namespace); - } - else if (esp_err != ESP_OK) { - ESP_LOGE(TAG,"Unable to open nvs namespace %s. Error: %s", wifi_manager_nvs_namespace, esp_err_to_name(esp_err)); - return esp_err; - } - esp_err = nvs_set_u8(handle, "autoexec", flag); - if (esp_err != ESP_OK){ - ESP_LOGE(TAG,"Unable to save autoexec flag value %u",flag); - nvs_close(handle); - return esp_err; - } - - esp_err = nvs_commit(handle); - if (esp_err != ESP_OK){ - ESP_LOGE(TAG,"nvs commit error"); - return esp_err; - } - - nvs_close(handle); - - ESP_LOGD(TAG, "wifi_manager_wrote autoexec flag value %u",flag); - - return ESP_OK; -} - -esp_err_t CODE_RAM_LOCATION wifi_manager_save_autoexec_config(char * value, char * name, int len){ +esp_err_t wifi_manager_save_config(char * value, char * name, int len){ nvs_handle handle; esp_err_t esp_err; ESP_LOGI(TAG, "About to save config to flash. Name: %s, value: %s", name,value); @@ -289,7 +243,7 @@ esp_err_t CODE_RAM_LOCATION wifi_manager_save_autoexec_config(char * value, char } -esp_err_t CODE_RAM_LOCATION wifi_manager_save_sta_config(){ +esp_err_t wifi_manager_save_sta_config(){ nvs_handle handle; esp_err_t esp_err; ESP_LOGI(TAG, "About to save config to flash"); @@ -331,7 +285,7 @@ esp_err_t CODE_RAM_LOCATION wifi_manager_save_sta_config(){ return ESP_OK; } -bool CODE_RAM_LOCATION wifi_manager_fetch_wifi_sta_config(){ +bool wifi_manager_fetch_wifi_sta_config(){ nvs_handle handle; esp_err_t esp_err; @@ -408,12 +362,12 @@ bool CODE_RAM_LOCATION wifi_manager_fetch_wifi_sta_config(){ } -void CODE_RAM_LOCATION wifi_manager_clear_ip_info_json(){ +void wifi_manager_clear_ip_info_json(){ strcpy(ip_info_json, "{}\n"); } -void CODE_RAM_LOCATION wifi_manager_generate_ip_info_json(update_reason_code_t update_reason_code){ +void wifi_manager_generate_ip_info_json(update_reason_code_t update_reason_code){ wifi_config_t *config = wifi_manager_get_wifi_sta_config(); if(update_reason_code == UPDATE_OTA) { update_reason_code = last_update_reason_code; @@ -497,11 +451,11 @@ void CODE_RAM_LOCATION wifi_manager_generate_ip_info_json(update_reason_code_t u } -void CODE_RAM_LOCATION wifi_manager_clear_access_points_json(){ +void wifi_manager_clear_access_points_json(){ strcpy(accessp_json, "[]\n"); } -void CODE_RAM_LOCATION wifi_manager_generate_acess_points_json(){ +void wifi_manager_generate_acess_points_json(){ strcpy(accessp_json, "["); @@ -530,7 +484,7 @@ void CODE_RAM_LOCATION wifi_manager_generate_acess_points_json(){ } -bool CODE_RAM_LOCATION wifi_manager_lock_sta_ip_string(TickType_t xTicksToWait){ +bool wifi_manager_lock_sta_ip_string(TickType_t xTicksToWait){ if(wifi_manager_sta_ip_mutex){ if( xSemaphoreTake( wifi_manager_sta_ip_mutex, xTicksToWait ) == pdTRUE ) { return true; @@ -545,11 +499,11 @@ bool CODE_RAM_LOCATION wifi_manager_lock_sta_ip_string(TickType_t xTicksToWait){ } -void CODE_RAM_LOCATION wifi_manager_unlock_sta_ip_string(){ +void wifi_manager_unlock_sta_ip_string(){ xSemaphoreGive( wifi_manager_sta_ip_mutex ); } -void CODE_RAM_LOCATION wifi_manager_safe_update_sta_ip_string(uint32_t ip){ +void wifi_manager_safe_update_sta_ip_string(uint32_t ip){ if(wifi_manager_lock_sta_ip_string(portMAX_DELAY)){ struct ip4_addr ip4; @@ -565,11 +519,11 @@ void CODE_RAM_LOCATION wifi_manager_safe_update_sta_ip_string(uint32_t ip){ } } -char* CODE_RAM_LOCATION wifi_manager_get_sta_ip_string(){ +char* wifi_manager_get_sta_ip_string(){ return wifi_manager_sta_ip; } -bool CODE_RAM_LOCATION wifi_manager_lock_json_buffer(TickType_t xTicksToWait){ +bool wifi_manager_lock_json_buffer(TickType_t xTicksToWait){ if(wifi_manager_json_mutex){ if( xSemaphoreTake( wifi_manager_json_mutex, xTicksToWait ) == pdTRUE ) { return true; @@ -584,15 +538,15 @@ bool CODE_RAM_LOCATION wifi_manager_lock_json_buffer(TickType_t xTicksToWait){ } -void CODE_RAM_LOCATION wifi_manager_unlock_json_buffer(){ +void wifi_manager_unlock_json_buffer(){ xSemaphoreGive( wifi_manager_json_mutex ); } -char* CODE_RAM_LOCATION wifi_manager_get_ap_list_json(){ +char* wifi_manager_get_ap_list_json(){ return accessp_json; } -esp_err_t CODE_RAM_LOCATION wifi_manager_event_handler(void *ctx, system_event_t *event) +esp_err_t wifi_manager_event_handler(void *ctx, system_event_t *event) { switch(event->event_id) { @@ -666,11 +620,11 @@ esp_err_t CODE_RAM_LOCATION wifi_manager_event_handler(void *ctx, system_event_t return ESP_OK; } -wifi_config_t* CODE_RAM_LOCATION wifi_manager_get_wifi_sta_config(){ +wifi_config_t* wifi_manager_get_wifi_sta_config(){ return wifi_manager_config_sta; } -void CODE_RAM_LOCATION wifi_manager_connect_async(){ +void wifi_manager_connect_async(){ /* in order to avoid a false positive on the front end app we need to quickly flush the ip json * There'se a risk the front end sees an IP or a password error when in fact * it's a remnant from a previous connection @@ -683,11 +637,11 @@ void CODE_RAM_LOCATION wifi_manager_connect_async(){ } -char* CODE_RAM_LOCATION wifi_manager_get_ip_info_json(){ +char* wifi_manager_get_ip_info_json(){ return ip_info_json; } -void CODE_RAM_LOCATION wifi_manager_destroy(){ +void wifi_manager_destroy(){ vTaskDelete(task_wifi_manager); task_wifi_manager = NULL; @@ -716,7 +670,7 @@ void CODE_RAM_LOCATION wifi_manager_destroy(){ wifi_manager_queue = NULL; } -void CODE_RAM_LOCATION wifi_manager_filter_unique( wifi_ap_record_t * aplist, uint16_t * aps) { +void wifi_manager_filter_unique( wifi_ap_record_t * aplist, uint16_t * aps) { int total_unique; wifi_ap_record_t * first_free; total_unique=*aps; @@ -767,27 +721,27 @@ void CODE_RAM_LOCATION wifi_manager_filter_unique( wifi_ap_record_t * aplist, ui *aps = total_unique; } -BaseType_t CODE_RAM_LOCATION wifi_manager_send_message_to_front(message_code_t code, void *param){ +BaseType_t wifi_manager_send_message_to_front(message_code_t code, void *param){ queue_message msg; msg.code = code; msg.param = param; return xQueueSendToFront( wifi_manager_queue, &msg, portMAX_DELAY); } -BaseType_t CODE_RAM_LOCATION wifi_manager_send_message(message_code_t code, void *param){ +BaseType_t wifi_manager_send_message(message_code_t code, void *param){ queue_message msg; msg.code = code; msg.param = param; return xQueueSend( wifi_manager_queue, &msg, portMAX_DELAY); } -void CODE_RAM_LOCATION wifi_manager_set_callback(message_code_t message_code, void (*func_ptr)(void*) ){ +void wifi_manager_set_callback(message_code_t message_code, void (*func_ptr)(void*) ){ if(cb_ptr_arr && message_code < MESSAGE_CODE_COUNT){ cb_ptr_arr[message_code] = func_ptr; } } -void CODE_RAM_LOCATION wifi_manager( void * pvParameters ){ +void wifi_manager( void * pvParameters ){ queue_message msg; BaseType_t xStatus; EventBits_t uxBits; @@ -912,6 +866,12 @@ void CODE_RAM_LOCATION wifi_manager( void * pvParameters ){ if(wifi_manager_lock_json_buffer( portMAX_DELAY )){ wifi_manager_generate_ip_info_json( UPDATE_OTA ); wifi_manager_unlock_json_buffer(); +#if RECOVERY_APPLICATION + ESP_LOGI(TAG,"Refresh from OTA status: %s - flash percent: %d%% ", + ota_get_status(), + ota_get_pct_complete()); +#endif + } break; diff --git a/components/wifi-manager/wifi_manager.h b/components/wifi-manager/wifi_manager.h index 18d6f00f..9b429565 100644 --- a/components/wifi-manager/wifi_manager.h +++ b/components/wifi-manager/wifi_manager.h @@ -268,71 +268,69 @@ typedef struct{ /** * Allocate heap memory for the wifi manager and start the wifi_manager RTOS task */ -void CODE_RAM_LOCATION wifi_manager_start(); +void wifi_manager_start(); /** * Frees up all memory allocated by the wifi_manager and kill the task. */ -void CODE_RAM_LOCATION wifi_manager_destroy(); +void wifi_manager_destroy(); /** * Filters the AP scan list to unique SSIDs */ -void CODE_RAM_LOCATION filter_unique( wifi_ap_record_t * aplist, uint16_t * ap_num); +void filter_unique( wifi_ap_record_t * aplist, uint16_t * ap_num); /** * Main task for the wifi_manager */ -void CODE_RAM_LOCATION wifi_manager( void * pvParameters ); +void wifi_manager( void * pvParameters ); -char* CODE_RAM_LOCATION wifi_manager_get_ap_list_json(); -char* CODE_RAM_LOCATION wifi_manager_get_ip_info_json(); +char* wifi_manager_get_ap_list_json(); +char* wifi_manager_get_ip_info_json(); -uint8_t CODE_RAM_LOCATION wifi_manager_get_flag(); -char * CODE_RAM_LOCATION wifi_manager_alloc_get_config(char * name, size_t * l); +char * wifi_manager_alloc_get_config(char * name, size_t * l); /** * @brief saves the current STA wifi config to flash ram storage. */ -esp_err_t CODE_RAM_LOCATION wifi_manager_save_sta_config(); +esp_err_t wifi_manager_save_sta_config(); /** * @brief saves the current configuration to flash ram storage */ -esp_err_t CODE_RAM_LOCATION wifi_manager_save_autoexec_config(char * value, char * name, int len); -esp_err_t CODE_RAM_LOCATION wifi_manager_save_autoexec_flag(uint8_t flag); +esp_err_t wifi_manager_save_config(char * value, char * name, int len); /** * @brief fetch a previously STA wifi config in the flash ram storage. * @return true if a previously saved config was found, false otherwise. */ -bool CODE_RAM_LOCATION wifi_manager_fetch_wifi_sta_config(); +bool wifi_manager_fetch_wifi_sta_config(); -wifi_config_t* CODE_RAM_LOCATION wifi_manager_get_wifi_sta_config(); +wifi_config_t* wifi_manager_get_wifi_sta_config(); /** * @brief A standard wifi event handler as recommended by Espressif */ -esp_err_t CODE_RAM_LOCATION wifi_manager_event_handler(void *ctx, system_event_t *event); +esp_err_t wifi_manager_event_handler(void *ctx, system_event_t *event); /** * @brief requests a connection to an access point that will be process in the main task thread. */ -void CODE_RAM_LOCATION wifi_manager_connect_async(); +void wifi_manager_connect_async(); /** * @brief requests a wifi scan */ -void CODE_RAM_LOCATION wifi_manager_scan_async(); +void wifi_manager_scan_async(); /** * @brief requests to disconnect and forget about the access point. */ -void CODE_RAM_LOCATION wifi_manager_disconnect_async(); +void wifi_manager_disconnect_async(); /** * @brief Tries to get access to json buffer mutex. @@ -349,65 +347,65 @@ void CODE_RAM_LOCATION wifi_manager_disconnect_async(); * @param xTicksToWait The time in ticks to wait for the semaphore to become available. * @return true in success, false otherwise. */ -bool CODE_RAM_LOCATION wifi_manager_lock_json_buffer(TickType_t xTicksToWait); +bool wifi_manager_lock_json_buffer(TickType_t xTicksToWait); /** * @brief Releases the json buffer mutex. */ -void CODE_RAM_LOCATION wifi_manager_unlock_json_buffer(); +void wifi_manager_unlock_json_buffer(); /** * @brief Generates the connection status json: ssid and IP addresses. * @note This is not thread-safe and should be called only if wifi_manager_lock_json_buffer call is successful. */ -void CODE_RAM_LOCATION wifi_manager_generate_ip_info_json(update_reason_code_t update_reason_code); +void wifi_manager_generate_ip_info_json(update_reason_code_t update_reason_code); /** * @brief Clears the connection status json. * @note This is not thread-safe and should be called only if wifi_manager_lock_json_buffer call is successful. */ -void CODE_RAM_LOCATION wifi_manager_clear_ip_info_json(); +void wifi_manager_clear_ip_info_json(); /** * @brief Generates the list of access points after a wifi scan. * @note This is not thread-safe and should be called only if wifi_manager_lock_json_buffer call is successful. */ -void CODE_RAM_LOCATION wifi_manager_generate_acess_points_json(); +void wifi_manager_generate_acess_points_json(); /** * @brief Clear the list of access points. * @note This is not thread-safe and should be called only if wifi_manager_lock_json_buffer call is successful. */ -void CODE_RAM_LOCATION wifi_manager_clear_access_points_json(); +void wifi_manager_clear_access_points_json(); /** * @brief Start the mDNS service */ -void CODE_RAM_LOCATION wifi_manager_initialise_mdns(); +void wifi_manager_initialise_mdns(); -bool CODE_RAM_LOCATION wifi_manager_lock_sta_ip_string(TickType_t xTicksToWait); -void CODE_RAM_LOCATION wifi_manager_unlock_sta_ip_string(); +bool wifi_manager_lock_sta_ip_string(TickType_t xTicksToWait); +void wifi_manager_unlock_sta_ip_string(); /** * @brief gets the string representation of the STA IP address, e.g.: "192.168.1.69" */ -char* CODE_RAM_LOCATION wifi_manager_get_sta_ip_string(); +char* wifi_manager_get_sta_ip_string(); /** * @brief thread safe char representation of the STA IP update */ -void CODE_RAM_LOCATION wifi_manager_safe_update_sta_ip_string(uint32_t ip); +void wifi_manager_safe_update_sta_ip_string(uint32_t ip); /** * @brief Register a callback to a custom function when specific event message_code happens. */ -void CODE_RAM_LOCATION wifi_manager_set_callback(message_code_t message_code, void (*func_ptr)(void*) ); +void wifi_manager_set_callback(message_code_t message_code, void (*func_ptr)(void*) ); -BaseType_t CODE_RAM_LOCATION wifi_manager_send_message(message_code_t code, void *param); -BaseType_t CODE_RAM_LOCATION wifi_manager_send_message_to_front(message_code_t code, void *param); +BaseType_t wifi_manager_send_message(message_code_t code, void *param); +BaseType_t wifi_manager_send_message_to_front(message_code_t code, void *param); #ifdef __cplusplus } diff --git a/main/console.c b/main/console.c index 174f5ebd..4aa75169 100644 --- a/main/console.c +++ b/main/console.c @@ -53,13 +53,14 @@ void process_autoexec(){ int i=1; char autoexec_name[21]={0}; char * autoexec_value=NULL; - uint8_t * autoexec_flag=NULL; + uint8_t autoexec_flag=0; - autoexec_flag = get_nvs_value_alloc(NVS_TYPE_U8, "autoexec"); + char * str_flag = get_nvs_value_alloc(NVS_TYPE_STR, "autoexec"); - if(autoexec_flag!=NULL ){ - ESP_LOGI(TAG,"autoexec flag value found with value %u", *autoexec_flag); - if(*autoexec_flag == 1) { + if(str_flag !=NULL ){ + autoexec_flag=atoi(str_flag); + ESP_LOGI(TAG,"autoexec flag value found with value %u", autoexec_flag); + if(autoexec_flag == 1) { do { snprintf(autoexec_name,sizeof(autoexec_name)-1,"autoexec%u",i++); ESP_LOGD(TAG,"Getting command name %s", autoexec_name); @@ -76,31 +77,17 @@ void process_autoexec(){ } } while(1); } - free(autoexec_flag); + free(str_flag); } else { ESP_LOGD(TAG,"No matching command found for name autoexec. Adding default entries"); - uint8_t autoexec_dft=0; + char autoexec_dft[]="0"; char autoexec1_dft[256]="squeezelite -o I2S -b 500:2000 -d all=info -M esp32"; - store_nvs_value(NVS_TYPE_U8,"autoexec",&autoexec_dft); + store_nvs_value(NVS_TYPE_STR,"autoexec",autoexec_dft); store_nvs_value(NVS_TYPE_STR,"autoexec1",autoexec1_dft); } } -//static void initialize_filesystem() { -// static wl_handle_t wl_handle; -// const esp_vfs_fat_mount_config_t mount_config = { -// .max_files = 10, -// .format_if_mount_failed = true, -// .allocation_unit_size = 4096 -// }; -// esp_err_t err = esp_vfs_fat_spiflash_mount(MOUNT_PATH, "storage", -// &mount_config, &wl_handle); -// if (err != ESP_OK) { -// ESP_LOGE(TAG, "Failed to mount FATFS (%s)", esp_err_to_name(err)); -// return; -// } -//} static void initialize_nvs() { esp_err_t err = nvs_flash_init();