mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-06 19:47:02 +03:00
Network manager implemented and relatively stable
This commit is contained in:
@@ -2,6 +2,17 @@ cmake_minimum_required(VERSION 3.5)
|
|||||||
set(EXTRA_COMPONENT_DIRS components/platform_console/app_recovery components/platform_console/app_squeezelite )
|
set(EXTRA_COMPONENT_DIRS components/platform_console/app_recovery components/platform_console/app_squeezelite )
|
||||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
add_definitions(-DMODEL_NAME=SqueezeESP32)
|
add_definitions(-DMODEL_NAME=SqueezeESP32)
|
||||||
|
# Uncomment line below to get memory usage trace details
|
||||||
|
#add_definitions(-DENABLE_MEMTRACE=1)
|
||||||
|
#uncomment line below to get network ethernet debug logs
|
||||||
|
#add_definitions(-DNETWORK_ETHERNET_LOG_LEVEL=ESP_LOG_DEBUG)
|
||||||
|
#uncomment line below to get network status debug logs
|
||||||
|
#add_definitions(-DNETWORK_STATUS_LOG_LEVEL=ESP_LOG_DEBUG)
|
||||||
|
#add_definitions(-DNETWORK_HANDLERS_LOG_LEVEL=ESP_LOG_DEBUG)
|
||||||
|
#add_definitions(-DNETWORK_WIFI_LOG_LEVEL=ESP_LOG_DEBUG)
|
||||||
|
#add_definitions(-DNETWORK_MANAGER_LOG_LEVEL=ESP_LOG_DEBUG)
|
||||||
|
|
||||||
|
|
||||||
if(NOT DEFINED DEPTH)
|
if(NOT DEFINED DEPTH)
|
||||||
set(DEPTH "16")
|
set(DEPTH "16")
|
||||||
endif()
|
endif()
|
||||||
@@ -11,10 +22,16 @@ set_property(TARGET recovery.elf PROPERTY RECOVERY_PREFIX app_recovery )
|
|||||||
include(squeezelite.cmake)
|
include(squeezelite.cmake)
|
||||||
set(PROJECT_VER $ENV{PROJECT_VER})
|
set(PROJECT_VER $ENV{PROJECT_VER})
|
||||||
|
|
||||||
#target_compile_definitions(__idf_wifi-manager PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_INFO)
|
|
||||||
target_compile_definitions(__idf_esp_wifi PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_INFO)
|
|
||||||
|
|
||||||
target_compile_definitions(__idf_app_recovery PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_INFO)
|
|
||||||
|
#target_compile_definitions(__idf_services PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
||||||
|
#target_compile_definitions(__idf_esp_eth PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
||||||
|
#target_compile_definitions(__idf_driver PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
||||||
|
#target_compile_definitions(__idf_wifi-manager PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_INFO)
|
||||||
|
#target_compile_definitions(__idf_esp_wifi PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
||||||
|
#target_compile_definitions(__idf_platform_console PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
||||||
|
|
||||||
|
#target_compile_definitions(__idf_app_recovery PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_INFO)
|
||||||
# target_compile_definitions(__idf_esp_eth PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_INFO)
|
# target_compile_definitions(__idf_esp_eth PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_INFO)
|
||||||
# target_compile_definitions(__idf_esp_event PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_INFO)
|
# target_compile_definitions(__idf_esp_event PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_INFO)
|
||||||
# target_compile_definitions(__idf_esp_netif PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
# target_compile_definitions(__idf_esp_netif PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
||||||
@@ -84,13 +101,12 @@ target_compile_definitions(__idf_app_recovery PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_
|
|||||||
# target_compile_definitions(__idf_openssl PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
# target_compile_definitions(__idf_openssl PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
||||||
# target_compile_definitions(__idf_perfmon PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
# target_compile_definitions(__idf_perfmon PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
||||||
# target_compile_definitions(__idf_platform_config PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
# target_compile_definitions(__idf_platform_config PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
||||||
# target_compile_definitions(__idf_platform_console PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
|
||||||
# target_compile_definitions(__idf_protobuf-c PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
# target_compile_definitions(__idf_protobuf-c PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
||||||
# target_compile_definitions(__idf_protocomm PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
# target_compile_definitions(__idf_protocomm PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
||||||
# target_compile_definitions(__idf_pthread PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
# target_compile_definitions(__idf_pthread PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
||||||
# target_compile_definitions(__idf_raop PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
# target_compile_definitions(__idf_raop PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
||||||
# target_compile_definitions(__idf_sdmmc PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
# target_compile_definitions(__idf_sdmmc PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
||||||
# target_compile_definitions(__idf_services PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
|
||||||
# target_compile_definitions(__idf_soc PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
# target_compile_definitions(__idf_soc PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
||||||
# target_compile_definitions(__idf_spiffs PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
# target_compile_definitions(__idf_spiffs PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
||||||
# target_compile_definitions(__idf_spi_flash PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
# target_compile_definitions(__idf_spi_flash PRIVATE -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG)
|
||||||
|
|||||||
Submodule components/cpp-stateless deleted from 9e7138f8fe
@@ -17,6 +17,7 @@
|
|||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/queue.h"
|
#include "freertos/queue.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
|
#include "globdefs.h"
|
||||||
|
|
||||||
static const char * TAG = "btappcore";
|
static const char * TAG = "btappcore";
|
||||||
|
|
||||||
@@ -41,8 +42,7 @@ bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, i
|
|||||||
if (param_len == 0) {
|
if (param_len == 0) {
|
||||||
return bt_app_send_msg(&msg);
|
return bt_app_send_msg(&msg);
|
||||||
} else if (p_params && param_len > 0) {
|
} else if (p_params && param_len > 0) {
|
||||||
if ((msg.param = malloc(param_len)) != NULL) {
|
if ((msg.param = clone_obj_psram(p_params, param_len)) != NULL) {
|
||||||
memcpy(msg.param, p_params, param_len);
|
|
||||||
/* check if caller has provided a copy callback to do the deep copy */
|
/* check if caller has provided a copy callback to do the deep copy */
|
||||||
if (p_copy_cback) {
|
if (p_copy_cback) {
|
||||||
p_copy_cback(&msg, msg.param, p_params);
|
p_copy_cback(&msg, msg.param, p_params);
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "messaging.h"
|
#include "messaging.h"
|
||||||
#include "cJSON.h"
|
#include "cJSON.h"
|
||||||
|
#include "globdefs.h"
|
||||||
|
|
||||||
static const char * TAG = "bt_app_source";
|
static const char * TAG = "bt_app_source";
|
||||||
static const char * BT_RC_CT_TAG="RCCT";
|
static const char * BT_RC_CT_TAG="RCCT";
|
||||||
@@ -226,8 +227,8 @@ void hal_bluetooth_init(const char * options)
|
|||||||
squeezelite_args.end = arg_end(2);
|
squeezelite_args.end = arg_end(2);
|
||||||
|
|
||||||
ESP_LOGD(TAG,"Copying parameters");
|
ESP_LOGD(TAG,"Copying parameters");
|
||||||
char * opts = strdup(options);
|
char * opts = strdup_psram(options);
|
||||||
char **argv = malloc(sizeof(char**)*15);
|
char **argv = malloc_init_external(sizeof(char**)*15);
|
||||||
|
|
||||||
size_t argv_size=15;
|
size_t argv_size=15;
|
||||||
|
|
||||||
@@ -254,7 +255,7 @@ void hal_bluetooth_init(const char * options)
|
|||||||
ESP_LOGW(TAG,"Unable to retrieve the a2dp sink name from nvs.");
|
ESP_LOGW(TAG,"Unable to retrieve the a2dp sink name from nvs.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
squeezelite_conf.sink_name=strdup(squeezelite_args.sink_name->sval[0]);
|
squeezelite_conf.sink_name=strdup_psram(squeezelite_args.sink_name->sval[0]);
|
||||||
// sync with NVS
|
// sync with NVS
|
||||||
esp_err_t err=ESP_OK;
|
esp_err_t err=ESP_OK;
|
||||||
if((err= config_set_value(NVS_TYPE_STR, "a2dp_sink_name", squeezelite_args.sink_name->sval[0]))!=ESP_OK){
|
if((err= config_set_value(NVS_TYPE_STR, "a2dp_sink_name", squeezelite_args.sink_name->sval[0]))!=ESP_OK){
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
idf_component_register( SRC_DIRS .
|
idf_component_register( SRC_DIRS .
|
||||||
INCLUDE_DIRS .
|
INCLUDE_DIRS .
|
||||||
PRIV_REQUIRES tools newlib console esp_common freertos
|
PRIV_REQUIRES tools newlib console esp_common freertos services
|
||||||
REQUIRES nvs_flash json
|
REQUIRES nvs_flash json
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
//#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
|
|
||||||
#include "nvs_utilities.h"
|
#include "nvs_utilities.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -15,6 +14,7 @@
|
|||||||
#include "nvs_flash.h"
|
#include "nvs_flash.h"
|
||||||
#include "nvs_utilities.h"
|
#include "nvs_utilities.h"
|
||||||
#include "platform_config.h"
|
#include "platform_config.h"
|
||||||
|
#include "globdefs.h"
|
||||||
|
|
||||||
const char current_namespace[] = "config";
|
const char current_namespace[] = "config";
|
||||||
const char settings_partition[] = "settings";
|
const char settings_partition[] = "settings";
|
||||||
@@ -69,6 +69,11 @@ const char *type_to_str(nvs_type_t type)
|
|||||||
|
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
|
void erase_settings_partition(){
|
||||||
|
ESP_LOGW(TAG, "Erasing nvs on partition %s",settings_partition);
|
||||||
|
ESP_ERROR_CHECK(nvs_flash_erase_partition(settings_partition));
|
||||||
|
nvs_flash_init_partition(settings_partition);
|
||||||
|
}
|
||||||
void initialize_nvs() {
|
void initialize_nvs() {
|
||||||
ESP_LOGI(TAG, "Initializing flash nvs ");
|
ESP_LOGI(TAG, "Initializing flash nvs ");
|
||||||
esp_err_t err = nvs_flash_init();
|
esp_err_t err = nvs_flash_init();
|
||||||
@@ -95,62 +100,89 @@ void initialize_nvs() {
|
|||||||
ESP_LOGD(TAG, "nvs init completed");
|
ESP_LOGD(TAG, "nvs init completed");
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t nvs_load_config(){
|
esp_err_t nvs_load_config() {
|
||||||
nvs_entry_info_t info;
|
nvs_entry_info_t info;
|
||||||
esp_err_t err = ESP_OK;
|
esp_err_t err = ESP_OK;
|
||||||
size_t malloc_int = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
size_t malloc_int = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||||
size_t malloc_spiram = heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
|
size_t malloc_spiram = heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
|
||||||
|
|
||||||
nvs_iterator_t it = nvs_entry_find(settings_partition, NULL, NVS_TYPE_ANY);
|
nvs_iterator_t it = nvs_entry_find(settings_partition, NULL, NVS_TYPE_ANY);
|
||||||
if(it == NULL) {
|
if (it == NULL) {
|
||||||
ESP_LOGW(TAG, "empty nvs partition %s, namespace %s",settings_partition,current_namespace );
|
ESP_LOGW(TAG, "empty nvs partition %s, namespace %s", settings_partition, current_namespace);
|
||||||
}
|
}
|
||||||
while (it != NULL) {
|
while (it != NULL) {
|
||||||
nvs_entry_info(it, &info);
|
nvs_entry_info(it, &info);
|
||||||
|
|
||||||
if(strstr(info.namespace_name, current_namespace)) {
|
if (strstr(info.namespace_name, current_namespace)) {
|
||||||
void * value = get_nvs_value_alloc(info.type,info.key);
|
if (strlen(info.key) == 0) {
|
||||||
if(value==NULL)
|
ESP_LOGW(TAG, "empty key name in namespace %s. Removing it.", current_namespace);
|
||||||
{
|
nvs_handle_t nvs_handle;
|
||||||
ESP_LOGE(TAG, "nvs read failed.");
|
err = nvs_open(settings_partition, NVS_READWRITE, &nvs_handle);
|
||||||
return ESP_FAIL;
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "nvs_open failed. %s", esp_err_to_name(err));
|
||||||
|
} else {
|
||||||
|
if ((err = nvs_erase_key(nvs_handle, info.key)) != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "nvs_erase_key failed. %s", esp_err_to_name(err));
|
||||||
|
} else {
|
||||||
|
nvs_commit(nvs_handle);
|
||||||
|
}
|
||||||
|
nvs_close(nvs_handle);
|
||||||
|
if (err == ESP_OK) {
|
||||||
|
ESP_LOGW(TAG, "nvs_erase_key completed on empty key. Restarting system to apply changes.");
|
||||||
|
esp_restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGW(TAG, "nvs_erase_key failed on empty key. Configuration partition should be erased. %s", esp_err_to_name(err));
|
||||||
|
err = ESP_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
void* value = get_nvs_value_alloc(info.type, info.key);
|
||||||
|
if (value == NULL) {
|
||||||
|
ESP_LOGE(TAG, "nvs read failed.");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
config_set_value(info.type, info.key, value);
|
||||||
|
free(value);
|
||||||
}
|
}
|
||||||
config_set_value(info.type, info.key, value);
|
}
|
||||||
free(value );
|
it = nvs_entry_next(it);
|
||||||
}
|
}
|
||||||
it = nvs_entry_next(it);
|
char* json_string = config_alloc_get_json(false);
|
||||||
}
|
if (json_string != NULL) {
|
||||||
char * json_string= config_alloc_get_json(false);
|
ESP_LOGD(TAG, "config json : %s\n", json_string);
|
||||||
if(json_string!=NULL) {
|
free(json_string);
|
||||||
ESP_LOGD(TAG, "config json : %s\n", json_string);
|
}
|
||||||
free(json_string);
|
|
||||||
}
|
|
||||||
ESP_LOGD(TAG,"Config memory usage. Heap internal:%zu (min:%zu) (used:%zu) external:%zu (min:%zu) (used:%zd)",
|
|
||||||
heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
|
|
||||||
heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL),
|
|
||||||
malloc_int-heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
|
|
||||||
heap_caps_get_free_size(MALLOC_CAP_SPIRAM),
|
|
||||||
heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM),
|
|
||||||
malloc_spiram -heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
ESP_LOGW(TAG, "Configuration memory usage. Heap internal:%zu (min:%zu) (used:%zu) external:%zu (min:%zu) (used:%zd)",
|
||||||
|
heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
|
||||||
|
heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL),
|
||||||
|
malloc_int - heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
|
||||||
|
heap_caps_get_free_size(MALLOC_CAP_SPIRAM),
|
||||||
|
heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM),
|
||||||
|
malloc_spiram - heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t store_nvs_value(nvs_type_t type, const char *key, void * data) {
|
esp_err_t store_nvs_value(nvs_type_t type, const char *key, void * data) {
|
||||||
if (type == NVS_TYPE_BLOB)
|
if (type == NVS_TYPE_BLOB)
|
||||||
return ESP_ERR_NVS_TYPE_MISMATCH;
|
return ESP_ERR_NVS_TYPE_MISMATCH;
|
||||||
return store_nvs_value_len(type, key, data,0);
|
return store_nvs_value_len(type, key, data,0);
|
||||||
}
|
}
|
||||||
esp_err_t store_nvs_value_len(nvs_type_t type, const char *key, void * data,
|
esp_err_t store_nvs_value_len_for_partition(const char * partition,const char * namespace,nvs_type_t type, const char *key, const void * data,size_t data_len) {
|
||||||
size_t data_len) {
|
|
||||||
esp_err_t err;
|
esp_err_t err;
|
||||||
nvs_handle nvs;
|
nvs_handle nvs;
|
||||||
|
if(!key || key[0]=='\0'){
|
||||||
|
ESP_LOGE(TAG, "Cannot store value to nvs: key is empty");
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
if (type == NVS_TYPE_ANY) {
|
if (type == NVS_TYPE_ANY) {
|
||||||
return ESP_ERR_NVS_TYPE_MISMATCH;
|
return ESP_ERR_NVS_TYPE_MISMATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = nvs_open_from_partition(settings_partition, current_namespace, NVS_READWRITE, &nvs);
|
err = nvs_open_from_partition(partition, namespace, NVS_READWRITE, &nvs);
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -185,53 +217,65 @@ esp_err_t store_nvs_value_len(nvs_type_t type, const char *key, void * data,
|
|||||||
nvs_close(nvs);
|
nvs_close(nvs);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
void * get_nvs_value_alloc(nvs_type_t type, const char *key) {
|
esp_err_t store_nvs_value_len(nvs_type_t type, const char *key, void * data,
|
||||||
|
size_t data_len) {
|
||||||
|
return store_nvs_value_len_for_partition(settings_partition,current_namespace,type,key,data,data_len);
|
||||||
|
}
|
||||||
|
void * get_nvs_value_alloc_for_partition(const char * partition,const char * namespace,nvs_type_t type, const char *key, size_t * size){
|
||||||
nvs_handle nvs;
|
nvs_handle nvs;
|
||||||
esp_err_t err;
|
esp_err_t err;
|
||||||
void * value=NULL;
|
void * value=NULL;
|
||||||
|
if(size){
|
||||||
err = nvs_open_from_partition(settings_partition, current_namespace, NVS_READONLY, &nvs);
|
*size=0;
|
||||||
|
}
|
||||||
|
err = nvs_open_from_partition(partition, namespace, NVS_READONLY, &nvs);
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "Could not open the nvs storage.");
|
ESP_LOGE(TAG, "Could not open the nvs storage.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == NVS_TYPE_I8) {
|
if (type == NVS_TYPE_I8) {
|
||||||
value=malloc(sizeof(int8_t));
|
value=malloc_init_external(sizeof(int8_t));
|
||||||
err = nvs_get_i8(nvs, key, (int8_t *) value);
|
err = nvs_get_i8(nvs, key, (int8_t *) value);
|
||||||
} else if (type == NVS_TYPE_U8) {
|
} else if (type == NVS_TYPE_U8) {
|
||||||
value=malloc(sizeof(uint8_t));
|
value=malloc_init_external(sizeof(uint8_t));
|
||||||
err = nvs_get_u8(nvs, key, (uint8_t *) value);
|
err = nvs_get_u8(nvs, key, (uint8_t *) value);
|
||||||
} else if (type == NVS_TYPE_I16) {
|
} else if (type == NVS_TYPE_I16) {
|
||||||
value=malloc(sizeof(int16_t));
|
value=malloc_init_external(sizeof(int16_t));
|
||||||
err = nvs_get_i16(nvs, key, (int16_t *) value);
|
err = nvs_get_i16(nvs, key, (int16_t *) value);
|
||||||
} else if (type == NVS_TYPE_U16) {
|
} else if (type == NVS_TYPE_U16) {
|
||||||
value=malloc(sizeof(uint16_t));
|
value=malloc_init_external(sizeof(uint16_t));
|
||||||
err = nvs_get_u16(nvs, key, (uint16_t *) value);
|
err = nvs_get_u16(nvs, key, (uint16_t *) value);
|
||||||
} else if (type == NVS_TYPE_I32) {
|
} else if (type == NVS_TYPE_I32) {
|
||||||
value=malloc(sizeof(int32_t));
|
value=malloc_init_external(sizeof(int32_t));
|
||||||
err = nvs_get_i32(nvs, key, (int32_t *) value);
|
err = nvs_get_i32(nvs, key, (int32_t *) value);
|
||||||
} else if (type == NVS_TYPE_U32) {
|
} else if (type == NVS_TYPE_U32) {
|
||||||
value=malloc(sizeof(uint32_t));
|
value=malloc_init_external(sizeof(uint32_t));
|
||||||
err = nvs_get_u32(nvs, key, (uint32_t *) value);
|
err = nvs_get_u32(nvs, key, (uint32_t *) value);
|
||||||
} else if (type == NVS_TYPE_I64) {
|
} else if (type == NVS_TYPE_I64) {
|
||||||
value=malloc(sizeof(int64_t));
|
value=malloc_init_external(sizeof(int64_t));
|
||||||
err = nvs_get_i64(nvs, key, (int64_t *) value);
|
err = nvs_get_i64(nvs, key, (int64_t *) value);
|
||||||
} else if (type == NVS_TYPE_U64) {
|
} else if (type == NVS_TYPE_U64) {
|
||||||
value=malloc(sizeof(uint64_t));
|
value=malloc_init_external(sizeof(uint64_t));
|
||||||
err = nvs_get_u64(nvs, key, (uint64_t *) value);
|
err = nvs_get_u64(nvs, key, (uint64_t *) value);
|
||||||
} else if (type == NVS_TYPE_STR) {
|
} else if (type == NVS_TYPE_STR) {
|
||||||
size_t len=0;
|
size_t len=0;
|
||||||
err = nvs_get_str(nvs, key, NULL, &len);
|
err = nvs_get_str(nvs, key, NULL, &len);
|
||||||
if (err == ESP_OK) {
|
if (err == ESP_OK) {
|
||||||
value=malloc(len);
|
value=malloc_init_external(len+1);
|
||||||
err = nvs_get_str(nvs, key, value, &len);
|
err = nvs_get_str(nvs, key, value, &len);
|
||||||
}
|
if(size){
|
||||||
|
*size=len;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (type == NVS_TYPE_BLOB) {
|
} else if (type == NVS_TYPE_BLOB) {
|
||||||
size_t len;
|
size_t len;
|
||||||
err = nvs_get_blob(nvs, key, NULL, &len);
|
err = nvs_get_blob(nvs, key, NULL, &len);
|
||||||
if (err == ESP_OK) {
|
if (err == ESP_OK) {
|
||||||
value=malloc(len+1);
|
value=malloc_init_external(len+1);
|
||||||
|
if(size){
|
||||||
|
*size=len;
|
||||||
|
}
|
||||||
err = nvs_get_blob(nvs, key, value, &len);
|
err = nvs_get_blob(nvs, key, value, &len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -244,6 +288,9 @@ void * get_nvs_value_alloc(nvs_type_t type, const char *key) {
|
|||||||
nvs_close(nvs);
|
nvs_close(nvs);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
void * get_nvs_value_alloc(nvs_type_t type, const char *key) {
|
||||||
|
return get_nvs_value_alloc_for_partition(settings_partition, current_namespace,type,key,NULL);
|
||||||
|
}
|
||||||
esp_err_t get_nvs_value(nvs_type_t type, const char *key, void*value, const uint8_t buf_size) {
|
esp_err_t get_nvs_value(nvs_type_t type, const char *key, void*value, const uint8_t buf_size) {
|
||||||
nvs_handle nvs;
|
nvs_handle nvs;
|
||||||
esp_err_t err;
|
esp_err_t err;
|
||||||
@@ -296,11 +343,10 @@ esp_err_t get_nvs_value(nvs_type_t type, const char *key, void*value, const uint
|
|||||||
nvs_close(nvs);
|
nvs_close(nvs);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
esp_err_t erase_nvs(const char *key)
|
esp_err_t erase_nvs_for_partition(const char * partition, const char * namespace,const char *key)
|
||||||
{
|
{
|
||||||
nvs_handle nvs;
|
nvs_handle nvs;
|
||||||
|
esp_err_t err = nvs_open_from_partition(partition,namespace, NVS_READWRITE, &nvs);
|
||||||
esp_err_t err = nvs_open(current_namespace, NVS_READWRITE, &nvs);
|
|
||||||
if (err == ESP_OK) {
|
if (err == ESP_OK) {
|
||||||
err = nvs_erase_key(nvs, key);
|
err = nvs_erase_key(nvs, key);
|
||||||
if (err == ESP_OK) {
|
if (err == ESP_OK) {
|
||||||
@@ -311,7 +357,35 @@ esp_err_t erase_nvs(const char *key)
|
|||||||
}
|
}
|
||||||
nvs_close(nvs);
|
nvs_close(nvs);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
ESP_LOGE(TAG,"Could not erase key %s from partition %s namespace %s : %s", key,partition,namespace, esp_err_to_name(err));
|
||||||
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
esp_err_t erase_nvs(const char *key)
|
||||||
|
{
|
||||||
|
return erase_nvs_for_partition(NVS_DEFAULT_PART_NAME, current_namespace,key);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t erase_nvs_partition(const char * partition, const char * namespace){
|
||||||
|
nvs_handle nvs;
|
||||||
|
const char * step = "Opening";
|
||||||
|
ESP_LOGD(TAG,"%s partition %s, namespace %s ",step,partition,namespace);
|
||||||
|
esp_err_t err = nvs_open_from_partition(partition,namespace, NVS_READWRITE, &nvs);
|
||||||
|
if (err == ESP_OK) {
|
||||||
|
step = "Erasing";
|
||||||
|
ESP_LOGD(TAG,"%s namespace %s ",step,partition);
|
||||||
|
err = nvs_erase_all(nvs);
|
||||||
|
if (err == ESP_OK) {
|
||||||
|
step = "Committing";
|
||||||
|
ESP_LOGD(TAG,"%s",step);
|
||||||
|
err = nvs_commit(nvs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(err !=ESP_OK){
|
||||||
|
ESP_LOGE(TAG,"%s partition %s, name space %s : %s",step,partition,namespace,esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
ESP_LOGD(TAG,"Closing %s ",namespace);
|
||||||
|
nvs_close(nvs);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
@@ -13,10 +13,15 @@ esp_err_t store_nvs_value_len(nvs_type_t type, const char *key, void * data, siz
|
|||||||
esp_err_t store_nvs_value(nvs_type_t type, const char *key, void * data);
|
esp_err_t store_nvs_value(nvs_type_t type, const char *key, void * data);
|
||||||
esp_err_t get_nvs_value(nvs_type_t type, const char *key, void*value, const uint8_t buf_size);
|
esp_err_t get_nvs_value(nvs_type_t type, const char *key, void*value, const uint8_t buf_size);
|
||||||
void * get_nvs_value_alloc(nvs_type_t type, const char *key);
|
void * get_nvs_value_alloc(nvs_type_t type, const char *key);
|
||||||
|
void * get_nvs_value_alloc_for_partition(const char * partition,const char * namespace,nvs_type_t type, const char *key, size_t * size);
|
||||||
|
esp_err_t erase_nvs_for_partition(const char * partition, const char * namespace,const char *key);
|
||||||
|
esp_err_t store_nvs_value_len_for_partition(const char * partition,const char * namespace,nvs_type_t type, const char *key, const void * data,size_t data_len);
|
||||||
esp_err_t erase_nvs(const char *key);
|
esp_err_t erase_nvs(const char *key);
|
||||||
void print_blob(const char *blob, size_t len);
|
void print_blob(const char *blob, size_t len);
|
||||||
const char *type_to_str(nvs_type_t type);
|
const char *type_to_str(nvs_type_t type);
|
||||||
nvs_type_t str_to_type(const char *type);
|
nvs_type_t str_to_type(const char *type);
|
||||||
|
esp_err_t erase_nvs_partition(const char * partition, const char * namespace);
|
||||||
|
void erase_settings_partition();
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
//#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
|
|
||||||
#include "platform_config.h"
|
#include "platform_config.h"
|
||||||
#include "nvs_utilities.h"
|
#include "nvs_utilities.h"
|
||||||
#include "platform_esp32.h"
|
#include "platform_esp32.h"
|
||||||
@@ -39,18 +38,18 @@
|
|||||||
#include "cJSON.h"
|
#include "cJSON.h"
|
||||||
#include "freertos/timers.h"
|
#include "freertos/timers.h"
|
||||||
#include "freertos/event_groups.h"
|
#include "freertos/event_groups.h"
|
||||||
|
#include "globdefs.h"
|
||||||
|
|
||||||
#define CONFIG_COMMIT_DELAY 1000
|
#define CONFIG_COMMIT_DELAY 1000
|
||||||
#define LOCK_MAX_WAIT 20*CONFIG_COMMIT_DELAY
|
#define LOCK_MAX_WAIT 20*CONFIG_COMMIT_DELAY
|
||||||
static const char * TAG = "config";
|
static const char * TAG = "config";
|
||||||
static cJSON * nvs_json=NULL;
|
EXT_RAM_ATTR static cJSON * nvs_json=NULL;
|
||||||
static TimerHandle_t timer;
|
EXT_RAM_ATTR static TimerHandle_t timer;
|
||||||
static SemaphoreHandle_t config_mutex = NULL;
|
EXT_RAM_ATTR static SemaphoreHandle_t config_mutex = NULL;
|
||||||
static EventGroupHandle_t config_group;
|
EXT_RAM_ATTR static EventGroupHandle_t config_group;
|
||||||
/* @brief indicate that the ESP32 is currently connected. */
|
/* @brief indicate that the ESP32 is currently connected. */
|
||||||
static const int CONFIG_NO_COMMIT_PENDING = BIT0;
|
EXT_RAM_ATTR static const int CONFIG_NO_COMMIT_PENDING = BIT0;
|
||||||
static const int CONFIG_LOAD_BIT = BIT1;
|
EXT_RAM_ATTR static const int CONFIG_LOAD_BIT = BIT1;
|
||||||
|
|
||||||
bool config_lock(TickType_t xTicksToWait);
|
bool config_lock(TickType_t xTicksToWait);
|
||||||
void config_unlock();
|
void config_unlock();
|
||||||
@@ -62,7 +61,7 @@ cJSON * config_set_value_safe(nvs_type_t nvs_type, const char *key,const void *
|
|||||||
static void vCallbackFunction( TimerHandle_t xTimer );
|
static void vCallbackFunction( TimerHandle_t xTimer );
|
||||||
void config_set_entry_changed_flag(cJSON * entry, cJSON_bool flag);
|
void config_set_entry_changed_flag(cJSON * entry, cJSON_bool flag);
|
||||||
#define IMPLEMENT_SET_DEFAULT(t,nt) void config_set_default_## t (const char *key, t value){\
|
#define IMPLEMENT_SET_DEFAULT(t,nt) void config_set_default_## t (const char *key, t value){\
|
||||||
void * pval = malloc(sizeof(value));\
|
void * pval = malloc_init_external(sizeof(value));\
|
||||||
*((t *) pval) = value;\
|
*((t *) pval) = value;\
|
||||||
config_set_default(nt, key,pval,0);\
|
config_set_default(nt, key,pval,0);\
|
||||||
free(pval); }
|
free(pval); }
|
||||||
@@ -72,7 +71,7 @@ void config_set_entry_changed_flag(cJSON * entry, cJSON_bool flag);
|
|||||||
return ESP_FAIL;}
|
return ESP_FAIL;}
|
||||||
static void * malloc_fn(size_t sz){
|
static void * malloc_fn(size_t sz){
|
||||||
|
|
||||||
void * ptr = is_recovery_running?malloc(sz):heap_caps_malloc(sz, MALLOC_CAP_SPIRAM);
|
void * ptr = is_recovery_running?malloc(sz):heap_caps_malloc(sz, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||||
if(ptr==NULL){
|
if(ptr==NULL){
|
||||||
ESP_LOGE(TAG,"malloc_fn: unable to allocate memory!");
|
ESP_LOGE(TAG,"malloc_fn: unable to allocate memory!");
|
||||||
}
|
}
|
||||||
@@ -85,20 +84,28 @@ void init_cJSON(){
|
|||||||
}
|
}
|
||||||
void config_init(){
|
void config_init(){
|
||||||
ESP_LOGD(TAG, "Creating mutex for Config");
|
ESP_LOGD(TAG, "Creating mutex for Config");
|
||||||
|
MEMTRACE_PRINT_DELTA();
|
||||||
config_mutex = xSemaphoreCreateMutex();
|
config_mutex = xSemaphoreCreateMutex();
|
||||||
|
MEMTRACE_PRINT_DELTA();
|
||||||
ESP_LOGD(TAG, "Creating event group");
|
ESP_LOGD(TAG, "Creating event group");
|
||||||
|
MEMTRACE_PRINT_DELTA();
|
||||||
config_group = xEventGroupCreate();
|
config_group = xEventGroupCreate();
|
||||||
|
MEMTRACE_PRINT_DELTA();
|
||||||
ESP_LOGD(TAG, "Loading config from nvs");
|
ESP_LOGD(TAG, "Loading config from nvs");
|
||||||
|
|
||||||
init_cJSON();
|
init_cJSON();
|
||||||
|
MEMTRACE_PRINT_DELTA();
|
||||||
if(nvs_json !=NULL){
|
if(nvs_json !=NULL){
|
||||||
cJSON_Delete(nvs_json);
|
cJSON_Delete(nvs_json);
|
||||||
}
|
}
|
||||||
nvs_json = cJSON_CreateObject();
|
nvs_json = cJSON_CreateObject();
|
||||||
|
|
||||||
config_set_group_bit(CONFIG_LOAD_BIT,true);
|
config_set_group_bit(CONFIG_LOAD_BIT,true);
|
||||||
|
MEMTRACE_PRINT_DELTA();
|
||||||
nvs_load_config();
|
nvs_load_config();
|
||||||
|
MEMTRACE_PRINT_DELTA();
|
||||||
config_set_group_bit(CONFIG_LOAD_BIT,false);
|
config_set_group_bit(CONFIG_LOAD_BIT,false);
|
||||||
|
MEMTRACE_PRINT_DELTA();
|
||||||
config_start_timer();
|
config_start_timer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,28 +325,28 @@ void * config_safe_alloc_get_entry_value(nvs_type_t nvs_type, cJSON * entry){
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (nvs_type == NVS_TYPE_I8) {
|
if (nvs_type == NVS_TYPE_I8) {
|
||||||
value=malloc(sizeof(int8_t));
|
value=malloc_init_external(sizeof(int8_t));
|
||||||
*(int8_t *)value = (int8_t)entry_value->valuedouble;
|
*(int8_t *)value = (int8_t)entry_value->valuedouble;
|
||||||
} else if (nvs_type == NVS_TYPE_U8) {
|
} else if (nvs_type == NVS_TYPE_U8) {
|
||||||
value=malloc(sizeof(uint8_t));
|
value=malloc_init_external(sizeof(uint8_t));
|
||||||
*(uint8_t *)value = (uint8_t)entry_value->valuedouble;
|
*(uint8_t *)value = (uint8_t)entry_value->valuedouble;
|
||||||
} else if (nvs_type == NVS_TYPE_I16) {
|
} else if (nvs_type == NVS_TYPE_I16) {
|
||||||
value=malloc(sizeof(int16_t));
|
value=malloc_init_external(sizeof(int16_t));
|
||||||
*(int16_t *)value = (int16_t)entry_value->valuedouble;
|
*(int16_t *)value = (int16_t)entry_value->valuedouble;
|
||||||
} else if (nvs_type == NVS_TYPE_U16) {
|
} else if (nvs_type == NVS_TYPE_U16) {
|
||||||
value=malloc(sizeof(uint16_t));
|
value=malloc_init_external(sizeof(uint16_t));
|
||||||
*(uint16_t *)value = (uint16_t)entry_value->valuedouble;
|
*(uint16_t *)value = (uint16_t)entry_value->valuedouble;
|
||||||
} else if (nvs_type == NVS_TYPE_I32) {
|
} else if (nvs_type == NVS_TYPE_I32) {
|
||||||
value=malloc(sizeof(int32_t));
|
value=malloc_init_external(sizeof(int32_t));
|
||||||
*(int32_t *)value = (int32_t)entry_value->valuedouble;
|
*(int32_t *)value = (int32_t)entry_value->valuedouble;
|
||||||
} else if (nvs_type == NVS_TYPE_U32) {
|
} else if (nvs_type == NVS_TYPE_U32) {
|
||||||
value=malloc(sizeof(uint32_t));
|
value=malloc_init_external(sizeof(uint32_t));
|
||||||
*(uint32_t *)value = (uint32_t)entry_value->valuedouble;
|
*(uint32_t *)value = (uint32_t)entry_value->valuedouble;
|
||||||
} else if (nvs_type == NVS_TYPE_I64) {
|
} else if (nvs_type == NVS_TYPE_I64) {
|
||||||
value=malloc(sizeof(int64_t));
|
value=malloc_init_external(sizeof(int64_t));
|
||||||
*(int64_t *)value = (int64_t)entry_value->valuedouble;
|
*(int64_t *)value = (int64_t)entry_value->valuedouble;
|
||||||
} else if (nvs_type == NVS_TYPE_U64) {
|
} else if (nvs_type == NVS_TYPE_U64) {
|
||||||
value=malloc(sizeof(uint64_t));
|
value=malloc_init_external(sizeof(uint64_t));
|
||||||
*(uint64_t *)value = (uint64_t)entry_value->valuedouble;
|
*(uint64_t *)value = (uint64_t)entry_value->valuedouble;
|
||||||
} else if (nvs_type == NVS_TYPE_STR) {
|
} else if (nvs_type == NVS_TYPE_STR) {
|
||||||
if(!cJSON_IsString(entry_value)){
|
if(!cJSON_IsString(entry_value)){
|
||||||
@@ -361,8 +368,7 @@ void * config_safe_alloc_get_entry_value(nvs_type_t nvs_type, cJSON * entry){
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
size_t len=strlen(cJSON_GetStringValue(entry_value));
|
size_t len=strlen(cJSON_GetStringValue(entry_value));
|
||||||
value=(void *)heap_caps_malloc(len+1, MALLOC_CAP_DMA);
|
value=(void *)malloc_init_external(len+1);
|
||||||
memset(value,0x00,len+1);
|
|
||||||
memcpy(value,cJSON_GetStringValue(entry_value),len);
|
memcpy(value,cJSON_GetStringValue(entry_value),len);
|
||||||
if(value==NULL){
|
if(value==NULL){
|
||||||
char * entry_str = cJSON_PrintUnformatted(entry);
|
char * entry_str = cJSON_PrintUnformatted(entry);
|
||||||
@@ -406,12 +412,11 @@ void config_commit_to_nvs(){
|
|||||||
void * value = config_safe_alloc_get_entry_value(type, entry);
|
void * value = config_safe_alloc_get_entry_value(type, entry);
|
||||||
if(value!=NULL){
|
if(value!=NULL){
|
||||||
size_t len=strlen(entry->string);
|
size_t len=strlen(entry->string);
|
||||||
char * key=(void *)heap_caps_malloc(len+1, MALLOC_CAP_DMA);
|
char * key=(void *)malloc_init_external(len+1);
|
||||||
memset(key,0x00,len+1);
|
|
||||||
memcpy(key,entry->string,len);
|
memcpy(key,entry->string,len);
|
||||||
esp_err_t err = store_nvs_value(type,key,value);
|
esp_err_t err = store_nvs_value(type,key,value);
|
||||||
free(key);
|
FREE_AND_NULL(key);
|
||||||
free(value);
|
FREE_AND_NULL(value);
|
||||||
|
|
||||||
if(err!=ESP_OK){
|
if(err!=ESP_OK){
|
||||||
char * entry_str = cJSON_PrintUnformatted(entry);
|
char * entry_str = cJSON_PrintUnformatted(entry);
|
||||||
@@ -617,11 +622,11 @@ void * config_alloc_get(nvs_type_t nvs_type, const char *key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void * config_alloc_get_str(const char *key, char *lead, char *fallback) {
|
void * config_alloc_get_str(const char *key, char *lead, char *fallback) {
|
||||||
if (lead && *lead) return strdup(lead);
|
if (lead && *lead) return strdup_psram(lead);
|
||||||
char *value = config_alloc_get_default(NVS_TYPE_STR, key, NULL, 0);
|
char *value = config_alloc_get_default(NVS_TYPE_STR, key, NULL, 0);
|
||||||
if ((!value || !*value) && fallback) {
|
if ((!value || !*value) && fallback) {
|
||||||
if (value) free(value);
|
if (value) free(value);
|
||||||
value = strdup(fallback);
|
value = strdup_psram(fallback);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@@ -673,7 +678,7 @@ char * config_alloc_get_json(bool bFormatted){
|
|||||||
char * json_buffer = NULL;
|
char * json_buffer = NULL;
|
||||||
if(!config_lock(LOCK_MAX_WAIT/portTICK_PERIOD_MS)){
|
if(!config_lock(LOCK_MAX_WAIT/portTICK_PERIOD_MS)){
|
||||||
ESP_LOGE(TAG, "Unable to lock config after %d ms",LOCK_MAX_WAIT);
|
ESP_LOGE(TAG, "Unable to lock config after %d ms",LOCK_MAX_WAIT);
|
||||||
return strdup("{\"error\":\"Unable to lock configuration object.\"}");
|
return strdup_psram("{\"error\":\"Unable to lock configuration object.\"}");
|
||||||
}
|
}
|
||||||
if(bFormatted){
|
if(bFormatted){
|
||||||
json_buffer= cJSON_Print(nvs_json);
|
json_buffer= cJSON_Print(nvs_json);
|
||||||
@@ -686,6 +691,10 @@ char * config_alloc_get_json(bool bFormatted){
|
|||||||
}
|
}
|
||||||
esp_err_t config_set_value(nvs_type_t nvs_type, const char *key, const void * value){
|
esp_err_t config_set_value(nvs_type_t nvs_type, const char *key, const void * value){
|
||||||
esp_err_t result = ESP_OK;
|
esp_err_t result = ESP_OK;
|
||||||
|
if(!key ||!key[0]){
|
||||||
|
ESP_LOGW(TAG,"Empty key passed. Ignoring entry!");
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
if(!config_lock(LOCK_MAX_WAIT/portTICK_PERIOD_MS)){
|
if(!config_lock(LOCK_MAX_WAIT/portTICK_PERIOD_MS)){
|
||||||
ESP_LOGE(TAG, "Unable to lock config after %d ms",LOCK_MAX_WAIT);
|
ESP_LOGE(TAG, "Unable to lock config after %d ms",LOCK_MAX_WAIT);
|
||||||
result = ESP_FAIL;
|
result = ESP_FAIL;
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ idf_component_register( SRCS
|
|||||||
cmd_config.c
|
cmd_config.c
|
||||||
INCLUDE_DIRS .
|
INCLUDE_DIRS .
|
||||||
REQUIRES nvs_flash
|
REQUIRES nvs_flash
|
||||||
PRIV_REQUIRES console app_update tools services spi_flash platform_config vfs pthread wifi-manager platform_config newlib telnet display squeezelite)
|
PRIV_REQUIRES console app_update tools services spi_flash platform_config vfs pthread wifi-manager platform_config newlib telnet display squeezelite services)
|
||||||
target_link_libraries(${COMPONENT_LIB} "-Wl,--undefined=GDS_DrawPixelFast")
|
target_link_libraries(${COMPONENT_LIB} "-Wl,--undefined=GDS_DrawPixelFast")
|
||||||
target_link_libraries(${COMPONENT_LIB} ${build_dir}/esp-idf/$<TARGET_PROPERTY:RECOVERY_PREFIX>/lib$<TARGET_PROPERTY:RECOVERY_PREFIX>.a )
|
target_link_libraries(${COMPONENT_LIB} ${build_dir}/esp-idf/$<TARGET_PROPERTY:RECOVERY_PREFIX>/lib$<TARGET_PROPERTY:RECOVERY_PREFIX>.a )
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
idf_build_get_property(idf_path IDF_PATH)
|
idf_build_get_property(idf_path IDF_PATH)
|
||||||
idf_component_register( SRCS cmd_squeezelite.c
|
idf_component_register( SRCS cmd_squeezelite.c
|
||||||
INCLUDE_DIRS .
|
INCLUDE_DIRS .
|
||||||
PRIV_REQUIRES spi_flash bootloader_support partition_table bootloader_support console codecs squeezelite newlib pthread tools platform_config display )
|
PRIV_REQUIRES spi_flash bootloader_support partition_table bootloader_support console codecs squeezelite newlib pthread tools platform_config display services)
|
||||||
|
|
||||||
|
|
||||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--undefined=feof")
|
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--undefined=feof")
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
#include "platform_esp32.h"
|
#include "platform_esp32.h"
|
||||||
#include "platform_config.h"
|
#include "platform_config.h"
|
||||||
#include "esp_app_format.h"
|
#include "esp_app_format.h"
|
||||||
|
#include "globdefs.h"
|
||||||
|
|
||||||
extern esp_err_t process_recovery_ota(const char * bin_url, char * bin_buffer, uint32_t length);
|
extern esp_err_t process_recovery_ota(const char * bin_url, char * bin_buffer, uint32_t length);
|
||||||
static const char * TAG = "squeezelite_cmd";
|
static const char * TAG = "squeezelite_cmd";
|
||||||
#define SQUEEZELITE_THREAD_STACK_SIZE (4*1024)
|
#define SQUEEZELITE_THREAD_STACK_SIZE (4*1024)
|
||||||
@@ -112,8 +114,7 @@ static int launchsqueezelite(int argc, char **argv)
|
|||||||
ESP_LOGV(TAG,"Saving args in thread structure");
|
ESP_LOGV(TAG,"Saving args in thread structure");
|
||||||
|
|
||||||
thread_parms.argc=0;
|
thread_parms.argc=0;
|
||||||
thread_parms.argv = malloc(sizeof(char**)*(argc+ADDITIONAL_SQUEEZELITE_ARGS));
|
thread_parms.argv = malloc_init_external(sizeof(char**)*(argc+ADDITIONAL_SQUEEZELITE_ARGS));
|
||||||
memset(thread_parms.argv,'\0',sizeof(char**)*(argc+ADDITIONAL_SQUEEZELITE_ARGS));
|
|
||||||
|
|
||||||
for(int i=0;i<argc;i++){
|
for(int i=0;i<argc;i++){
|
||||||
ESP_LOGD(TAG ,"assigning parm %u : %s",i,argv[i]);
|
ESP_LOGD(TAG ,"assigning parm %u : %s",i,argv[i]);
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
CONDITIONS OF ANY KIND, either express or implied.
|
CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*/
|
*/
|
||||||
//#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "cmd_config.h"
|
#include "cmd_config.h"
|
||||||
#include "argtable3/argtable3.h"
|
#include "argtable3/argtable3.h"
|
||||||
@@ -18,14 +17,19 @@
|
|||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "messaging.h"
|
#include "messaging.h"
|
||||||
#include "accessors.h"
|
#include "accessors.h"
|
||||||
|
#include "adac.h"
|
||||||
|
#include "globdefs.h"
|
||||||
|
#include "cJSON.h"
|
||||||
|
|
||||||
const char * desc_squeezelite ="Squeezelite Options";
|
const char * desc_squeezelite ="Squeezelite Options";
|
||||||
const char * desc_dac= "DAC Options";
|
const char * desc_dac= "DAC Options";
|
||||||
|
const char * desc_preset= "Preset Options";
|
||||||
const char * desc_spdif= "SPDIF Options";
|
const char * desc_spdif= "SPDIF Options";
|
||||||
const char * desc_audio= "General Audio Options";
|
const char * desc_audio= "General Audio Options";
|
||||||
const char * desc_bt_source= "Bluetooth Audio Output Options";
|
const char * desc_bt_source= "Bluetooth Audio Output Options";
|
||||||
const char * desc_rotary= "Rotary Control";
|
const char * desc_rotary= "Rotary Control";
|
||||||
|
|
||||||
|
extern const struct adac_s *dac_set[];
|
||||||
|
|
||||||
#define CODECS_BASE "flac|pcm|mp3|ogg"
|
#define CODECS_BASE "flac|pcm|mp3|ogg"
|
||||||
#if NO_FAAD
|
#if NO_FAAD
|
||||||
@@ -44,6 +48,11 @@ const char * desc_rotary= "Rotary Control";
|
|||||||
#define CODECS_DSD ""
|
#define CODECS_DSD ""
|
||||||
#endif
|
#endif
|
||||||
#define CODECS_MP3 "|mad|mpg"
|
#define CODECS_MP3 "|mad|mpg"
|
||||||
|
#ifdef CONFIG_SQUEEZEAMP
|
||||||
|
static const char * known_configs = "";
|
||||||
|
#else
|
||||||
|
static const char * known_configs_string = "[{\"name\":\"ESP32A1S Old Model config 1 (AC101)\",\"config\":[{\"dac_config\":\"AC101,bck=27,ws=26,do=25,di=35,sda=33,scl=32\"},{\"dac_controlset\":\"\"},{\"set_GPIO\":\"\"},{\"spdif_config\":\"21=amp,22=green:0,39=jack:0\"}]},{\"name\":\"ESP32A1S Old Model config 2 (AC101)\",\"config\":[{\"dac_config\":\"AC101,bck=27,ws=26,do=25,di=35,sda=33,scl=32\"},{\"dac_controlset\":\"\"},{\"set_GPIO\":\"\"},{\"spdif_config\":\"21=amp,22=green:0,5=jack:0\"}]},{\"name\":\"ESP32A1S V2.2+ variant 1 (ES8388)\",\"config\":[{\"dac_config\":\"model=ES8388,bck=27,ws=25,do=26,sda=33,scl=32,di=35,i2c=16\"},{\"dac_controlset\":\"\"},{\"set_GPIO\":\"21=amp,22=green:0,39=jack:0\"},{\"spdif_config\":\"\"}]},{\"name\":\"ESP32A1S V2.2+ variant 2 (ES8388)\",\"config\":[{\"dac_config\":\"model=ES8388,bck=5,ws=25,do=26,sda=18,scl=23,i2c=16\"},{\"dac_controlset\":\"\"},{\"set_GPIO\":\"21=amp,22=green:0,39=jack:0\"},{\"spdif_config\":\"\"}]}]";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if !defined(MODEL_NAME)
|
#if !defined(MODEL_NAME)
|
||||||
@@ -58,6 +67,7 @@ const char * desc_rotary= "Rotary Control";
|
|||||||
#define MODEL_NAME_STRING STR(MODEL_NAME)
|
#define MODEL_NAME_STRING STR(MODEL_NAME)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define CODECS CODECS_BASE CODECS_AAC CODECS_FF CODECS_DSD CODECS_MP3
|
#define CODECS CODECS_BASE CODECS_AAC CODECS_FF CODECS_DSD CODECS_MP3
|
||||||
#define NOT_OUTPUT "has input capabilities only"
|
#define NOT_OUTPUT "has input capabilities only"
|
||||||
#define NOT_GPIO "is not a GPIO"
|
#define NOT_GPIO "is not a GPIO"
|
||||||
@@ -85,7 +95,10 @@ static struct {
|
|||||||
struct arg_lit *clear;
|
struct arg_lit *clear;
|
||||||
struct arg_end *end;
|
struct arg_end *end;
|
||||||
} i2s_args;
|
} i2s_args;
|
||||||
|
static struct {
|
||||||
|
struct arg_str *model_name;
|
||||||
|
struct arg_end *end;
|
||||||
|
} known_model_args;
|
||||||
static struct {
|
static struct {
|
||||||
struct arg_rem * rem;
|
struct arg_rem * rem;
|
||||||
struct arg_int * A;
|
struct arg_int * A;
|
||||||
@@ -189,9 +202,8 @@ int check_missing_parm(struct arg_int * int_parm, FILE * f){
|
|||||||
}
|
}
|
||||||
char * strip_bt_name(char * opt_str)
|
char * strip_bt_name(char * opt_str)
|
||||||
{
|
{
|
||||||
char *result = malloc(strlen(opt_str)+1);
|
char *result = malloc_init_external(strlen(opt_str)+1);
|
||||||
memset(result, 0x00, strlen(opt_str)+1);
|
char *str = strdup_psram(opt_str);
|
||||||
char *str = strdup(opt_str);
|
|
||||||
const char * output_marker=" -o";
|
const char * output_marker=" -o";
|
||||||
|
|
||||||
if(!result ){
|
if(!result ){
|
||||||
@@ -555,7 +567,18 @@ static int do_rotary_cmd(int argc, char **argv){
|
|||||||
FREE_AND_NULL(buf);
|
FREE_AND_NULL(buf);
|
||||||
return (nerrors==0 && err==ESP_OK)?0:1;
|
return (nerrors==0 && err==ESP_OK)?0:1;
|
||||||
}
|
}
|
||||||
|
static int is_valid_gpio_number(int gpio, const char * name, FILE *f, bool mandatory, struct arg_int * target, bool output){
|
||||||
|
bool invalid = (!GPIO_IS_VALID_GPIO(gpio) ||(output && !GPIO_IS_VALID_OUTPUT_GPIO(gpio))) ;
|
||||||
|
if(invalid && mandatory && gpio!=-1){
|
||||||
|
fprintf(f,"Error: Invalid mandatory gpio %d for %s\n",gpio,name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(target && !invalid){
|
||||||
|
target->count=1;
|
||||||
|
target->ival[0]=gpio;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
static int do_i2s_cmd(int argc, char **argv)
|
static int do_i2s_cmd(int argc, char **argv)
|
||||||
{
|
{
|
||||||
i2s_platform_config_t i2s_dac_pin = {
|
i2s_platform_config_t i2s_dac_pin = {
|
||||||
@@ -570,6 +593,7 @@ static int do_i2s_cmd(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
strcpy(i2s_dac_pin.model, "I2S");
|
strcpy(i2s_dac_pin.model, "I2S");
|
||||||
|
ESP_LOGD(TAG,"Processing i2s command %s with %d parameters",argv[0],argc);
|
||||||
|
|
||||||
esp_err_t err=ESP_OK;
|
esp_err_t err=ESP_OK;
|
||||||
int nerrors = arg_parse(argc, argv,(void **)&i2s_args);
|
int nerrors = arg_parse(argc, argv,(void **)&i2s_args);
|
||||||
@@ -583,39 +607,39 @@ static int do_i2s_cmd(int argc, char **argv)
|
|||||||
size_t buf_size = 0;
|
size_t buf_size = 0;
|
||||||
FILE *f = open_memstream(&buf, &buf_size);
|
FILE *f = open_memstream(&buf, &buf_size);
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
|
ESP_LOGE(TAG, "do_i2s_cmd: Failed to open memstream");
|
||||||
cmd_send_messaging(argv[0],MESSAGING_ERROR,"Unable to open memory stream.\n");
|
cmd_send_messaging(argv[0],MESSAGING_ERROR,"Unable to open memory stream.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(nerrors >0){
|
if(nerrors >0){
|
||||||
|
ESP_LOGE(TAG,"do_i2s_cmd: %d errors parsing arguments",nerrors);
|
||||||
arg_print_errors(f,i2s_args.end,desc_dac);
|
arg_print_errors(f,i2s_args.end,desc_dac);
|
||||||
fclose(f);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
nerrors+=is_output_gpio(i2s_args.clock, f, &i2s_dac_pin.pin.bck_io_num, true);
|
else {
|
||||||
nerrors+=is_output_gpio(i2s_args.wordselect, f, &i2s_dac_pin.pin.ws_io_num, true);
|
|
||||||
nerrors+=is_output_gpio(i2s_args.data, f, &i2s_dac_pin.pin.data_out_num, true);
|
|
||||||
nerrors+=is_output_gpio(i2s_args.mute_gpio, f, &i2s_dac_pin.mute_gpio, false);
|
|
||||||
if(i2s_dac_pin.mute_gpio>0){
|
|
||||||
i2s_dac_pin.mute_level = i2s_args.mute_level->count>0?1:0;
|
|
||||||
}
|
|
||||||
if(i2s_args.dac_sda->count>0 && i2s_args.dac_sda->ival[0]>=0){
|
|
||||||
// if SDA specified, then SDA and SCL are both mandatory
|
|
||||||
nerrors+=is_output_gpio(i2s_args.dac_sda, f, &i2s_dac_pin.sda, false);
|
|
||||||
nerrors+=is_output_gpio(i2s_args.dac_scl, f, &i2s_dac_pin.scl, false);
|
|
||||||
}
|
|
||||||
if(i2s_args.dac_sda->count==0&& i2s_args.dac_i2c->count>0){
|
|
||||||
fprintf(f,"warning: ignoring i2c address, since dac i2c gpios config is incomplete\n");
|
|
||||||
}
|
|
||||||
else if(i2s_args.dac_i2c->count>0){
|
|
||||||
i2s_dac_pin.i2c_addr = i2s_args.dac_i2c->ival[0];
|
|
||||||
}
|
|
||||||
if(i2s_args.model_name->count>0 && strlen(i2s_args.model_name->sval[0])>0){
|
|
||||||
strncpy(i2s_dac_pin.model,i2s_args.model_name->sval[0],sizeof(i2s_dac_pin.model));
|
strncpy(i2s_dac_pin.model,i2s_args.model_name->sval[0],sizeof(i2s_dac_pin.model));
|
||||||
i2s_dac_pin.model[sizeof(i2s_dac_pin.model) - 1] = '\0';
|
i2s_dac_pin.model[sizeof(i2s_dac_pin.model) - 1] = '\0';
|
||||||
}
|
nerrors += is_output_gpio(i2s_args.clock, f, &i2s_dac_pin.pin.bck_io_num, true);
|
||||||
if(!nerrors ){
|
nerrors += is_output_gpio(i2s_args.wordselect, f, &i2s_dac_pin.pin.ws_io_num, true);
|
||||||
fprintf(f,"Storing i2s parameters.\n");
|
nerrors += is_output_gpio(i2s_args.data, f, &i2s_dac_pin.pin.data_out_num, true);
|
||||||
nerrors+=(config_i2s_set(&i2s_dac_pin, "dac_config")!=ESP_OK);
|
nerrors += is_output_gpio(i2s_args.mute_gpio, f, &i2s_dac_pin.mute_gpio, false);
|
||||||
|
if (i2s_dac_pin.mute_gpio >= 0) {
|
||||||
|
i2s_dac_pin.mute_level = i2s_args.mute_level->count > 0 ? 1 : 0;
|
||||||
|
}
|
||||||
|
if (i2s_args.dac_sda->count > 0 && i2s_args.dac_sda->ival[0] >= 0) {
|
||||||
|
// if SDA specified, then SDA and SCL are both mandatory
|
||||||
|
nerrors += is_output_gpio(i2s_args.dac_sda, f, &i2s_dac_pin.sda, false);
|
||||||
|
nerrors += is_output_gpio(i2s_args.dac_scl, f, &i2s_dac_pin.scl, false);
|
||||||
|
}
|
||||||
|
if (i2s_args.dac_sda->count == 0 && i2s_args.dac_i2c->count > 0) {
|
||||||
|
fprintf(f, "warning: ignoring i2c address, since dac i2c gpios config is incomplete\n");
|
||||||
|
} else if (i2s_args.dac_i2c->count > 0) {
|
||||||
|
i2s_dac_pin.i2c_addr = i2s_args.dac_i2c->ival[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nerrors) {
|
||||||
|
fprintf(f, "Storing i2s parameters.\n");
|
||||||
|
nerrors += (config_i2s_set(&i2s_dac_pin, "dac_config") != ESP_OK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(!nerrors ){
|
if(!nerrors ){
|
||||||
fprintf(f,"Done.\n");
|
fprintf(f,"Done.\n");
|
||||||
@@ -647,40 +671,58 @@ cJSON * example_cb(){
|
|||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
//const i2s_pin_config_t * config_get_spdif_pin_struct( );
|
cJSON * known_model_cb(){
|
||||||
|
const char * key="board_model";
|
||||||
|
cJSON * values = cJSON_CreateObject();
|
||||||
|
if(!values){
|
||||||
|
ESP_LOGE(TAG,"known_model_cb: Failed to create JSON object");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
char * name = config_alloc_get_default(NVS_TYPE_STR,key,"",0);
|
||||||
|
if(!name){
|
||||||
|
ESP_LOGE(TAG,"Failed to get board model from nvs key %s ",key);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cJSON_AddStringToObject(values,known_model_args.model_name->hdr.longopts,name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
cJSON * i2s_cb(){
|
cJSON * i2s_cb(){
|
||||||
cJSON * values = cJSON_CreateObject();
|
cJSON * values = cJSON_CreateObject();
|
||||||
|
|
||||||
const i2s_platform_config_t * i2s_conf= config_dac_get( );
|
const i2s_platform_config_t * i2s_conf= config_dac_get( );
|
||||||
|
|
||||||
if(i2s_conf->pin.bck_io_num>0 ) {
|
if(i2s_conf->pin.bck_io_num>0 ) {
|
||||||
cJSON_AddNumberToObject(values,"clock",i2s_conf->pin.bck_io_num);
|
cJSON_AddNumberToObject(values,i2s_args.clock->hdr.longopts,i2s_conf->pin.bck_io_num);
|
||||||
}
|
}
|
||||||
if(i2s_conf->pin.ws_io_num>=0 ) {
|
if(i2s_conf->pin.ws_io_num>=0 ) {
|
||||||
cJSON_AddNumberToObject(values,"wordselect",i2s_conf->pin.ws_io_num);
|
cJSON_AddNumberToObject(values,i2s_args.wordselect->hdr.longopts,i2s_conf->pin.ws_io_num);
|
||||||
}
|
}
|
||||||
if(i2s_conf->pin.data_out_num>=0 ) {
|
if(i2s_conf->pin.data_out_num>=0 ) {
|
||||||
cJSON_AddNumberToObject(values,"data",i2s_conf->pin.data_out_num);
|
cJSON_AddNumberToObject(values,i2s_args.data->hdr.longopts,i2s_conf->pin.data_out_num);
|
||||||
}
|
}
|
||||||
if(i2s_conf->sda>=0 ) {
|
if(i2s_conf->sda>=0 ) {
|
||||||
cJSON_AddNumberToObject(values,"dac_sda",i2s_conf->sda);
|
cJSON_AddNumberToObject(values,i2s_args.dac_sda->hdr.longopts,i2s_conf->sda);
|
||||||
}
|
}
|
||||||
if(i2s_conf->scl>=0 ) {
|
if(i2s_conf->scl>=0 ) {
|
||||||
cJSON_AddNumberToObject(values,"dac_scl",i2s_conf->scl);
|
cJSON_AddNumberToObject(values,i2s_args.dac_scl->hdr.longopts,i2s_conf->scl);
|
||||||
}
|
}
|
||||||
if(i2s_conf->i2c_addr>=0 ) {
|
if(i2s_conf->i2c_addr>=0 ) {
|
||||||
cJSON_AddNumberToObject(values,"dac_i2c",i2s_conf->i2c_addr);
|
cJSON_AddNumberToObject(values,i2s_args.dac_i2c->hdr.longopts,i2s_conf->i2c_addr);
|
||||||
}
|
}
|
||||||
if(i2s_conf->mute_gpio>=0 ) {
|
if(i2s_conf->mute_gpio>=0 ) {
|
||||||
cJSON_AddNumberToObject(values,"mute_gpio",i2s_conf->mute_gpio);
|
cJSON_AddNumberToObject(values,i2s_args.mute_gpio->hdr.longopts,i2s_conf->mute_gpio);
|
||||||
}
|
}
|
||||||
if(i2s_conf->mute_level>=0 ) {
|
if(i2s_conf->mute_level>=0 ) {
|
||||||
cJSON_AddBoolToObject(values,"mute_level",i2s_conf->mute_level>0);
|
cJSON_AddBoolToObject(values,i2s_args.mute_level->hdr.longopts,i2s_conf->mute_level>0);
|
||||||
}
|
}
|
||||||
if(strlen(i2s_conf->model)>0){
|
if(strlen(i2s_conf->model)>0){
|
||||||
cJSON_AddStringToObject(values,"model_name",i2s_conf->model);
|
cJSON_AddStringToObject(values,i2s_args.model_name->hdr.longopts,i2s_conf->model);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cJSON_AddStringToObject(values,"model_name","I2S");
|
cJSON_AddStringToObject(values,i2s_args.model_name->hdr.longopts,"I2S");
|
||||||
}
|
}
|
||||||
|
|
||||||
return values;
|
return values;
|
||||||
@@ -862,17 +904,288 @@ static char * get_log_level_options(const char * longname){
|
|||||||
char * options = NULL;
|
char * options = NULL;
|
||||||
int len = snprintf(NULL,0,template,longname,longname,longname);
|
int len = snprintf(NULL,0,template,longname,longname,longname);
|
||||||
if(len>0){
|
if(len>0){
|
||||||
options = malloc(len+1);
|
options = malloc_init_external(len+1);
|
||||||
snprintf(options,len,template,longname,longname,longname);
|
snprintf(options,len,template,longname,longname,longname);
|
||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// loop through dac_set and concatenate model name separated with |
|
||||||
|
static char * get_dac_list(){
|
||||||
|
const char * ES8388_MODEL_NAME = "ES8388|";
|
||||||
|
char * dac_list=NULL;
|
||||||
|
size_t total_len=0;
|
||||||
|
for(int i=0;dac_set[i];i++){
|
||||||
|
if(dac_set[i]->model && strlen(dac_set[i]->model)>0){
|
||||||
|
total_len+=strlen(dac_set[i]->model)+1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
total_len+=strlen(ES8388_MODEL_NAME);
|
||||||
|
dac_list = malloc_init_external(total_len+1);
|
||||||
|
if(dac_list){
|
||||||
|
for(int i=0;dac_set[i];i++){
|
||||||
|
if(dac_set[i]->model && strlen(dac_set[i]->model)>0){
|
||||||
|
strcat(dac_list,dac_set[i]->model);
|
||||||
|
strcat(dac_list,"|");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strcat(dac_list,ES8388_MODEL_NAME);
|
||||||
|
}
|
||||||
|
return dac_list;
|
||||||
|
}
|
||||||
|
void replace_char_in_string(char * str, char find, char replace){
|
||||||
|
for(int i=0;str[i];i++){
|
||||||
|
if(str[i]==find){
|
||||||
|
str[i]=replace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static cJSON * get_known_configurations(FILE * f){
|
||||||
|
#define err1_msg "Failed to parse known_configs json. %s\nError at:\n%s"
|
||||||
|
#define err2_msg "Known configs should be an array and it is not: \n%s"
|
||||||
|
if(!known_configs_string || strlen(known_configs_string)==0){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
cJSON * known_configs_json = cJSON_Parse(known_configs_string);
|
||||||
|
if(!known_configs_json){
|
||||||
|
if(f){
|
||||||
|
fprintf(f,err1_msg,known_configs_string,STR_OR_BLANK(cJSON_GetErrorPtr()));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ESP_LOGE(TAG,err1_msg,known_configs_string,STR_OR_BLANK(cJSON_GetErrorPtr()));
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(!cJSON_IsArray(known_configs_json)){
|
||||||
|
if(f){
|
||||||
|
fprintf(f,err2_msg,STR_OR_BLANK(cJSON_GetErrorPtr()));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ESP_LOGE(TAG,err2_msg,STR_OR_BLANK(cJSON_GetErrorPtr()));
|
||||||
|
}
|
||||||
|
cJSON_Delete(known_configs_json);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return known_configs_json;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static cJSON * find_known_model_name(cJSON * root,const char * name, FILE * f, bool * found){
|
||||||
|
if(found){
|
||||||
|
*found = false;
|
||||||
|
}
|
||||||
|
if(!root){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
cJSON * item;
|
||||||
|
cJSON_ArrayForEach(item, root){
|
||||||
|
if(cJSON_IsObject(item)){
|
||||||
|
cJSON * model = cJSON_GetObjectItem(item,"name");
|
||||||
|
if(model && cJSON_IsString(model) && strcmp(cJSON_GetStringValue(model),name)==0){
|
||||||
|
if(found){
|
||||||
|
*found = true;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
static esp_err_t is_known_model_name(const char * name, FILE * f, bool * found){
|
||||||
|
esp_err_t err = ESP_OK;
|
||||||
|
if(found){
|
||||||
|
*found = false;
|
||||||
|
}
|
||||||
|
if(!known_configs_string || strlen(known_configs_string)==0){
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
cJSON * known_configs_json = get_known_configurations(f);
|
||||||
|
if(known_configs_json){
|
||||||
|
cJSON * known_item = find_known_model_name(known_configs_json,name,f,found);
|
||||||
|
if(known_item && found){
|
||||||
|
*found = true;
|
||||||
|
}
|
||||||
|
cJSON_Delete(known_configs_json);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t save_known_config(const char * name, FILE * f){
|
||||||
|
esp_err_t err = ESP_OK;
|
||||||
|
char * json_string=NULL;
|
||||||
|
if(!known_configs_string || strlen(known_configs_string)==0){
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
cJSON * known_configs_json = get_known_configurations(f);
|
||||||
|
if(known_configs_json){
|
||||||
|
bool found = false;
|
||||||
|
cJSON * known_item = find_known_model_name(known_configs_json,name,f,&found);
|
||||||
|
if(known_item && found){
|
||||||
|
json_string = cJSON_Print(known_item);
|
||||||
|
ESP_LOGD(TAG,"known_item_string: %s",STR_OR_BLANK(json_string));
|
||||||
|
FREE_AND_NULL(json_string);
|
||||||
|
cJSON * kvp=NULL;
|
||||||
|
cJSON * config_array = cJSON_GetObjectItem(known_item,"config");
|
||||||
|
if(config_array && cJSON_IsArray(config_array)){
|
||||||
|
json_string = cJSON_Print(config_array);
|
||||||
|
ESP_LOGD(TAG,"config_array: %s",STR_OR_BLANK(json_string));
|
||||||
|
FREE_AND_NULL(json_string);
|
||||||
|
cJSON_ArrayForEach(kvp, config_array){
|
||||||
|
cJSON * kvp_value=kvp->child;
|
||||||
|
if(!kvp_value){
|
||||||
|
ESP_LOGE(TAG,"config entry is not an object!");
|
||||||
|
err=ESP_FAIL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
char * key = kvp_value->string;
|
||||||
|
char * value = kvp_value->valuestring;
|
||||||
|
if(!key || !value || strlen(key)==0){
|
||||||
|
ESP_LOGE(TAG,"Invalid config entry %s:%s",STR_OR_BLANK(key),STR_OR_BLANK(value));
|
||||||
|
err=ESP_FAIL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(f,"Storing %s=%s\n",key,value);
|
||||||
|
err = config_set_value(NVS_TYPE_STR,key,value);
|
||||||
|
if(err){
|
||||||
|
fprintf(f,"Failed: %s\n",esp_err_to_name(err));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
json_string = cJSON_Print(config_array);
|
||||||
|
char * known_item_string = cJSON_Print(known_item);
|
||||||
|
fprintf(f,"Failed to parse config array. %s\n%s\nKnown item found: %s\n",config_array?cJSON_IsArray(config_array)?"":"NOT AN ARRAY":"config entry not found",STR_OR_BLANK(json_string),STR_OR_BLANK(known_item_string));
|
||||||
|
FREE_AND_NULL(json_string);
|
||||||
|
FREE_AND_NULL(known_item_string);
|
||||||
|
err = ESP_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(err==ESP_OK){
|
||||||
|
err = config_set_value(NVS_TYPE_STR,"board_model",name);
|
||||||
|
if(err!=ESP_OK){
|
||||||
|
fprintf(f,"Failed to save board model %s\n",name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cJSON_Delete(known_configs_json);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * config_dac_alloc_print_known_config(){
|
||||||
|
cJSON * item=NULL;
|
||||||
|
char * dac_list=NULL;
|
||||||
|
size_t total_len=0;
|
||||||
|
cJSON * object = get_known_configurations(NULL);
|
||||||
|
if(!object){
|
||||||
|
return strdup_psram("");
|
||||||
|
}
|
||||||
|
// loop through all items, and concatenate model name separated with |
|
||||||
|
|
||||||
|
cJSON_ArrayForEach(item, object){
|
||||||
|
if(cJSON_IsObject(item)){
|
||||||
|
cJSON * model = cJSON_GetObjectItem(item,"name");
|
||||||
|
if(model && cJSON_IsString(model)){
|
||||||
|
total_len+=strlen(model->valuestring)+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(total_len==0){
|
||||||
|
ESP_LOGI(TAG,"No known configs found");
|
||||||
|
cJSON_Delete(object);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
dac_list = malloc_init_external(total_len+1);
|
||||||
|
if(dac_list){
|
||||||
|
cJSON_ArrayForEach(item, object){
|
||||||
|
if(cJSON_IsObject(item)){
|
||||||
|
cJSON * model = cJSON_GetObjectItem(item,"name");
|
||||||
|
if(model && cJSON_IsString(model)){
|
||||||
|
strcat(dac_list,model->valuestring);
|
||||||
|
strcat(dac_list,"|");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dac_list[strlen(dac_list)-1]='\0';
|
||||||
|
cJSON_Delete(object);
|
||||||
|
return dac_list;
|
||||||
|
}
|
||||||
|
static int do_register_known_templates_config(int argc, char **argv){
|
||||||
|
esp_err_t err=ESP_OK;
|
||||||
|
int nerrors = arg_parse(argc, argv,(void **)&known_model_args);
|
||||||
|
char *buf = NULL;
|
||||||
|
size_t buf_size = 0;
|
||||||
|
FILE *f = open_memstream(&buf, &buf_size);
|
||||||
|
if (f == NULL) {
|
||||||
|
cmd_send_messaging(argv[0],MESSAGING_ERROR,"Unable to open memory stream.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(nerrors >0){
|
||||||
|
arg_print_errors(f,known_model_args.end,desc_preset);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bool found=false;
|
||||||
|
|
||||||
|
if(nerrors +=(is_known_model_name(known_model_args.model_name->sval[0],f,&found)!=ESP_OK)){
|
||||||
|
fprintf(f,"Error registering known config %s. The model was not found.\n",known_model_args.model_name->sval[0]);
|
||||||
|
}
|
||||||
|
if(nerrors==0 && found){
|
||||||
|
fprintf(f,"Appling template configuration for %s\n",known_model_args.model_name->sval[0]);
|
||||||
|
nerrors+=((err=save_known_config(known_model_args.model_name->sval[0],f))!=ESP_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(err!=ESP_OK){
|
||||||
|
nerrors++;
|
||||||
|
fprintf(f,"Error registering known config %s.\n",known_model_args.model_name->sval[0]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(f,"Registered known config %s.\n",known_model_args.model_name->sval[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!nerrors ){
|
||||||
|
fprintf(f,"Done.\n");
|
||||||
|
}
|
||||||
|
fflush (f);
|
||||||
|
cmd_send_messaging(argv[0],nerrors>0?MESSAGING_ERROR:MESSAGING_INFO,"%s", buf);
|
||||||
|
fclose(f);
|
||||||
|
FREE_AND_NULL(buf);
|
||||||
|
return (nerrors==0 && err==ESP_OK)?0:1;
|
||||||
|
}
|
||||||
|
static void register_known_templates_config(){
|
||||||
|
char * known_models = config_dac_alloc_print_known_config();
|
||||||
|
known_model_args.model_name = arg_str1(NULL,"model_name",known_models,"Known Board Name.\nFor known boards, several systems parameters will be updated");
|
||||||
|
known_model_args.end = arg_end(1);
|
||||||
|
const esp_console_cmd_t cmd = {
|
||||||
|
.command = CFG_TYPE_HW("preset"),
|
||||||
|
.help = desc_preset,
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &do_register_known_templates_config,
|
||||||
|
.argtable = &known_model_args
|
||||||
|
};
|
||||||
|
cmd_to_json_with_cb(&cmd,&known_model_cb);
|
||||||
|
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
|
||||||
|
FREE_AND_NULL(known_models);
|
||||||
|
|
||||||
|
}
|
||||||
static void register_i2s_config(void){
|
static void register_i2s_config(void){
|
||||||
i2s_args.model_name = arg_str1(NULL,"model_name","TAS57xx|TAS5713|AC101|WM8978|I2S","DAC Model Name");
|
i2s_args.model_name = arg_str1(NULL,"model_name",STR_OR_BLANK(get_dac_list()),"DAC Model Name");
|
||||||
i2s_args.clear = arg_lit0(NULL, "clear", "Clear configuration");
|
i2s_args.clear = arg_lit0(NULL, "clear", "Clear configuration");
|
||||||
i2s_args.clock = arg_int1(NULL,"clock","<n>","Clock GPIO. e.g. 33");
|
i2s_args.clock = arg_int0(NULL,"clock","<n>","Clock GPIO. e.g. 33");
|
||||||
i2s_args.wordselect = arg_int1(NULL,"wordselect","<n>","Word Select GPIO. e.g. 25");
|
i2s_args.wordselect = arg_int0(NULL,"wordselect","<n>","Word Select GPIO. e.g. 25");
|
||||||
i2s_args.data = arg_int1(NULL,"data","<n>","Data GPIO. e.g. 32");
|
i2s_args.data = arg_int0(NULL,"data","<n>","Data GPIO. e.g. 32");
|
||||||
i2s_args.mute_gpio = arg_int0(NULL,"mute_gpio", "<n>", "Mute GPIO. e.g. 14");
|
i2s_args.mute_gpio = arg_int0(NULL,"mute_gpio", "<n>", "Mute GPIO. e.g. 14");
|
||||||
i2s_args.mute_level = arg_lit0(NULL,"mute_level","Mute GPIO level. Checked=HIGH, Unchecked=LOW");
|
i2s_args.mute_level = arg_lit0(NULL,"mute_level","Mute GPIO level. Checked=HIGH, Unchecked=LOW");
|
||||||
i2s_args.dac_sda = arg_int0(NULL,"dac_sda", "<n>", "SDA GPIO. e.g. 27");
|
i2s_args.dac_sda = arg_int0(NULL,"dac_sda", "<n>", "SDA GPIO. e.g. 27");
|
||||||
@@ -1005,6 +1318,9 @@ static void register_squeezelite_config(void){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void register_config_cmd(void){
|
void register_config_cmd(void){
|
||||||
|
if(!is_dac_config_locked()){
|
||||||
|
register_known_templates_config();
|
||||||
|
}
|
||||||
register_audio_config();
|
register_audio_config();
|
||||||
// register_squeezelite_config();
|
// register_squeezelite_config();
|
||||||
register_bt_source_config();
|
register_bt_source_config();
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
CONDITIONS OF ANY KIND, either express or implied.
|
CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*/
|
*/
|
||||||
//#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "cmd_i2ctools.h"
|
#include "cmd_i2ctools.h"
|
||||||
#include "argtable3/argtable3.h"
|
#include "argtable3/argtable3.h"
|
||||||
@@ -21,6 +20,7 @@
|
|||||||
#include "messaging.h"
|
#include "messaging.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "globdefs.h"
|
||||||
|
|
||||||
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
|
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
|
||||||
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
|
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
|
||||||
@@ -754,7 +754,7 @@ static int do_i2cget_cmd(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||||
i2c_master_start(cmd);
|
i2c_master_start(cmd);
|
||||||
uint8_t *data = malloc(len);
|
uint8_t *data = malloc_init_external(len);
|
||||||
if (data_addr != -1) {
|
if (data_addr != -1) {
|
||||||
i2c_master_write_byte(cmd, chip_addr << 1 | WRITE_BIT, ACK_CHECK_EN);
|
i2c_master_write_byte(cmd, chip_addr << 1 | WRITE_BIT, ACK_CHECK_EN);
|
||||||
i2c_master_write_byte(cmd, data_addr, ACK_CHECK_EN);
|
i2c_master_write_byte(cmd, data_addr, ACK_CHECK_EN);
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
CONDITIONS OF ANY KIND, either express or implied.
|
CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*/
|
*/
|
||||||
//#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -27,41 +26,50 @@ extern "C" {
|
|||||||
#include "nvs_utilities.h"
|
#include "nvs_utilities.h"
|
||||||
#include "platform_console.h"
|
#include "platform_console.h"
|
||||||
#include "messaging.h"
|
#include "messaging.h"
|
||||||
|
#include "globdefs.h"
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
|
extern esp_err_t network_wifi_erase_legacy();
|
||||||
|
extern esp_err_t network_wifi_erase_known_ap();
|
||||||
|
|
||||||
static const char *ARG_TYPE_STR = "type can be: i8, u8, i16, u16 i32, u32 i64, u64, str, blob";
|
static const char *ARG_TYPE_STR = "type can be: i8, u8, i16, u16 i32, u32 i64, u64, str, blob";
|
||||||
static const char * TAG = "cmd_nvs";
|
static const char * TAG = "cmd_nvs";
|
||||||
|
|
||||||
static struct {
|
EXT_RAM_ATTR static struct {
|
||||||
struct arg_str *key;
|
struct arg_str *key;
|
||||||
struct arg_str *type;
|
struct arg_str *type;
|
||||||
struct arg_str *value;
|
struct arg_str *value;
|
||||||
struct arg_end *end;
|
struct arg_end *end;
|
||||||
} set_args;
|
} set_args;
|
||||||
|
|
||||||
static struct {
|
EXT_RAM_ATTR static struct {
|
||||||
struct arg_str *key;
|
struct arg_str *key;
|
||||||
struct arg_str *type;
|
struct arg_str *type;
|
||||||
struct arg_end *end;
|
struct arg_end *end;
|
||||||
} get_args;
|
} get_args;
|
||||||
|
|
||||||
static struct {
|
EXT_RAM_ATTR static struct {
|
||||||
struct arg_str *key;
|
struct arg_str *key;
|
||||||
struct arg_end *end;
|
struct arg_end *end;
|
||||||
} erase_args;
|
} erase_args;
|
||||||
|
|
||||||
static struct {
|
EXT_RAM_ATTR static struct {
|
||||||
struct arg_str *namespace;
|
struct arg_str *namespace;
|
||||||
struct arg_end *end;
|
struct arg_end *end;
|
||||||
} erase_all_args;
|
} erase_all_args;
|
||||||
|
|
||||||
static struct {
|
EXT_RAM_ATTR static struct {
|
||||||
struct arg_str *partition;
|
struct arg_str *partition;
|
||||||
struct arg_str *namespace;
|
struct arg_str *namespace;
|
||||||
struct arg_str *type;
|
struct arg_str *type;
|
||||||
struct arg_end *end;
|
struct arg_end *end;
|
||||||
} list_args;
|
} list_args;
|
||||||
|
|
||||||
|
EXT_RAM_ATTR static struct {
|
||||||
|
struct arg_lit *legacy;
|
||||||
|
struct arg_lit *ap_list;
|
||||||
|
struct arg_end *end;
|
||||||
|
} wifi_erase_args;
|
||||||
|
|
||||||
|
|
||||||
static esp_err_t store_blob(nvs_handle nvs, const char *key, const char *str_values)
|
static esp_err_t store_blob(nvs_handle nvs, const char *key, const char *str_values)
|
||||||
@@ -75,7 +83,7 @@ static esp_err_t store_blob(nvs_handle nvs, const char *key, const char *str_val
|
|||||||
return ESP_ERR_NVS_TYPE_MISMATCH;
|
return ESP_ERR_NVS_TYPE_MISMATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *blob = (char *)malloc(blob_len);
|
char *blob = (char *)malloc_init_external(blob_len);
|
||||||
if (blob == NULL) {
|
if (blob == NULL) {
|
||||||
return ESP_ERR_NO_MEM;
|
return ESP_ERR_NO_MEM;
|
||||||
}
|
}
|
||||||
@@ -261,7 +269,7 @@ static esp_err_t get_value_from_nvs(const char *key, const char *str_type)
|
|||||||
} else if (type == NVS_TYPE_STR) {
|
} else if (type == NVS_TYPE_STR) {
|
||||||
size_t len=0;
|
size_t len=0;
|
||||||
if ( (err = nvs_get_str(nvs, key, NULL, &len)) == ESP_OK) {
|
if ( (err = nvs_get_str(nvs, key, NULL, &len)) == ESP_OK) {
|
||||||
char *str = (char *)malloc(len);
|
char *str = (char *)malloc_init_external(len);
|
||||||
if ( (err = nvs_get_str(nvs, key, str, &len)) == ESP_OK) {
|
if ( (err = nvs_get_str(nvs, key, str, &len)) == ESP_OK) {
|
||||||
log_send_messaging(MESSAGING_INFO,"String associated with key '%s' is %s \n", key, str);
|
log_send_messaging(MESSAGING_INFO,"String associated with key '%s' is %s \n", key, str);
|
||||||
}
|
}
|
||||||
@@ -270,7 +278,7 @@ static esp_err_t get_value_from_nvs(const char *key, const char *str_type)
|
|||||||
} else if (type == NVS_TYPE_BLOB) {
|
} else if (type == NVS_TYPE_BLOB) {
|
||||||
size_t len;
|
size_t len;
|
||||||
if ( (err = nvs_get_blob(nvs, key, NULL, &len)) == ESP_OK) {
|
if ( (err = nvs_get_blob(nvs, key, NULL, &len)) == ESP_OK) {
|
||||||
char *blob = (char *)malloc(len);
|
char *blob = (char *)malloc_init_external(len);
|
||||||
if ( (err = nvs_get_blob(nvs, key, blob, &len)) == ESP_OK) {
|
if ( (err = nvs_get_blob(nvs, key, blob, &len)) == ESP_OK) {
|
||||||
log_send_messaging(MESSAGING_INFO,"Blob associated with key '%s' is %d bytes long: \n", key, len);
|
log_send_messaging(MESSAGING_INFO,"Blob associated with key '%s' is %d bytes long: \n", key, len);
|
||||||
print_blob(blob, len);
|
print_blob(blob, len);
|
||||||
@@ -399,7 +407,7 @@ static int erase_namespace(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int erase_wifi_manager(int argc, char **argv)
|
static int erase_network_manager(int argc, char **argv)
|
||||||
{
|
{
|
||||||
nvs_handle nvs;
|
nvs_handle nvs;
|
||||||
esp_err_t err = nvs_open("config", NVS_READWRITE, &nvs);
|
esp_err_t err = nvs_open("config", NVS_READWRITE, &nvs);
|
||||||
@@ -411,15 +419,49 @@ static int erase_wifi_manager(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
nvs_close(nvs);
|
nvs_close(nvs);
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
cmd_send_messaging(argv[0],MESSAGING_ERROR, "wifi manager configuration was not erase. %s", esp_err_to_name(err));
|
cmd_send_messaging(argv[0],MESSAGING_ERROR, "System configuration was not erased. %s", esp_err_to_name(err));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cmd_send_messaging(argv[0],MESSAGING_WARNING, "Wifi manager configuration was erased");
|
cmd_send_messaging(argv[0],MESSAGING_WARNING, "system configuration was erased. Please reboot.");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int wifi_erase_config(int argc, char **argv)
|
||||||
|
{
|
||||||
|
esp_err_t err=ESP_OK;
|
||||||
|
esp_err_t err_ap_list=ESP_OK;
|
||||||
|
bool done = false;
|
||||||
|
int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&wifi_erase_args);
|
||||||
|
if (nerrors != 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(wifi_erase_args.ap_list->count>0){
|
||||||
|
err_ap_list = network_wifi_erase_known_ap();
|
||||||
|
if (err_ap_list != ESP_OK) {
|
||||||
|
cmd_send_messaging(argv[0],MESSAGING_ERROR, "Could not erase legacy wifi configuration: %s", esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cmd_send_messaging(argv[0],MESSAGING_ERROR, "Legacy wifi configuration was erased");
|
||||||
|
}
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
if(wifi_erase_args.legacy->count>0){
|
||||||
|
err = network_wifi_erase_legacy();
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
cmd_send_messaging(argv[0],MESSAGING_ERROR, "Could not erase known ap list : %s", esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cmd_send_messaging(argv[0],MESSAGING_ERROR, "Known access point list was erased");
|
||||||
|
}
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
if(!done){
|
||||||
|
cmd_send_messaging(argv[0],MESSAGING_WARNING, "Please specify at least one configuration type to erase.", esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
return (err_ap_list==ESP_OK && err==ESP_OK)?0:1;
|
||||||
|
}
|
||||||
|
|
||||||
static int list(const char *part, const char *name, const char *str_type)
|
static int list(const char *part, const char *name, const char *str_type)
|
||||||
{
|
{
|
||||||
@@ -476,6 +518,10 @@ void register_nvs()
|
|||||||
erase_all_args.namespace = arg_str1(NULL, NULL, "<namespace>", "namespace to be erased");
|
erase_all_args.namespace = arg_str1(NULL, NULL, "<namespace>", "namespace to be erased");
|
||||||
erase_all_args.end = arg_end(2);
|
erase_all_args.end = arg_end(2);
|
||||||
|
|
||||||
|
wifi_erase_args.ap_list = arg_lit0("a","ap_list","Erases Known access points list");
|
||||||
|
wifi_erase_args.legacy = arg_lit0("l","legacy","Erases legacy access point storage");
|
||||||
|
wifi_erase_args.end = arg_end(1);
|
||||||
|
|
||||||
list_args.partition = arg_str1(NULL, NULL, "<partition>", "partition name");
|
list_args.partition = arg_str1(NULL, NULL, "<partition>", "partition name");
|
||||||
list_args.namespace = arg_str0("n", "namespace", "<namespace>", "namespace name");
|
list_args.namespace = arg_str0("n", "namespace", "<namespace>", "namespace name");
|
||||||
list_args.type = arg_str0("t", "type", "<type>", ARG_TYPE_STR);
|
list_args.type = arg_str0("t", "type", "<type>", ARG_TYPE_STR);
|
||||||
@@ -516,11 +562,19 @@ void register_nvs()
|
|||||||
.func = &erase_namespace,
|
.func = &erase_namespace,
|
||||||
.argtable = &erase_all_args
|
.argtable = &erase_all_args
|
||||||
};
|
};
|
||||||
const esp_console_cmd_t erase_wifimanager_cmd = {
|
const esp_console_cmd_t erase_config_cmd = {
|
||||||
.command = "nvs_erase_wifi_manager",
|
.command = "wifi_erase_config",
|
||||||
.help = "Erases wifi_manager's config",
|
.help = "Erases all stored access points from flash",
|
||||||
.hint = NULL,
|
.hint = NULL,
|
||||||
.func = &erase_wifi_manager,
|
.func = &wifi_erase_config,
|
||||||
|
.argtable = &wifi_erase_args
|
||||||
|
};
|
||||||
|
|
||||||
|
const esp_console_cmd_t erase_networkmanager_cmd = {
|
||||||
|
.command = "nvs_erase_configuration",
|
||||||
|
.help = "Erases system's configuration",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &erase_network_manager,
|
||||||
.argtable = NULL
|
.argtable = NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -535,12 +589,21 @@ void register_nvs()
|
|||||||
.func = &list_entries,
|
.func = &list_entries,
|
||||||
.argtable = &list_args
|
.argtable = &list_args
|
||||||
};
|
};
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("registering list_entries_cmd");
|
||||||
ESP_ERROR_CHECK(esp_console_cmd_register(&list_entries_cmd));
|
ESP_ERROR_CHECK(esp_console_cmd_register(&list_entries_cmd));
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("registering set_cmd");
|
||||||
ESP_ERROR_CHECK(esp_console_cmd_register(&set_cmd));
|
ESP_ERROR_CHECK(esp_console_cmd_register(&set_cmd));
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("registering get_cmd");
|
||||||
ESP_ERROR_CHECK(esp_console_cmd_register(&get_cmd));
|
ESP_ERROR_CHECK(esp_console_cmd_register(&get_cmd));
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("registering erase_cmd");
|
||||||
ESP_ERROR_CHECK(esp_console_cmd_register(&erase_cmd));
|
ESP_ERROR_CHECK(esp_console_cmd_register(&erase_cmd));
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("registering erase_namespace_cmd");
|
||||||
ESP_ERROR_CHECK(esp_console_cmd_register(&erase_namespace_cmd));
|
ESP_ERROR_CHECK(esp_console_cmd_register(&erase_namespace_cmd));
|
||||||
ESP_ERROR_CHECK(esp_console_cmd_register(&erase_wifimanager_cmd));
|
MEMTRACE_PRINT_DELTA_MESSAGE("registering erase_config_cmd");
|
||||||
|
ESP_ERROR_CHECK(esp_console_cmd_register(&erase_networkmanager_cmd));
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("registering erase_config_cmd");
|
||||||
|
ESP_ERROR_CHECK(esp_console_cmd_register(&erase_config_cmd));
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("Done");
|
||||||
|
|
||||||
}
|
}
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -32,21 +32,23 @@
|
|||||||
#include "messaging.h"
|
#include "messaging.h"
|
||||||
#include "platform_console.h"
|
#include "platform_console.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
#include "globdefs.h"
|
||||||
|
|
||||||
#ifdef CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS
|
#ifdef CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS
|
||||||
#pragma message("Runtime stats enabled")
|
#pragma message("Runtime stats enabled")
|
||||||
#define WITH_TASKS_INFO 1
|
#define WITH_TASKS_INFO 1
|
||||||
#else
|
#else
|
||||||
#pragma message("Runtime stats disabled")
|
#pragma message("Runtime stats disabled")
|
||||||
#endif
|
#endif
|
||||||
static struct {
|
EXT_RAM_ATTR static struct {
|
||||||
struct arg_str *scanmode;
|
struct arg_str *scanmode;
|
||||||
struct arg_end *end;
|
struct arg_end *end;
|
||||||
} wifi_parms_arg;
|
} wifi_parms_arg;
|
||||||
static struct {
|
EXT_RAM_ATTR static struct {
|
||||||
struct arg_str *name;
|
struct arg_str *name;
|
||||||
struct arg_end *end;
|
struct arg_end *end;
|
||||||
} name_args;
|
} name_args;
|
||||||
static struct {
|
EXT_RAM_ATTR static struct {
|
||||||
struct arg_lit *btspeaker;
|
struct arg_lit *btspeaker;
|
||||||
struct arg_lit *airplay;
|
struct arg_lit *airplay;
|
||||||
struct arg_str *telnet;
|
struct arg_str *telnet;
|
||||||
@@ -61,6 +63,7 @@ static const char * TAG = "cmd_system";
|
|||||||
static void register_free();
|
static void register_free();
|
||||||
static void register_setdevicename();
|
static void register_setdevicename();
|
||||||
static void register_heap();
|
static void register_heap();
|
||||||
|
static void register_dump_heap();
|
||||||
static void register_version();
|
static void register_version();
|
||||||
static void register_restart();
|
static void register_restart();
|
||||||
static void register_deep_sleep();
|
static void register_deep_sleep();
|
||||||
@@ -73,7 +76,7 @@ static void register_set_wifi_parms();
|
|||||||
#if WITH_TASKS_INFO
|
#if WITH_TASKS_INFO
|
||||||
static void register_tasks();
|
static void register_tasks();
|
||||||
#endif
|
#endif
|
||||||
extern BaseType_t wifi_manager_task;
|
extern BaseType_t network_manager_task;
|
||||||
void register_system()
|
void register_system()
|
||||||
{
|
{
|
||||||
register_set_wifi_parms();
|
register_set_wifi_parms();
|
||||||
@@ -81,6 +84,7 @@ void register_system()
|
|||||||
register_free();
|
register_free();
|
||||||
register_set_services();
|
register_set_services();
|
||||||
register_heap();
|
register_heap();
|
||||||
|
register_dump_heap();
|
||||||
register_setdevicename();
|
register_setdevicename();
|
||||||
register_version();
|
register_version();
|
||||||
register_restart();
|
register_restart();
|
||||||
@@ -297,12 +301,35 @@ static void register_free()
|
|||||||
cmd_to_json(&cmd);
|
cmd_to_json(&cmd);
|
||||||
ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
|
ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
|
||||||
}
|
}
|
||||||
|
static int dump_heap(int argc, char **argv)
|
||||||
|
{
|
||||||
|
ESP_LOGD(TAG, "Dumping heap");
|
||||||
|
heap_caps_dump_all();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
/* 'heap' command prints minumum heap size */
|
/* 'heap' command prints minumum heap size */
|
||||||
static int heap_size(int argc, char **argv)
|
static int heap_size(int argc, char **argv)
|
||||||
{
|
{
|
||||||
uint32_t heap_size = heap_caps_get_minimum_free_size(MALLOC_CAP_DEFAULT);
|
ESP_LOGI(TAG,"Heap internal:%zu (min:%zu) (largest block:%zu)\nexternal:%zu (min:%zu) (largest block:%zd)\ndma :%zu (min:%zu) (largest block:%zd)",
|
||||||
cmd_send_messaging(argv[0],MESSAGING_INFO, "min heap size: %u", heap_size);
|
heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
|
||||||
|
heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL),
|
||||||
|
heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL),
|
||||||
|
heap_caps_get_free_size(MALLOC_CAP_SPIRAM),
|
||||||
|
heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM),
|
||||||
|
heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM),
|
||||||
|
heap_caps_get_free_size(MALLOC_CAP_DMA),
|
||||||
|
heap_caps_get_minimum_free_size(MALLOC_CAP_DMA),
|
||||||
|
heap_caps_get_largest_free_block(MALLOC_CAP_DMA));
|
||||||
|
cmd_send_messaging(argv[0],MESSAGING_INFO,"Heap internal:%zu (min:%zu) (largest block:%zu)\nexternal:%zu (min:%zu) (largest block:%zd)\ndma :%zu (min:%zu) (largest block:%zd)",
|
||||||
|
heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
|
||||||
|
heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL),
|
||||||
|
heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL),
|
||||||
|
heap_caps_get_free_size(MALLOC_CAP_SPIRAM),
|
||||||
|
heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM),
|
||||||
|
heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM),
|
||||||
|
heap_caps_get_free_size(MALLOC_CAP_DMA),
|
||||||
|
heap_caps_get_minimum_free_size(MALLOC_CAP_DMA),
|
||||||
|
heap_caps_get_largest_free_block(MALLOC_CAP_DMA));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
cJSON * setdevicename_cb(){
|
cJSON * setdevicename_cb(){
|
||||||
@@ -341,10 +368,9 @@ int set_squeezelite_player_name(FILE * f,const char * name){
|
|||||||
if(nvs_config && strlen(nvs_config)>0){
|
if(nvs_config && strlen(nvs_config)>0){
|
||||||
// allocate enough memory to hold the new command line
|
// allocate enough memory to hold the new command line
|
||||||
size_t cmdLength = strlen(nvs_config) + strlen(cleaned_name) + strlen(parm) +1 ;
|
size_t cmdLength = strlen(nvs_config) + strlen(cleaned_name) + strlen(parm) +1 ;
|
||||||
newCommandLine = malloc(cmdLength);
|
newCommandLine = malloc_init_external(cmdLength);
|
||||||
memset(newCommandLine,0x00, cmdLength);
|
ESP_LOGD(TAG,"Parsing command %s",nvs_config);
|
||||||
ESP_LOGD(TAG,"Parsing command %s",nvs_config);
|
argv = (char **) malloc_init_external(22* sizeof(char *));
|
||||||
argv = (char **) calloc(22, sizeof(char *));
|
|
||||||
if (argv == NULL) {
|
if (argv == NULL) {
|
||||||
FREE_AND_NULL(nvs_config);
|
FREE_AND_NULL(nvs_config);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -400,7 +426,7 @@ static int setdevicename(int argc, char **argv)
|
|||||||
|
|
||||||
/* Check "--name" option */
|
/* Check "--name" option */
|
||||||
if (name_args.name->count) {
|
if (name_args.name->count) {
|
||||||
name=strdup(name_args.name->sval[0]);
|
name=strdup_psram(name_args.name->sval[0]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cmd_send_messaging(argv[0],MESSAGING_ERROR,"Name must be specified.");
|
cmd_send_messaging(argv[0],MESSAGING_ERROR,"Name must be specified.");
|
||||||
@@ -448,6 +474,17 @@ static void register_heap()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void register_dump_heap()
|
||||||
|
{
|
||||||
|
const esp_console_cmd_t heap_cmd = {
|
||||||
|
.command = "dump_heap",
|
||||||
|
.help = "Dumps the content of the heap to serial output",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &dump_heap,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK( esp_console_cmd_register(&heap_cmd) );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static void register_setdevicename()
|
static void register_setdevicename()
|
||||||
{
|
{
|
||||||
@@ -470,7 +507,7 @@ static void register_setdevicename()
|
|||||||
static int tasks_info(int argc, char **argv)
|
static int tasks_info(int argc, char **argv)
|
||||||
{
|
{
|
||||||
const size_t bytes_per_task = 40; /* see vTaskList description */
|
const size_t bytes_per_task = 40; /* see vTaskList description */
|
||||||
char *task_list_buffer = malloc(uxTaskGetNumberOfTasks() * bytes_per_task);
|
char *task_list_buffer = malloc_init_external(uxTaskGetNumberOfTasks() * bytes_per_task);
|
||||||
if (task_list_buffer == NULL) {
|
if (task_list_buffer == NULL) {
|
||||||
cmd_send_messaging(argv[0],MESSAGING_ERROR, "failed to allocate buffer for vTaskList output");
|
cmd_send_messaging(argv[0],MESSAGING_ERROR, "failed to allocate buffer for vTaskList output");
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -32,12 +32,12 @@
|
|||||||
#include "esp_netif.h"
|
#include "esp_netif.h"
|
||||||
#include "esp_event.h"
|
#include "esp_event.h"
|
||||||
#include "led.h"
|
#include "led.h"
|
||||||
extern bool bypass_wifi_manager;
|
extern bool bypass_network_manager;
|
||||||
#define JOIN_TIMEOUT_MS (10000)
|
#define JOIN_TIMEOUT_MS (10000)
|
||||||
#include "platform_console.h"
|
#include "platform_console.h"
|
||||||
|
|
||||||
|
|
||||||
extern EventGroupHandle_t wifi_event_group;
|
extern EventGroupHandle_t network_event_group;
|
||||||
extern const int CONNECTED_BIT;
|
extern const int CONNECTED_BIT;
|
||||||
//static const char * TAG = "cmd_wifi";
|
//static const char * TAG = "cmd_wifi";
|
||||||
/** Arguments used by 'join' function */
|
/** Arguments used by 'join' function */
|
||||||
@@ -65,10 +65,10 @@ static void event_handler(void* arg, esp_event_base_t event_base,
|
|||||||
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
||||||
led_blink_pushed(LED_GREEN, 250, 250);
|
led_blink_pushed(LED_GREEN, 250, 250);
|
||||||
esp_wifi_connect();
|
esp_wifi_connect();
|
||||||
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
|
xEventGroupClearBits(network_event_group, CONNECTED_BIT);
|
||||||
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
||||||
led_unpush(LED_GREEN);
|
led_unpush(LED_GREEN);
|
||||||
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
|
xEventGroupSetBits(network_event_group, CONNECTED_BIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//bool wait_for_wifi(){
|
//bool wait_for_wifi(){
|
||||||
@@ -127,7 +127,7 @@ static bool wifi_join(const char *ssid, const char *pass, int timeout_ms)
|
|||||||
ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
|
ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
|
||||||
ESP_ERROR_CHECK( esp_wifi_connect() );
|
ESP_ERROR_CHECK( esp_wifi_connect() );
|
||||||
|
|
||||||
int bits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
|
int bits = xEventGroupWaitBits(network_event_group, CONNECTED_BIT,
|
||||||
pdFALSE, pdTRUE, timeout_ms / portTICK_PERIOD_MS);
|
pdFALSE, pdTRUE, timeout_ms / portTICK_PERIOD_MS);
|
||||||
return (bits & CONNECTED_BIT) != 0;
|
return (bits & CONNECTED_BIT) != 0;
|
||||||
}
|
}
|
||||||
@@ -202,7 +202,7 @@ void register_wifi_join()
|
|||||||
void register_wifi()
|
void register_wifi()
|
||||||
{
|
{
|
||||||
register_wifi_join();
|
register_wifi_join();
|
||||||
if(bypass_wifi_manager){
|
if(bypass_network_manager){
|
||||||
initialise_wifi();
|
initialise_wifi();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ pthread_t thread_console;
|
|||||||
static void * console_thread();
|
static void * console_thread();
|
||||||
void console_start();
|
void console_start();
|
||||||
static const char * TAG = "console";
|
static const char * TAG = "console";
|
||||||
extern bool bypass_wifi_manager;
|
extern bool bypass_network_manager;
|
||||||
extern void register_squeezelite();
|
extern void register_squeezelite();
|
||||||
|
|
||||||
/* Prompt to be printed before each line.
|
/* Prompt to be printed before each line.
|
||||||
@@ -188,8 +188,8 @@ void process_autoexec(){
|
|||||||
uint8_t autoexec_flag=0;
|
uint8_t autoexec_flag=0;
|
||||||
|
|
||||||
char * str_flag = config_alloc_get(NVS_TYPE_STR, "autoexec");
|
char * str_flag = config_alloc_get(NVS_TYPE_STR, "autoexec");
|
||||||
if(!bypass_wifi_manager){
|
if(!bypass_network_manager){
|
||||||
ESP_LOGW(TAG, "Processing autoexec commands while wifi_manager active. Wifi related commands will be ignored.");
|
ESP_LOGW(TAG, "Processing autoexec commands while network manager active. Wifi related commands will be ignored.");
|
||||||
}
|
}
|
||||||
if(is_recovery_running){
|
if(is_recovery_running){
|
||||||
ESP_LOGD(TAG, "Processing autoexec commands in recovery mode. Squeezelite commands will be ignored.");
|
ESP_LOGD(TAG, "Processing autoexec commands in recovery mode. Squeezelite commands will be ignored.");
|
||||||
@@ -203,7 +203,7 @@ void process_autoexec(){
|
|||||||
ESP_LOGD(TAG,"Getting command name %s", autoexec_name);
|
ESP_LOGD(TAG,"Getting command name %s", autoexec_name);
|
||||||
autoexec_value= config_alloc_get(NVS_TYPE_STR, autoexec_name);
|
autoexec_value= config_alloc_get(NVS_TYPE_STR, autoexec_name);
|
||||||
if(autoexec_value!=NULL ){
|
if(autoexec_value!=NULL ){
|
||||||
if(!bypass_wifi_manager && strstr(autoexec_value, "join ")!=NULL ){
|
if(!bypass_network_manager && strstr(autoexec_value, "join ")!=NULL ){
|
||||||
ESP_LOGW(TAG,"Ignoring wifi join command.");
|
ESP_LOGW(TAG,"Ignoring wifi join command.");
|
||||||
}
|
}
|
||||||
else if(is_recovery_running && !strstr(autoexec_value, "squeezelite " ) ){
|
else if(is_recovery_running && !strstr(autoexec_value, "squeezelite " ) ){
|
||||||
@@ -298,18 +298,26 @@ void console_start() {
|
|||||||
ESP_ERROR_CHECK(esp_console_init(&console_config));
|
ESP_ERROR_CHECK(esp_console_init(&console_config));
|
||||||
}
|
}
|
||||||
/* Register commands */
|
/* Register commands */
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("Registering help command");
|
||||||
esp_console_register_help_command();
|
esp_console_register_help_command();
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("Registering system commands");
|
||||||
register_system();
|
register_system();
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("Registering config commands");
|
||||||
register_config_cmd();
|
register_config_cmd();
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("Registering nvs commands");
|
||||||
register_nvs();
|
register_nvs();
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("Registering wifi commands");
|
||||||
register_wifi();
|
register_wifi();
|
||||||
|
|
||||||
if(!is_recovery_running){
|
if(!is_recovery_running){
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("Registering squeezelite commands");
|
||||||
register_squeezelite();
|
register_squeezelite();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("Registering recovery commands");
|
||||||
register_ota_cmd();
|
register_ota_cmd();
|
||||||
}
|
}
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("Registering i2c commands");
|
||||||
register_i2ctools();
|
register_i2ctools();
|
||||||
|
|
||||||
if(!is_serial_suppressed()){
|
if(!is_serial_suppressed()){
|
||||||
@@ -358,14 +366,16 @@ void console_start() {
|
|||||||
prompt = recovery_prompt;
|
prompt = recovery_prompt;
|
||||||
cfg.stack_size = 4096 ;
|
cfg.stack_size = 4096 ;
|
||||||
}
|
}
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("Creating console thread with stack size of 4096 bytes");
|
||||||
esp_pthread_set_cfg(&cfg);
|
esp_pthread_set_cfg(&cfg);
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
|
|
||||||
pthread_create(&thread_console, &attr, console_thread, NULL);
|
pthread_create(&thread_console, &attr, console_thread, NULL);
|
||||||
pthread_attr_destroy(&attr);
|
pthread_attr_destroy(&attr);
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("Console thread created");
|
||||||
}
|
}
|
||||||
else if(!is_recovery_running){
|
else if(!is_recovery_running){
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("Running autoexec");
|
||||||
process_autoexec();
|
process_autoexec();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -392,7 +402,9 @@ esp_err_t run_command(char * line){
|
|||||||
}
|
}
|
||||||
static void * console_thread() {
|
static void * console_thread() {
|
||||||
if(!is_recovery_running){
|
if(!is_recovery_running){
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("Running autoexec");
|
||||||
process_autoexec();
|
process_autoexec();
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("Autoexec done");
|
||||||
}
|
}
|
||||||
/* Main loop */
|
/* Main loop */
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|||||||
@@ -164,6 +164,8 @@ static bool raop_sink_start(raop_cmd_vcb_t cmd_cb, raop_data_cb_t data_cb) {
|
|||||||
tcpip_adapter_if_t ifs[] = { TCPIP_ADAPTER_IF_ETH, TCPIP_ADAPTER_IF_STA, TCPIP_ADAPTER_IF_AP };
|
tcpip_adapter_if_t ifs[] = { TCPIP_ADAPTER_IF_ETH, TCPIP_ADAPTER_IF_STA, TCPIP_ADAPTER_IF_AP };
|
||||||
|
|
||||||
// get various IP info
|
// get various IP info
|
||||||
|
// it is possible to get the currently active interface with the following call:
|
||||||
|
// network_get_active_interface()
|
||||||
for (int i = 0; i < sizeof(ifs) / sizeof(tcpip_adapter_if_t); i++)
|
for (int i = 0; i < sizeof(ifs) / sizeof(tcpip_adapter_if_t); i++)
|
||||||
if (tcpip_adapter_get_ip_info(ifs[i], &ipInfo) == ESP_OK && ipInfo.ip.addr != IPADDR_ANY) {
|
if (tcpip_adapter_get_ip_info(ifs[i], &ipInfo) == ESP_OK && ipInfo.ip.addr != IPADDR_ANY) {
|
||||||
tcpip_adapter_get_hostname(ifs[i], &hostname);
|
tcpip_adapter_get_hostname(ifs[i], &hostname);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
idf_component_register(SRC_DIRS .
|
idf_component_register(SRC_DIRS .
|
||||||
INCLUDE_DIRS . ${IDF_PATH}/components/driver
|
INCLUDE_DIRS . ${IDF_PATH}/components/driver
|
||||||
REQUIRES json tools platform_config display
|
REQUIRES json tools platform_config display wifi-manager
|
||||||
PRIV_REQUIRES soc esp32 squeezelite
|
PRIV_REQUIRES soc esp32 squeezelite
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "monitor.h"
|
#include "monitor.h"
|
||||||
#include "messaging.h"
|
#include "messaging.h"
|
||||||
|
#include "network_ethernet.h"
|
||||||
|
|
||||||
|
|
||||||
static const char *TAG = "services";
|
static const char *TAG = "services";
|
||||||
@@ -62,6 +63,7 @@ static char * config_spdif_get_string(){
|
|||||||
",ws=" STR(CONFIG_SPDIF_WS_IO) ",do=" STR(CONFIG_SPDIF_DO_IO));
|
",ws=" STR(CONFIG_SPDIF_WS_IO) ",do=" STR(CONFIG_SPDIF_DO_IO));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -122,7 +124,6 @@ const i2s_platform_config_t * config_get_i2s_from_str(char * dac_config ){
|
|||||||
set_i2s_pin(dac_config, &i2s_dac_pin.pin);
|
set_i2s_pin(dac_config, &i2s_dac_pin.pin);
|
||||||
strcpy(i2s_dac_pin.model, "i2s");
|
strcpy(i2s_dac_pin.model, "i2s");
|
||||||
char * p=NULL;
|
char * p=NULL;
|
||||||
|
|
||||||
if ((p = strcasestr(dac_config, "i2c")) != NULL) i2s_dac_pin.i2c_addr = atoi(strchr(p, '=') + 1);
|
if ((p = strcasestr(dac_config, "i2c")) != NULL) i2s_dac_pin.i2c_addr = atoi(strchr(p, '=') + 1);
|
||||||
if ((p = strcasestr(dac_config, "sda")) != NULL) i2s_dac_pin.sda = atoi(strchr(p, '=') + 1);
|
if ((p = strcasestr(dac_config, "sda")) != NULL) i2s_dac_pin.sda = atoi(strchr(p, '=') + 1);
|
||||||
if ((p = strcasestr(dac_config, "scl")) != NULL) i2s_dac_pin.scl = atoi(strchr(p, '=') + 1);
|
if ((p = strcasestr(dac_config, "scl")) != NULL) i2s_dac_pin.scl = atoi(strchr(p, '=') + 1);
|
||||||
@@ -143,9 +144,8 @@ const eth_config_t * config_get_eth_from_str(char * eth_config ){
|
|||||||
char * p=NULL;
|
char * p=NULL;
|
||||||
static EXT_RAM_ATTR eth_config_t eth_pin;
|
static EXT_RAM_ATTR eth_config_t eth_pin;
|
||||||
memset(ð_pin, 0xFF, sizeof(eth_pin));
|
memset(ð_pin, 0xFF, sizeof(eth_pin));
|
||||||
memset(ð_pin.model, 0xFF, sizeof(eth_pin.model));
|
memset(ð_pin.model, 0x00, sizeof(eth_pin.model));
|
||||||
eth_pin.spi = false;
|
eth_pin.valid = true;
|
||||||
eth_pin.rmii = false;
|
|
||||||
|
|
||||||
if ((p = strcasestr(eth_config, "model")) != NULL) sscanf(p, "%*[^=]=%15[^,]", eth_pin.model);
|
if ((p = strcasestr(eth_config, "model")) != NULL) sscanf(p, "%*[^=]=%15[^,]", eth_pin.model);
|
||||||
if ((p = strcasestr(eth_config, "mdc")) != NULL) eth_pin.mdc = atoi(strchr(p, '=') + 1);
|
if ((p = strcasestr(eth_config, "mdc")) != NULL) eth_pin.mdc = atoi(strchr(p, '=') + 1);
|
||||||
@@ -158,15 +158,32 @@ const eth_config_t * config_get_eth_from_str(char * eth_config ){
|
|||||||
if ((p = strcasestr(eth_config, "speed")) != NULL) eth_pin.speed = atoi(strchr(p, '=') + 1);
|
if ((p = strcasestr(eth_config, "speed")) != NULL) eth_pin.speed = atoi(strchr(p, '=') + 1);
|
||||||
if ((p = strcasestr(eth_config, "clk")) != NULL) eth_pin.clk = atoi(strchr(p, '=') + 1);
|
if ((p = strcasestr(eth_config, "clk")) != NULL) eth_pin.clk = atoi(strchr(p, '=') + 1);
|
||||||
if ((p = strcasestr(eth_config, "host")) != NULL) eth_pin.host = atoi(strchr(p, '=') + 1);
|
if ((p = strcasestr(eth_config, "host")) != NULL) eth_pin.host = atoi(strchr(p, '=') + 1);
|
||||||
eth_pin.valid = eth_pin.model && strlen(eth_pin.model)>0 && GPIO_IS_VALID_GPIO(eth_pin.mdio) && GPIO_IS_VALID_GPIO(eth_pin.mdc);
|
|
||||||
|
if(!eth_pin.model || strlen(eth_pin.model)==0){
|
||||||
if(strcasestr(eth_pin.model, "LAN8720")){
|
eth_pin.valid = false;
|
||||||
eth_pin.rmii = true;
|
return ð_pin;
|
||||||
}
|
}
|
||||||
else {
|
network_ethernet_driver_t* network_driver = network_ethernet_driver_autodetect(eth_pin.model);
|
||||||
eth_pin.spi = true;
|
if(!network_driver || !network_driver->valid){
|
||||||
/* here we must also check that we have at least a CS gpio */
|
messaging_post_message(MESSAGING_ERROR,MESSAGING_CLASS_SYSTEM,"Ethernet config invalid: model %s %s",eth_pin.model,network_driver?"was not compiled in":"was not found");
|
||||||
eth_pin.valid = eth_pin.valid && GPIO_IS_VALID_GPIO(eth_pin.cs);
|
eth_pin.valid = false;
|
||||||
|
}
|
||||||
|
if(network_driver){
|
||||||
|
eth_pin.rmii = network_driver->rmii;
|
||||||
|
eth_pin.spi = network_driver->spi;
|
||||||
|
|
||||||
|
if(network_driver->rmii){
|
||||||
|
if(!GPIO_IS_VALID_GPIO(eth_pin.mdio) || !GPIO_IS_VALID_GPIO(eth_pin.mdc)){
|
||||||
|
messaging_post_message(MESSAGING_ERROR,MESSAGING_CLASS_SYSTEM,"Ethernet config invalid: %s %s",!GPIO_IS_VALID_GPIO(eth_pin.mdc)?"Invalid MDC":"",!GPIO_IS_VALID_GPIO(eth_pin.mdio)?"Invalid mdio":"");
|
||||||
|
eth_pin.valid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(network_driver->spi){
|
||||||
|
if(!GPIO_IS_VALID_GPIO(eth_pin.cs)){
|
||||||
|
messaging_post_message(MESSAGING_ERROR,MESSAGING_CLASS_SYSTEM,"Ethernet config invalid: invalid CS pin");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ð_pin;
|
return ð_pin;
|
||||||
}
|
}
|
||||||
@@ -216,10 +233,12 @@ const eth_config_t * config_eth_get( ){
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
",mdc=" STR(CONFIG_ETH_MDC_IO) ",mdio=" STR(CONFIG_ETH_MDIO_IO)) ;
|
",mdc=" STR(CONFIG_ETH_MDC_IO) ",mdio=" STR(CONFIG_ETH_MDIO_IO)) ;
|
||||||
|
if(config && strlen(config)>0){
|
||||||
|
ESP_LOGD(TAG,"Parsing ethernet configuration %s", config);
|
||||||
|
}
|
||||||
static EXT_RAM_ATTR eth_config_t eth_config;
|
static EXT_RAM_ATTR eth_config_t eth_config;
|
||||||
ESP_LOGD(TAG, "Ethernet config string %s", config);
|
|
||||||
memcpy(ð_config, config_get_eth_from_str(config), sizeof(eth_config));
|
memcpy(ð_config, config_get_eth_from_str(config), sizeof(eth_config));
|
||||||
free(config);
|
FREE_AND_NULL(config);
|
||||||
return ð_config;
|
return ð_config;
|
||||||
}
|
}
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
@@ -236,7 +255,7 @@ void config_eth_init( eth_config_t * target ){
|
|||||||
esp_err_t config_i2c_set(const i2c_config_t * config, int port){
|
esp_err_t config_i2c_set(const i2c_config_t * config, int port){
|
||||||
int buffer_size=255;
|
int buffer_size=255;
|
||||||
esp_err_t err=ESP_OK;
|
esp_err_t err=ESP_OK;
|
||||||
char * config_buffer=calloc(buffer_size,1);
|
char * config_buffer=malloc_init_external(buffer_size);
|
||||||
if(config_buffer) {
|
if(config_buffer) {
|
||||||
snprintf(config_buffer,buffer_size,"scl=%u,sda=%u,speed=%u,port=%u",config->scl_io_num,config->sda_io_num,config->master.clk_speed,port);
|
snprintf(config_buffer,buffer_size,"scl=%u,sda=%u,speed=%u,port=%u",config->scl_io_num,config->sda_io_num,config->master.clk_speed,port);
|
||||||
log_send_messaging(MESSAGING_INFO,"Updating I2C configuration to %s",config_buffer);
|
log_send_messaging(MESSAGING_INFO,"Updating I2C configuration to %s",config_buffer);
|
||||||
@@ -255,8 +274,8 @@ esp_err_t config_i2c_set(const i2c_config_t * config, int port){
|
|||||||
esp_err_t config_rotary_set(rotary_struct_t * config){
|
esp_err_t config_rotary_set(rotary_struct_t * config){
|
||||||
int buffer_size=512;
|
int buffer_size=512;
|
||||||
esp_err_t err=ESP_OK;
|
esp_err_t err=ESP_OK;
|
||||||
char * config_buffer=calloc(buffer_size,1);
|
char * config_buffer=malloc_init_external(buffer_size);
|
||||||
char * config_buffer2=calloc(buffer_size,1);
|
char * config_buffer2=malloc_init_external(buffer_size);
|
||||||
if(config_buffer && config_buffer2) {
|
if(config_buffer && config_buffer2) {
|
||||||
snprintf(config_buffer,buffer_size,"A=%i,B=%i",config->A, config->B);
|
snprintf(config_buffer,buffer_size,"A=%i,B=%i",config->A, config->B);
|
||||||
if(config->SW >=0 ){
|
if(config->SW >=0 ){
|
||||||
@@ -296,8 +315,8 @@ esp_err_t config_rotary_set(rotary_struct_t * config){
|
|||||||
esp_err_t config_display_set(const display_config_t * config){
|
esp_err_t config_display_set(const display_config_t * config){
|
||||||
int buffer_size=512;
|
int buffer_size=512;
|
||||||
esp_err_t err=ESP_OK;
|
esp_err_t err=ESP_OK;
|
||||||
char * config_buffer=calloc(buffer_size,1);
|
char * config_buffer=malloc_init_external(buffer_size);
|
||||||
char * config_buffer2=calloc(buffer_size,1);
|
char * config_buffer2=malloc_init_external(buffer_size);
|
||||||
if(config_buffer && config_buffer2) {
|
if(config_buffer && config_buffer2) {
|
||||||
snprintf(config_buffer,buffer_size,"%s,width=%i,height=%i",config->type,config->width,config->height);
|
snprintf(config_buffer,buffer_size,"%s,width=%i,height=%i",config->type,config->width,config->height);
|
||||||
if(strcasecmp("I2C",config->type)==0){
|
if(strcasecmp("I2C",config->type)==0){
|
||||||
@@ -348,8 +367,8 @@ esp_err_t config_display_set(const display_config_t * config){
|
|||||||
esp_err_t config_i2s_set(const i2s_platform_config_t * config, const char * nvs_name){
|
esp_err_t config_i2s_set(const i2s_platform_config_t * config, const char * nvs_name){
|
||||||
int buffer_size=255;
|
int buffer_size=255;
|
||||||
esp_err_t err=ESP_OK;
|
esp_err_t err=ESP_OK;
|
||||||
char * config_buffer=calloc(buffer_size,1);
|
char * config_buffer=malloc_init_external(buffer_size);
|
||||||
char * config_buffer2=calloc(buffer_size,1);
|
char * config_buffer2=malloc_init_external(buffer_size);
|
||||||
if(config_buffer && config_buffer2) {
|
if(config_buffer && config_buffer2) {
|
||||||
snprintf(config_buffer,buffer_size,"model=%s,bck=%u,ws=%u,do=%u",config->model,config->pin.bck_io_num,config->pin.ws_io_num,config->pin.data_out_num);
|
snprintf(config_buffer,buffer_size,"model=%s,bck=%u,ws=%u,do=%u",config->model,config->pin.bck_io_num,config->pin.ws_io_num,config->pin.data_out_num);
|
||||||
if(config->mute_gpio>=0){
|
if(config->mute_gpio>=0){
|
||||||
@@ -384,7 +403,7 @@ esp_err_t config_i2s_set(const i2s_platform_config_t * config, const char * nvs_
|
|||||||
esp_err_t config_spdif_set(const i2s_platform_config_t * config){
|
esp_err_t config_spdif_set(const i2s_platform_config_t * config){
|
||||||
int buffer_size=255;
|
int buffer_size=255;
|
||||||
esp_err_t err=ESP_OK;
|
esp_err_t err=ESP_OK;
|
||||||
char * config_buffer=calloc(buffer_size,1);
|
char * config_buffer=malloc_init_external(buffer_size);
|
||||||
if(config_buffer ) {
|
if(config_buffer ) {
|
||||||
snprintf(config_buffer,buffer_size,"bck=%u,ws=%u,do=%u",config->pin.bck_io_num,config->pin.ws_io_num,config->pin.data_out_num);
|
snprintf(config_buffer,buffer_size,"bck=%u,ws=%u,do=%u",config->pin.bck_io_num,config->pin.ws_io_num,config->pin.data_out_num);
|
||||||
log_send_messaging(MESSAGING_INFO,"Updating SPDIF configuration to %s",config_buffer);
|
log_send_messaging(MESSAGING_INFO,"Updating SPDIF configuration to %s",config_buffer);
|
||||||
@@ -406,7 +425,7 @@ esp_err_t config_spdif_set(const i2s_platform_config_t * config){
|
|||||||
esp_err_t config_spi_set(const spi_bus_config_t * config, int host, int dc){
|
esp_err_t config_spi_set(const spi_bus_config_t * config, int host, int dc){
|
||||||
int buffer_size=255;
|
int buffer_size=255;
|
||||||
esp_err_t err = ESP_OK;
|
esp_err_t err = ESP_OK;
|
||||||
char * config_buffer=calloc(buffer_size,1);
|
char * config_buffer=malloc_init_external(buffer_size);
|
||||||
if(config_buffer) {
|
if(config_buffer) {
|
||||||
snprintf(config_buffer,buffer_size,"data=%u,clk=%u,dc=%u,host=%u,miso=%d",config->mosi_io_num,config->sclk_io_num,dc,host,config->miso_io_num);
|
snprintf(config_buffer,buffer_size,"data=%u,clk=%u,dc=%u,host=%u,miso=%d",config->mosi_io_num,config->sclk_io_num,dc,host,config->miso_io_num);
|
||||||
log_send_messaging(MESSAGING_INFO,"Updating SPI configuration to %s",config_buffer);
|
log_send_messaging(MESSAGING_INFO,"Updating SPI configuration to %s",config_buffer);
|
||||||
@@ -855,7 +874,7 @@ cJSON * get_Rotary_GPIO(cJSON * list){
|
|||||||
*/
|
*/
|
||||||
esp_err_t get_gpio_structure(cJSON * gpio_entry, gpio_entry_t ** gpio){
|
esp_err_t get_gpio_structure(cJSON * gpio_entry, gpio_entry_t ** gpio){
|
||||||
esp_err_t err = ESP_OK;
|
esp_err_t err = ESP_OK;
|
||||||
*gpio = malloc(sizeof(gpio_entry_t));
|
*gpio = malloc_init_external(sizeof(gpio_entry_t));
|
||||||
cJSON * val = cJSON_GetObjectItem(gpio_entry,"gpio");
|
cJSON * val = cJSON_GetObjectItem(gpio_entry,"gpio");
|
||||||
if(val){
|
if(val){
|
||||||
(*gpio)->gpio= (int)val->valuedouble;
|
(*gpio)->gpio= (int)val->valuedouble;
|
||||||
@@ -865,14 +884,14 @@ esp_err_t get_gpio_structure(cJSON * gpio_entry, gpio_entry_t ** gpio){
|
|||||||
}
|
}
|
||||||
val = cJSON_GetObjectItem(gpio_entry,"name");
|
val = cJSON_GetObjectItem(gpio_entry,"name");
|
||||||
if(val){
|
if(val){
|
||||||
(*gpio)->name= strdup(cJSON_GetStringValue(val));
|
(*gpio)->name= strdup_psram(cJSON_GetStringValue(val));
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGE(TAG,"gpio name value not found");
|
ESP_LOGE(TAG,"gpio name value not found");
|
||||||
err=ESP_FAIL;
|
err=ESP_FAIL;
|
||||||
}
|
}
|
||||||
val = cJSON_GetObjectItem(gpio_entry,"group");
|
val = cJSON_GetObjectItem(gpio_entry,"group");
|
||||||
if(val){
|
if(val){
|
||||||
(*gpio)->group= strdup(cJSON_GetStringValue(val));
|
(*gpio)->group= strdup_psram(cJSON_GetStringValue(val));
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGE(TAG,"gpio group value not found");
|
ESP_LOGE(TAG,"gpio group value not found");
|
||||||
err=ESP_FAIL;
|
err=ESP_FAIL;
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
#include "driver/i2c.h"
|
#include "driver/i2c.h"
|
||||||
#include "driver/i2s.h"
|
#include "driver/i2s.h"
|
||||||
#include "driver/spi_master.h"
|
#include "driver/spi_master.h"
|
||||||
|
#include "freertos/queue.h"
|
||||||
|
|
||||||
extern const char *i2c_name_type;
|
extern const char *i2c_name_type;
|
||||||
extern const char *spi_name_type;
|
extern const char *spi_name_type;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -30,7 +32,7 @@ typedef struct {
|
|||||||
bool rotate;
|
bool rotate;
|
||||||
} display_config_t;
|
} display_config_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct eth_config_struct {
|
||||||
char model[16];
|
char model[16];
|
||||||
bool valid;
|
bool valid;
|
||||||
bool rmii;
|
bool rmii;
|
||||||
@@ -98,6 +100,7 @@ const spi_bus_config_t * config_spi_get(spi_host_device_t * spi_host);
|
|||||||
void parse_set_GPIO(void (*cb)(int gpio, char *value));
|
void parse_set_GPIO(void (*cb)(int gpio, char *value));
|
||||||
const i2s_platform_config_t * config_dac_get();
|
const i2s_platform_config_t * config_dac_get();
|
||||||
const i2s_platform_config_t * config_spdif_get( );
|
const i2s_platform_config_t * config_spdif_get( );
|
||||||
|
const i2s_platform_config_t * config_get_i2s_from_str(char * dac_config );
|
||||||
esp_err_t config_spdif_set(const i2s_platform_config_t * config);
|
esp_err_t config_spdif_set(const i2s_platform_config_t * config);
|
||||||
bool is_spdif_config_locked();
|
bool is_spdif_config_locked();
|
||||||
esp_err_t free_gpio_entry( gpio_entry_t ** gpio);
|
esp_err_t free_gpio_entry( gpio_entry_t ** gpio);
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ typedef struct {
|
|||||||
int timer, base_channel, max;
|
int timer, base_channel, max;
|
||||||
} pwm_system_t;
|
} pwm_system_t;
|
||||||
extern pwm_system_t pwm_system;
|
extern pwm_system_t pwm_system;
|
||||||
|
|
||||||
#ifdef CONFIG_SQUEEZEAMP
|
#ifdef CONFIG_SQUEEZEAMP
|
||||||
#define ADAC dac_tas57xx
|
#define ADAC dac_tas57xx
|
||||||
#elif defined(CONFIG_A1S)
|
#elif defined(CONFIG_A1S)
|
||||||
@@ -29,3 +28,6 @@ extern pwm_system_t pwm_system;
|
|||||||
#else
|
#else
|
||||||
#define ADAC dac_external
|
#define ADAC dac_external
|
||||||
#endif
|
#endif
|
||||||
|
void * malloc_init_external(size_t sz);
|
||||||
|
void * clone_obj_psram(void * source, size_t source_sz);
|
||||||
|
char * strdup_psram(const char * source);
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "platform_esp32.h"
|
#include "platform_esp32.h"
|
||||||
#include "messaging.h"
|
#include "messaging.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
#include "globdefs.h"
|
||||||
/************************************
|
/************************************
|
||||||
* Globals
|
* Globals
|
||||||
*/
|
*/
|
||||||
@@ -38,7 +39,7 @@ messaging_handle_t get_handle_ptr(messaging_list_t * handle){
|
|||||||
|
|
||||||
RingbufHandle_t messaging_create_ring_buffer(uint8_t max_count){
|
RingbufHandle_t messaging_create_ring_buffer(uint8_t max_count){
|
||||||
RingbufHandle_t buf_handle = NULL;
|
RingbufHandle_t buf_handle = NULL;
|
||||||
StaticRingbuffer_t *buffer_struct = malloc(sizeof(StaticRingbuffer_t));
|
StaticRingbuffer_t *buffer_struct = malloc_init_external(sizeof(StaticRingbuffer_t));
|
||||||
if (buffer_struct != NULL) {
|
if (buffer_struct != NULL) {
|
||||||
size_t buf_size = (size_t )(sizeof(single_message_t)+8+MSG_LENGTH_AVG)*(size_t )(max_count>0?max_count:5); // no-split buffer requires an additional 8 bytes
|
size_t buf_size = (size_t )(sizeof(single_message_t)+8+MSG_LENGTH_AVG)*(size_t )(max_count>0?max_count:5); // no-split buffer requires an additional 8 bytes
|
||||||
buf_size = buf_size - (buf_size % 4);
|
buf_size = buf_size - (buf_size % 4);
|
||||||
@@ -76,7 +77,7 @@ messaging_handle_t messaging_register_subscriber(uint8_t max_count, char * name)
|
|||||||
while(cur->next){
|
while(cur->next){
|
||||||
cur = get_struct_ptr(cur->next);
|
cur = get_struct_ptr(cur->next);
|
||||||
}
|
}
|
||||||
cur->next=heap_caps_malloc(sizeof(messaging_list_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
cur->next=malloc_init_external(sizeof(messaging_list_t));
|
||||||
if(!cur->next){
|
if(!cur->next){
|
||||||
ESP_LOGE(tag,"subscriber alloc failed");
|
ESP_LOGE(tag,"subscriber alloc failed");
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -84,7 +85,7 @@ messaging_handle_t messaging_register_subscriber(uint8_t max_count, char * name)
|
|||||||
memset(cur->next,0x00,sizeof(messaging_list_t));
|
memset(cur->next,0x00,sizeof(messaging_list_t));
|
||||||
cur = get_struct_ptr(cur->next);
|
cur = get_struct_ptr(cur->next);
|
||||||
cur->max_count=max_count;
|
cur->max_count=max_count;
|
||||||
cur->subscriber_name=strdup(name);
|
cur->subscriber_name=strdup_psram(name);
|
||||||
cur->buf_handle = messaging_create_ring_buffer(max_count);
|
cur->buf_handle = messaging_create_ring_buffer(max_count);
|
||||||
if(cur->buf_handle){
|
if(cur->buf_handle){
|
||||||
messaging_fill_messages(cur);
|
messaging_fill_messages(cur);
|
||||||
@@ -99,7 +100,7 @@ void messaging_service_init(){
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
top.max_count = max_count;
|
top.max_count = max_count;
|
||||||
top.subscriber_name = strdup("messaging");
|
top.subscriber_name = strdup_psram("messaging");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -161,10 +162,7 @@ single_message_t * messaging_retrieve_message(RingbufHandle_t buf_handle){
|
|||||||
vRingbufferGetInfo(buf_handle, NULL, NULL, NULL, NULL, &uxItemsWaiting);
|
vRingbufferGetInfo(buf_handle, NULL, NULL, NULL, NULL, &uxItemsWaiting);
|
||||||
if(uxItemsWaiting>0){
|
if(uxItemsWaiting>0){
|
||||||
message = (single_message_t *)xRingbufferReceive(buf_handle, &item_size, pdMS_TO_TICKS(50));
|
message = (single_message_t *)xRingbufferReceive(buf_handle, &item_size, pdMS_TO_TICKS(50));
|
||||||
message_copy = heap_caps_malloc(item_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
message_copy = clone_obj_psram(message,item_size);
|
||||||
if(message_copy){
|
|
||||||
memcpy(message_copy,message,item_size);
|
|
||||||
}
|
|
||||||
vRingbufferReturnItem(buf_handle, (void *)message);
|
vRingbufferReturnItem(buf_handle, (void *)message);
|
||||||
}
|
}
|
||||||
return message_copy;
|
return message_copy;
|
||||||
@@ -231,7 +229,7 @@ void messaging_post_message(messaging_types type,messaging_classes msg_class, co
|
|||||||
va_start(va, fmt);
|
va_start(va, fmt);
|
||||||
ln = vsnprintf(NULL, 0, fmt, va)+1;
|
ln = vsnprintf(NULL, 0, fmt, va)+1;
|
||||||
msg_size = sizeof(single_message_t)+ln;
|
msg_size = sizeof(single_message_t)+ln;
|
||||||
message = (single_message_t *)heap_caps_malloc(msg_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
message = (single_message_t *)malloc_init_external(msg_size);
|
||||||
vsprintf(message->message, fmt, va);
|
vsprintf(message->message, fmt, va);
|
||||||
va_end(va);
|
va_end(va);
|
||||||
message->msg_size = msg_size;
|
message->msg_size = msg_size;
|
||||||
@@ -256,11 +254,25 @@ void messaging_post_message(messaging_types type,messaging_classes msg_class, co
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
char * messaging_alloc_format_string(const char *fmt, ...) {
|
||||||
|
va_list va;
|
||||||
|
va_start(va, fmt);
|
||||||
|
size_t ln = vsnprintf(NULL, 0, fmt, va)+1;
|
||||||
|
char * message_txt = malloc_init_external(ln);
|
||||||
|
if(message_txt){
|
||||||
|
vsprintf(message_txt, fmt, va);
|
||||||
|
va_end(va);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
ESP_LOGE(tag, "Memory allocation failed while sending message");
|
||||||
|
}
|
||||||
|
return message_txt;
|
||||||
|
}
|
||||||
void log_send_messaging(messaging_types msgtype,const char *fmt, ...) {
|
void log_send_messaging(messaging_types msgtype,const char *fmt, ...) {
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start(va, fmt);
|
va_start(va, fmt);
|
||||||
size_t ln = vsnprintf(NULL, 0, fmt, va)+1;
|
size_t ln = vsnprintf(NULL, 0, fmt, va)+1;
|
||||||
char * message_txt = malloc(ln);
|
char * message_txt = malloc_init_external(ln);
|
||||||
if(message_txt){
|
if(message_txt){
|
||||||
vsprintf(message_txt, fmt, va);
|
vsprintf(message_txt, fmt, va);
|
||||||
va_end(va);
|
va_end(va);
|
||||||
@@ -272,12 +284,13 @@ void log_send_messaging(messaging_types msgtype,const char *fmt, ...) {
|
|||||||
ESP_LOGE(tag, "Memory allocation failed while sending message");
|
ESP_LOGE(tag, "Memory allocation failed while sending message");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmd_send_messaging(const char * cmdname,messaging_types msgtype, const char *fmt, ...){
|
void cmd_send_messaging(const char * cmdname,messaging_types msgtype, const char *fmt, ...){
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start(va, fmt);
|
va_start(va, fmt);
|
||||||
size_t cmd_len = strlen(cmdname)+1;
|
size_t cmd_len = strlen(cmdname)+1;
|
||||||
size_t ln = vsnprintf(NULL, 0, fmt, va)+1;
|
size_t ln = vsnprintf(NULL, 0, fmt, va)+1;
|
||||||
char * message_txt = malloc(ln+cmd_len);
|
char * message_txt = malloc_init_external(ln+cmd_len);
|
||||||
if(message_txt){
|
if(message_txt){
|
||||||
strcpy(message_txt,cmdname);
|
strcpy(message_txt,cmdname);
|
||||||
strcat(message_txt,"\n");
|
strcat(message_txt,"\n");
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ single_message_t * messaging_retrieve_message(RingbufHandle_t buf_handle);
|
|||||||
void log_send_messaging(messaging_types msgtype,const char *fmt, ...);
|
void log_send_messaging(messaging_types msgtype,const char *fmt, ...);
|
||||||
void cmd_send_messaging(const char * cmdname,messaging_types msgtype, const char *fmt, ...);
|
void cmd_send_messaging(const char * cmdname,messaging_types msgtype, const char *fmt, ...);
|
||||||
esp_err_t messaging_type_to_err_type(messaging_types type);
|
esp_err_t messaging_type_to_err_type(messaging_types type);
|
||||||
|
char * messaging_alloc_format_string(const char *fmt, ...) ;
|
||||||
void messaging_service_init();
|
void messaging_service_init();
|
||||||
|
|
||||||
#define REALLOC_CAT(e,n) e=realloc(e,strlen(n)); e=strcat(e,n)
|
#define REALLOC_CAT(e,n) e=realloc(e,strlen(n)); e=strcat(e,n)
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ static void task_stats( cJSON* top ) {
|
|||||||
} current, previous;
|
} current, previous;
|
||||||
cJSON * tlist=cJSON_CreateArray();
|
cJSON * tlist=cJSON_CreateArray();
|
||||||
current.n = uxTaskGetNumberOfTasks();
|
current.n = uxTaskGetNumberOfTasks();
|
||||||
current.tasks = malloc( current.n * sizeof( TaskStatus_t ) );
|
current.tasks = malloc_init_external( current.n * sizeof( TaskStatus_t ) );
|
||||||
current.n = uxTaskGetSystemState( current.tasks, current.n, ¤t.total );
|
current.n = uxTaskGetSystemState( current.tasks, current.n, ¤t.total );
|
||||||
cJSON_AddNumberToObject(top,"ntasks",current.n);
|
cJSON_AddNumberToObject(top,"ntasks",current.n);
|
||||||
|
|
||||||
@@ -126,11 +126,13 @@ static void monitor_callback(TimerHandle_t xTimer) {
|
|||||||
cJSON_AddNumberToObject(top,"free_spiram",heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
|
cJSON_AddNumberToObject(top,"free_spiram",heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
|
||||||
cJSON_AddNumberToObject(top,"min_free_spiram",heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM));
|
cJSON_AddNumberToObject(top,"min_free_spiram",heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM));
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Heap internal:%zu (min:%zu) external:%zu (min:%zu)",
|
ESP_LOGI(TAG, "Heap internal:%zu (min:%zu) external:%zu (min:%zu) dma:%zu (min:%zu)",
|
||||||
heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
|
heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
|
||||||
heap_caps_get_minimum_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_free_size(MALLOC_CAP_SPIRAM),
|
||||||
heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM));
|
heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM),
|
||||||
|
heap_caps_get_free_size(MALLOC_CAP_DMA),
|
||||||
|
heap_caps_get_minimum_free_size(MALLOC_CAP_DMA));
|
||||||
|
|
||||||
task_stats(top);
|
task_stats(top);
|
||||||
char * top_a= cJSON_PrintUnformatted(top);
|
char * top_a= cJSON_PrintUnformatted(top);
|
||||||
@@ -248,11 +250,13 @@ void monitor_svc_init(void) {
|
|||||||
}
|
}
|
||||||
FREE_AND_NULL(p);
|
FREE_AND_NULL(p);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Heap internal:%zu (min:%zu) external:%zu (min:%zu)",
|
ESP_LOGI(TAG, "Heap internal:%zu (min:%zu) external:%zu (min:%zu) dma:%zu (min:%zu)",
|
||||||
heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
|
heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
|
||||||
heap_caps_get_minimum_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_free_size(MALLOC_CAP_SPIRAM),
|
||||||
heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM));
|
heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM),
|
||||||
|
heap_caps_get_free_size(MALLOC_CAP_DMA),
|
||||||
|
heap_caps_get_minimum_free_size(MALLOC_CAP_DMA));
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
|
|||||||
@@ -18,6 +18,9 @@
|
|||||||
#include "globdefs.h"
|
#include "globdefs.h"
|
||||||
#include "accessors.h"
|
#include "accessors.h"
|
||||||
#include "messaging.h"
|
#include "messaging.h"
|
||||||
|
#include "esp_heap_caps.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
|
||||||
extern void battery_svc_init(void);
|
extern void battery_svc_init(void);
|
||||||
extern void monitor_svc_init(void);
|
extern void monitor_svc_init(void);
|
||||||
@@ -35,6 +38,43 @@ pwm_system_t pwm_system = {
|
|||||||
|
|
||||||
static const char *TAG = "services";
|
static const char *TAG = "services";
|
||||||
|
|
||||||
|
|
||||||
|
void * malloc_init_external(size_t sz){
|
||||||
|
void * ptr=NULL;
|
||||||
|
ptr = heap_caps_malloc(sz, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||||
|
if(ptr==NULL){
|
||||||
|
ESP_LOGE(TAG,"malloc_init_external: unable to allocate %d bytes of PSRAM!",sz);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memset(ptr,0x00,sz);
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
void * clone_obj_psram(void * source, size_t source_sz){
|
||||||
|
void * ptr=NULL;
|
||||||
|
ptr = heap_caps_malloc(source_sz, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||||
|
if(ptr==NULL){
|
||||||
|
ESP_LOGE(TAG,"clone_obj_psram: unable to allocate %d bytes of PSRAM!",source_sz);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memcpy(ptr,source,source_sz);
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
char * strdup_psram(const char * source){
|
||||||
|
void * ptr=NULL;
|
||||||
|
size_t source_sz = strlen(source)+1;
|
||||||
|
ptr = heap_caps_malloc(source_sz, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||||
|
if(ptr==NULL){
|
||||||
|
ESP_LOGE(TAG,"strdup_psram: unable to allocate %d bytes of PSRAM! Cannot clone string %s",source_sz,source);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memset(ptr,0x00,source_sz);
|
||||||
|
strcpy(ptr,source);
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
#include "gds_draw.h"
|
#include "gds_draw.h"
|
||||||
#include "platform_esp32.h"
|
#include "platform_esp32.h"
|
||||||
#include "lwip/sockets.h"
|
#include "lwip/sockets.h"
|
||||||
|
#include "globdefs.h"
|
||||||
|
|
||||||
extern const char * get_certificate();
|
extern const char * get_certificate();
|
||||||
#define IF_DISPLAY(x) if(display) { x; }
|
#define IF_DISPLAY(x) if(display) { x; }
|
||||||
@@ -95,11 +95,13 @@ static esp_http_client_config_t http_client_config;
|
|||||||
|
|
||||||
|
|
||||||
void _printMemStats(){
|
void _printMemStats(){
|
||||||
ESP_LOGD(TAG,"Heap internal:%zu (min:%zu) external:%zu (min:%zu)",
|
ESP_LOGD(TAG, "Heap internal:%zu (min:%zu) external:%zu (min:%zu) dma:%zu (min:%zu)",
|
||||||
heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
|
heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
|
||||||
heap_caps_get_minimum_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_free_size(MALLOC_CAP_SPIRAM),
|
||||||
heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM));
|
heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM),
|
||||||
|
heap_caps_get_free_size(MALLOC_CAP_DMA),
|
||||||
|
heap_caps_get_minimum_free_size(MALLOC_CAP_DMA));
|
||||||
}
|
}
|
||||||
uint8_t ota_get_pct_complete(){
|
uint8_t ota_get_pct_complete(){
|
||||||
return ota_status->total_image_len==0?0:
|
return ota_status->total_image_len==0?0:
|
||||||
@@ -183,7 +185,7 @@ void sendMessaging(messaging_types type,const char * fmt, ...){
|
|||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
str_len = vsnprintf(NULL,0,fmt,args)+1;
|
str_len = vsnprintf(NULL,0,fmt,args)+1;
|
||||||
if(str_len>0){
|
if(str_len>0){
|
||||||
msg_str = malloc(str_len);
|
msg_str = malloc_init_external(str_len);
|
||||||
vsnprintf(msg_str,str_len,fmt,args);
|
vsnprintf(msg_str,str_len,fmt,args);
|
||||||
if(type == MESSAGING_WARNING){
|
if(type == MESSAGING_WARNING){
|
||||||
ESP_LOGW(TAG,"%s",msg_str);
|
ESP_LOGW(TAG,"%s",msg_str);
|
||||||
@@ -237,7 +239,7 @@ esp_err_t handle_http_on_data(esp_http_client_event_t *evt){
|
|||||||
ota_status->total_image_len=esp_http_client_get_content_length(evt->client);
|
ota_status->total_image_len=esp_http_client_get_content_length(evt->client);
|
||||||
ota_status->downloaded_image_len = 0;
|
ota_status->downloaded_image_len = 0;
|
||||||
ota_status->newdownloadpct = 0;
|
ota_status->newdownloadpct = 0;
|
||||||
ota_status->bin_data= malloc(ota_status->total_image_len);
|
ota_status->bin_data= malloc_init_external(ota_status->total_image_len);
|
||||||
if(ota_status->bin_data==NULL){
|
if(ota_status->bin_data==NULL){
|
||||||
sendMessaging(MESSAGING_ERROR,"Error: buffer alloc error");
|
sendMessaging(MESSAGING_ERROR,"Error: buffer alloc error");
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
@@ -351,7 +353,7 @@ esp_err_t init_config(ota_thread_parms_t * p_ota_thread_parms){
|
|||||||
http_client_config.event_handler = _http_event_handler;
|
http_client_config.event_handler = _http_event_handler;
|
||||||
http_client_config.disable_auto_redirect=false;
|
http_client_config.disable_auto_redirect=false;
|
||||||
http_client_config.skip_cert_common_name_check = false;
|
http_client_config.skip_cert_common_name_check = false;
|
||||||
http_client_config.url = strdup(p_ota_thread_parms->url);
|
http_client_config.url = strdup_psram(p_ota_thread_parms->url);
|
||||||
http_client_config.max_redirection_count = 4;
|
http_client_config.max_redirection_count = 4;
|
||||||
// buffer size below is for http read chunks
|
// buffer size below is for http read chunks
|
||||||
http_client_config.buffer_size = 8192; //1024 ;
|
http_client_config.buffer_size = 8192; //1024 ;
|
||||||
@@ -680,12 +682,11 @@ esp_err_t process_recovery_ota(const char * bin_url, char * bin_buffer, uint32_t
|
|||||||
ESP_LOGE(TAG,"OTA Already started. ");
|
ESP_LOGE(TAG,"OTA Already started. ");
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
ota_status = heap_caps_malloc(sizeof(ota_status_t) , (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT));
|
ota_status = malloc_init_external(sizeof(ota_status_t));
|
||||||
memset(ota_status, 0x00, sizeof(ota_status_t));
|
|
||||||
ota_status->bOTAThreadStarted=true;
|
ota_status->bOTAThreadStarted=true;
|
||||||
|
|
||||||
if(bin_url){
|
if(bin_url){
|
||||||
ota_thread_parms.url =strdup(bin_url);
|
ota_thread_parms.url =strdup_psram(bin_url);
|
||||||
ESP_LOGD(TAG, "Starting ota on core %u for : %s", OTA_CORE,ota_thread_parms.url);
|
ESP_LOGD(TAG, "Starting ota on core %u for : %s", OTA_CORE,ota_thread_parms.url);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -751,7 +752,7 @@ in_addr_t discover_ota_server(int max) {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
ESP_LOGI(TAG,"sending LMS discovery");
|
ESP_LOGI(TAG,"sending LMS discovery for OTA Update");
|
||||||
memset(&s, 0, sizeof(s));
|
memset(&s, 0, sizeof(s));
|
||||||
|
|
||||||
if (sendto(disc_sock, buf, len, 0, (struct sockaddr *)&d, sizeof(d)) < 0) {
|
if (sendto(disc_sock, buf, len, 0, (struct sockaddr *)&d, sizeof(d)) < 0) {
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ static size_t log_buf_size=2000; //32-bit aligned size
|
|||||||
static bool bIsEnabled=false;
|
static bool bIsEnabled=false;
|
||||||
static int partnerSocket=0;
|
static int partnerSocket=0;
|
||||||
static telnet_t *tnHandle;
|
static telnet_t *tnHandle;
|
||||||
extern bool bypass_wifi_manager;
|
extern bool bypass_network_manager;
|
||||||
|
|
||||||
/************************************
|
/************************************
|
||||||
* Forward declarations
|
* Forward declarations
|
||||||
@@ -92,7 +92,7 @@ void init_telnet(){
|
|||||||
// if wifi manager is bypassed, there will possibly be no wifi available
|
// if wifi manager is bypassed, there will possibly be no wifi available
|
||||||
//
|
//
|
||||||
bMirrorToUART = (strcasestr("D",val)!=NULL);
|
bMirrorToUART = (strcasestr("D",val)!=NULL);
|
||||||
if(!bMirrorToUART && bypass_wifi_manager){
|
if(!bMirrorToUART && bypass_network_manager){
|
||||||
// This isn't supposed to happen, as telnet won't start if wifi manager isn't
|
// This isn't supposed to happen, as telnet won't start if wifi manager isn't
|
||||||
// started. So this is a safeguard only.
|
// started. So this is a safeguard only.
|
||||||
ESP_LOGW(TAG,"Wifi manager is not active. Forcing console on Serial output.");
|
ESP_LOGW(TAG,"Wifi manager is not active. Forcing console on Serial output.");
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
idf_component_register(SRCS operator.cpp utf8.c
|
idf_component_register(SRCS operator.cpp utf8.c trace.c
|
||||||
REQUIRES esp_common pthread
|
REQUIRES esp_common pthread
|
||||||
INCLUDE_DIRS .
|
INCLUDE_DIRS .
|
||||||
|
PRIV_REQUIRES services freertos pthread esp_common
|
||||||
)
|
)
|
||||||
|
|
||||||
#doing our own implementation of new operator for some pre-compiled binaries
|
#doing our own implementation of new operator for some pre-compiled binaries
|
||||||
|
|||||||
120
components/tools/trace.c
Normal file
120
components/tools/trace.c
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include "esp_system.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "freertos/xtensa_api.h"
|
||||||
|
#include "freertos/FreeRTOSConfig.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/queue.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "globdefs.h"
|
||||||
|
#include "esp_event.h"
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
|
|
||||||
|
static const char TAG[] = "TRACE";
|
||||||
|
// typedef struct mem_usage_trace_for_thread {
|
||||||
|
// TaskHandle_t task;
|
||||||
|
// size_t malloc_int_last;
|
||||||
|
// size_t malloc_spiram_last;
|
||||||
|
// size_t malloc_dma_last;
|
||||||
|
// const char *name;
|
||||||
|
// SLIST_ENTRY(mem_usage_trace_for_thread) next;
|
||||||
|
// } mem_usage_trace_for_thread_t;
|
||||||
|
|
||||||
|
// static EXT_RAM_ATTR SLIST_HEAD(memtrace, mem_usage_trace_for_thread) s_memtrace;
|
||||||
|
|
||||||
|
// mem_usage_trace_for_thread_t* memtrace_get_thread_entry(TaskHandle_t task) {
|
||||||
|
// if(!task) {
|
||||||
|
// ESP_LOGE(TAG, "memtrace_get_thread_entry: task is NULL");
|
||||||
|
// return NULL;
|
||||||
|
// }
|
||||||
|
// ESP_LOGD(TAG,"Looking for task %s",STR_OR_ALT(pcTaskGetName(task ), "unknown"));
|
||||||
|
// mem_usage_trace_for_thread_t* it;
|
||||||
|
// SLIST_FOREACH(it, &s_memtrace, next) {
|
||||||
|
// if ( it->task == task ) {
|
||||||
|
// ESP_LOGD(TAG,"Found task %s",STR_OR_ALT(pcTaskGetName(task ), "unknown"));
|
||||||
|
// return it;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return NULL;
|
||||||
|
// }
|
||||||
|
// void memtrace_add_thread_entry(TaskHandle_t task) {
|
||||||
|
// if(!task) {
|
||||||
|
// ESP_LOGE(TAG, "memtrace_get_thread_entry: task is NULL");
|
||||||
|
// return ;
|
||||||
|
// }
|
||||||
|
// mem_usage_trace_for_thread_t* it = memtrace_get_thread_entry(task);
|
||||||
|
// if (it) {
|
||||||
|
// ESP_LOGW(TAG, "memtrace_add_thread_entry: thread already in list");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// it = (mem_usage_trace_for_thread_t*)malloc_init_external(sizeof(mem_usage_trace_for_thread_t));
|
||||||
|
// if (!it) {
|
||||||
|
// ESP_LOGE(TAG, "memtrace_add_thread_entry: malloc failed");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// it->task = task;
|
||||||
|
// it->malloc_int_last = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||||
|
// it->malloc_spiram_last = heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
|
||||||
|
// it->malloc_dma_last = heap_caps_get_free_size(MALLOC_CAP_DMA);
|
||||||
|
// it->name = pcTaskGetName(task);
|
||||||
|
// SLIST_INSERT_HEAD(&s_memtrace, it, next);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// void memtrace_print_delta(){
|
||||||
|
// TaskHandle_t task = xTaskGetCurrentTaskHandle();
|
||||||
|
// mem_usage_trace_for_thread_t* it = memtrace_get_thread_entry(task);
|
||||||
|
// if (!it) {
|
||||||
|
// memtrace_add_thread_entry(task);
|
||||||
|
// ESP_LOGW(TAG, "memtrace_print_delta: added new entry for task %s",STR_OR_ALT(pcTaskGetName(task ), "unknown"));
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// size_t malloc_int_delta = heap_caps_get_free_size(MALLOC_CAP_INTERNAL) - it->malloc_int_last;
|
||||||
|
// size_t malloc_spiram_delta = heap_caps_get_free_size(MALLOC_CAP_SPIRAM) - it->malloc_spiram_last;
|
||||||
|
// size_t malloc_dma_delta = heap_caps_get_free_size(MALLOC_CAP_DMA) - it->malloc_dma_last;
|
||||||
|
// ESP_LOG(TAG, "Heap internal:%zu (min:%zu) external:%zu (min:%zu) dma:%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),
|
||||||
|
// heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM),
|
||||||
|
// heap_caps_get_free_size(MALLOC_CAP_DMA),
|
||||||
|
// heap_caps_get_minimum_free_size(MALLOC_CAP_DMA));
|
||||||
|
// ESP_LOGW(TAG, "memtrace_print_delta: %s: malloc_int_delta=%d, malloc_spiram_delta=%d, malloc_dma_delta=%d",
|
||||||
|
// STR_OR_ALT(it->name, "unknown"),
|
||||||
|
// malloc_int_delta,
|
||||||
|
// malloc_spiram_delta,
|
||||||
|
// malloc_dma_delta);
|
||||||
|
// it->malloc_int_last = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||||
|
// it->malloc_spiram_last = heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
|
||||||
|
// it->malloc_dma_last = heap_caps_get_free_size(MALLOC_CAP_DMA);
|
||||||
|
|
||||||
|
// }
|
||||||
|
size_t malloc_int = 0;
|
||||||
|
size_t malloc_spiram =0;
|
||||||
|
size_t malloc_dma = 0;
|
||||||
|
void memtrace_print_delta(const char * msg, const char * tag, const char * function){
|
||||||
|
size_t malloc_int_delta = heap_caps_get_free_size(MALLOC_CAP_INTERNAL) - malloc_int;
|
||||||
|
size_t malloc_spiram_delta = heap_caps_get_free_size(MALLOC_CAP_SPIRAM) - malloc_spiram;
|
||||||
|
size_t malloc_dma_delta = heap_caps_get_free_size(MALLOC_CAP_DMA) - malloc_dma;
|
||||||
|
ESP_LOGW(TAG, "Heap internal:%zu (min:%zu)(chg:%d)/external:%zu (min:%zu)(chg:%d)/dma:%zu (min:%zu)(chg:%d) : %s%s%s%s%s",
|
||||||
|
heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
|
||||||
|
heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL),
|
||||||
|
malloc_int_delta,
|
||||||
|
heap_caps_get_free_size(MALLOC_CAP_SPIRAM),
|
||||||
|
heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM),
|
||||||
|
malloc_spiram_delta,
|
||||||
|
heap_caps_get_free_size(MALLOC_CAP_DMA),
|
||||||
|
heap_caps_get_minimum_free_size(MALLOC_CAP_DMA),
|
||||||
|
malloc_dma_delta,
|
||||||
|
STR_OR_BLANK(tag),
|
||||||
|
tag?" ":"",
|
||||||
|
STR_OR_BLANK(function),
|
||||||
|
function?" ":"",
|
||||||
|
STR_OR_BLANK(msg)
|
||||||
|
);
|
||||||
|
malloc_int = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||||
|
malloc_spiram = heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
|
||||||
|
malloc_dma = heap_caps_get_free_size(MALLOC_CAP_DMA);
|
||||||
|
}
|
||||||
@@ -21,6 +21,9 @@
|
|||||||
#ifndef STR_OR_ALT
|
#ifndef STR_OR_ALT
|
||||||
#define STR_OR_ALT(str,alt) (str?str:alt)
|
#define STR_OR_ALT(str,alt) (str?str:alt)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef STR_OR_BLANK
|
||||||
|
#define STR_OR_BLANK(p) p == NULL ? "" : p
|
||||||
|
#endif
|
||||||
#define ENUM_TO_STRING(g) \
|
#define ENUM_TO_STRING(g) \
|
||||||
case g: \
|
case g: \
|
||||||
return STR(g); \
|
return STR(g); \
|
||||||
@@ -28,6 +31,14 @@
|
|||||||
extern const char unknown_string_placeholder[];
|
extern const char unknown_string_placeholder[];
|
||||||
extern const char * str_or_unknown(const char * str);
|
extern const char * str_or_unknown(const char * str);
|
||||||
extern const char * str_or_null(const char * str);
|
extern const char * str_or_null(const char * str);
|
||||||
|
void memtrace_print_delta(const char * msg, const char * TAG, const char * function);
|
||||||
|
#ifdef ENABLE_MEMTRACE
|
||||||
|
#define MEMTRACE_PRINT_DELTA() memtrace_print_delta(NULL,TAG,__FUNCTION__);
|
||||||
|
#define MEMTRACE_PRINT_DELTA_MESSAGE(x) memtrace_print_delta(x,TAG,__FUNCTION__);
|
||||||
|
#else
|
||||||
|
#define MEMTRACE_PRINT_DELTA()
|
||||||
|
#define MEMTRACE_PRINT_DELTA_MESSAGE(x) ESP_LOGD(TAG,"%s",x);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef FREE_AND_NULL
|
#ifndef FREE_AND_NULL
|
||||||
#define FREE_AND_NULL(x) if(x) { free(x); x=NULL; }
|
#define FREE_AND_NULL(x) if(x) { free(x); x=NULL; }
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
|
|
||||||
set( WEBPACK_DIR webapp/webpack/dist )
|
set( WEBPACK_DIR webapp/webpack/dist )
|
||||||
idf_component_register( SRC_DIRS . webapp
|
idf_component_register( SRC_DIRS . webapp UML-State-Machine-in-C/src
|
||||||
INCLUDE_DIRS . webapp ${IDF_PATH}/components/esp_http_server/src ${IDF_PATH}/components/esp_http_server/src/port/esp32 ${IDF_PATH}/components/esp_http_server/src/util ${IDF_PATH}/components/esp_http_server/src/
|
INCLUDE_DIRS . webapp UML-State-Machine-in-C/src ${IDF_PATH}/components/esp_http_server/src ${IDF_PATH}/components/esp_http_server/src/port/esp32 ${IDF_PATH}/components/esp_http_server/src/util ${IDF_PATH}/components/esp_http_server/src/
|
||||||
REQUIRES squeezelite-ota json mdns
|
REQUIRES squeezelite-ota json mdns
|
||||||
PRIV_REQUIRES tools cpp-stateless services platform_config esp_common json newlib freertos spi_flash nvs_flash mdns pthread wpa_supplicant platform_console esp_http_server console driver_bt
|
PRIV_REQUIRES tools services platform_config esp_common json newlib freertos spi_flash nvs_flash mdns pthread wpa_supplicant platform_console esp_http_server console driver_bt
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
# What is esp32-wifi-manager?
|
|
||||||
*esp32-wifi-manager* is an esp32 program that enables easy management of wifi networks through a web application.
|
|
||||||
|
|
||||||
*esp32-wifi-manager* is **lightweight** (8KB of task stack in total) and barely uses any CPU power through a completely event driven architecture. It's an all in one wifi scanner, http server & dns daemon living in the least amount of RAM possible.
|
|
||||||
|
|
||||||
For real time constrained applications, *esp32-wifi-manager* can live entirely on PRO CPU, leaving the entire APP CPU untouched for your own needs.
|
|
||||||
|
|
||||||
*esp32-wifi-manager* will automatically attempt to re-connect to a previously saved network on boot, and it will start its own wifi access point through which you can manage wifi networks if a saved network cannot be found and/or if the connection is lost.
|
|
||||||
|
|
||||||
*esp32-wifi-manager* is an esp-idf project that compiles successfully with the esp-idf 3.2 release. You can simply copy the project and start adding your own code to it.
|
|
||||||
|
|
||||||
# Demo
|
|
||||||
[](http://www.youtube.com/watch?v=hxlZi15bym4)
|
|
||||||
|
|
||||||
# Look and Feel
|
|
||||||
 
|
|
||||||
|
|
||||||
# Adding esp32-wifi-manager to your code
|
|
||||||
Ther are effectively three different ways you can embed esp32-wifi-manager with your code:
|
|
||||||
* Just forget about it and poll in your code for wifi connectivity status
|
|
||||||
* Use event callbacks
|
|
||||||
* Modify esp32-wifi-manager code directly to fit your needs
|
|
||||||
|
|
||||||
**Event callbacks** are the cleanest way to use the wifi manager and that's the recommended way to do it. A typical use-case would be to get notified when wifi manager finally gets a connection an access point. In order to do this you can simply define a callback function:
|
|
||||||
|
|
||||||
```c
|
|
||||||
void cb_connection_ok(void *pvParameter){
|
|
||||||
ESP_LOGI(TAG, "I have a connection!");
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Then just register it by calling:
|
|
||||||
|
|
||||||
```c
|
|
||||||
wifi_manager_set_callback(EVENT_STA_GOT_IP, &cb_connection_ok);
|
|
||||||
```
|
|
||||||
|
|
||||||
That's it! Now everytime the event is triggered it will call this function.
|
|
||||||
|
|
||||||
# License
|
|
||||||
*esp32-wifi-manager* is MIT licensed. As such, it can be included in any project, commercial or not, as long as you retain original copyright. Please make sure to read the license file.
|
|
||||||
1
components/wifi-manager/UML-State-Machine-in-C
Submodule
1
components/wifi-manager/UML-State-Machine-in-C
Submodule
Submodule components/wifi-manager/UML-State-Machine-in-C added at 96264241ad
@@ -24,6 +24,7 @@
|
|||||||
#include <_esp_http_server.h>
|
#include <_esp_http_server.h>
|
||||||
#include "esp_httpd_priv.h"
|
#include "esp_httpd_priv.h"
|
||||||
#include "ctrl_sock.h"
|
#include "ctrl_sock.h"
|
||||||
|
#include "globdefs.h"
|
||||||
|
|
||||||
static const char *TAG = "_httpd";
|
static const char *TAG = "_httpd";
|
||||||
|
|
||||||
@@ -269,18 +270,18 @@ static void _httpd_thread(void *arg)
|
|||||||
static struct httpd_data *__httpd_create(const httpd_config_t *config)
|
static struct httpd_data *__httpd_create(const httpd_config_t *config)
|
||||||
{
|
{
|
||||||
/* Allocate memory for httpd instance data */
|
/* Allocate memory for httpd instance data */
|
||||||
struct httpd_data *hd = calloc(1, sizeof(struct httpd_data));
|
struct httpd_data *hd = malloc_init_external(sizeof(struct httpd_data));
|
||||||
if (!hd) {
|
if (!hd) {
|
||||||
ESP_LOGE(TAG, LOG_FMT("Failed to allocate memory for HTTP server instance"));
|
ESP_LOGE(TAG, LOG_FMT("Failed to allocate memory for HTTP server instance"));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
hd->hd_calls = calloc(config->max_uri_handlers, sizeof(httpd_uri_t *));
|
hd->hd_calls = malloc_init_external(config->max_uri_handlers* sizeof(httpd_uri_t *));
|
||||||
if (!hd->hd_calls) {
|
if (!hd->hd_calls) {
|
||||||
ESP_LOGE(TAG, LOG_FMT("Failed to allocate memory for HTTP URI handlers"));
|
ESP_LOGE(TAG, LOG_FMT("Failed to allocate memory for HTTP URI handlers"));
|
||||||
free(hd);
|
free(hd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
hd->hd_sd = calloc(config->max_open_sockets, sizeof(struct sock_db));
|
hd->hd_sd = malloc_init_external(config->max_open_sockets* sizeof(struct sock_db));
|
||||||
if (!hd->hd_sd) {
|
if (!hd->hd_sd) {
|
||||||
ESP_LOGE(TAG, LOG_FMT("Failed to allocate memory for HTTP session data"));
|
ESP_LOGE(TAG, LOG_FMT("Failed to allocate memory for HTTP session data"));
|
||||||
free(hd->hd_calls);
|
free(hd->hd_calls);
|
||||||
@@ -288,7 +289,7 @@ static struct httpd_data *__httpd_create(const httpd_config_t *config)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
struct httpd_req_aux *ra = &hd->hd_req_aux;
|
struct httpd_req_aux *ra = &hd->hd_req_aux;
|
||||||
ra->resp_hdrs = calloc(config->max_resp_headers, sizeof(struct resp_hdr));
|
ra->resp_hdrs = malloc_init_external(config->max_resp_headers* sizeof(struct resp_hdr));
|
||||||
if (!ra->resp_hdrs) {
|
if (!ra->resp_hdrs) {
|
||||||
ESP_LOGE(TAG, LOG_FMT("Failed to allocate memory for HTTP response headers"));
|
ESP_LOGE(TAG, LOG_FMT("Failed to allocate memory for HTTP response headers"));
|
||||||
free(hd->hd_sd);
|
free(hd->hd_sd);
|
||||||
@@ -296,7 +297,7 @@ static struct httpd_data *__httpd_create(const httpd_config_t *config)
|
|||||||
free(hd);
|
free(hd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
hd->err_handler_fns = calloc(HTTPD_ERR_CODE_MAX, sizeof(httpd_err_handler_func_t));
|
hd->err_handler_fns = malloc_init_external(HTTPD_ERR_CODE_MAX* sizeof(httpd_err_handler_func_t));
|
||||||
if (!hd->err_handler_fns) {
|
if (!hd->err_handler_fns) {
|
||||||
ESP_LOGE(TAG, LOG_FMT("Failed to allocate memory for HTTP error handlers"));
|
ESP_LOGE(TAG, LOG_FMT("Failed to allocate memory for HTTP error handlers"));
|
||||||
free(ra->resp_hdrs);
|
free(ra->resp_hdrs);
|
||||||
|
|||||||
@@ -59,8 +59,8 @@ static const char TAG[] = "dns_server";
|
|||||||
static TaskHandle_t task_dns_server = NULL;
|
static TaskHandle_t task_dns_server = NULL;
|
||||||
int socket_fd;
|
int socket_fd;
|
||||||
|
|
||||||
void dns_server_start() {
|
void dns_server_start(esp_netif_t * netif) {
|
||||||
xTaskCreate(&dns_server, "dns_server", 3072, NULL, WIFI_MANAGER_TASK_PRIORITY-1, &task_dns_server);
|
xTaskCreate(&dns_server, "dns_server", 3072, (void *)netif, WIFI_MANAGER_TASK_PRIORITY-1, &task_dns_server);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dns_server_stop(){
|
void dns_server_stop(){
|
||||||
@@ -75,7 +75,8 @@ void dns_server_stop(){
|
|||||||
|
|
||||||
void dns_server(void *pvParameters) {
|
void dns_server(void *pvParameters) {
|
||||||
struct sockaddr_in sa, ra;
|
struct sockaddr_in sa, ra;
|
||||||
|
esp_err_t esp_err = ESP_OK;
|
||||||
|
esp_netif_t * netif = (esp_netif_t * )pvParameters;
|
||||||
/* Set redirection DNS hijack to the access point IP */
|
/* Set redirection DNS hijack to the access point IP */
|
||||||
ip4_addr_t ip_resolved;
|
ip4_addr_t ip_resolved;
|
||||||
inet_pton(AF_INET, DEFAULT_AP_IP, &ip_resolved);
|
inet_pton(AF_INET, DEFAULT_AP_IP, &ip_resolved);
|
||||||
@@ -90,10 +91,14 @@ void dns_server(void *pvParameters) {
|
|||||||
memset(&sa, 0, sizeof(struct sockaddr_in));
|
memset(&sa, 0, sizeof(struct sockaddr_in));
|
||||||
|
|
||||||
/* Bind to port 53 (typical DNS Server port) */
|
/* Bind to port 53 (typical DNS Server port) */
|
||||||
tcpip_adapter_ip_info_t ip;
|
esp_netif_ip_info_t ip_info;
|
||||||
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip);
|
esp_err = esp_netif_get_ip_info(netif,&ip_info);
|
||||||
|
if(esp_err!=ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to get adapter info for udp: %s", esp_err_to_name(esp_err));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
ra.sin_family = AF_INET;
|
ra.sin_family = AF_INET;
|
||||||
ra.sin_addr.s_addr = ip.ip.addr;
|
ra.sin_addr.s_addr = ip_info.ip.addr;
|
||||||
ra.sin_port = htons(53);
|
ra.sin_port = htons(53);
|
||||||
if (bind(socket_fd, (struct sockaddr *)&ra, sizeof(struct sockaddr_in)) == -1) {
|
if (bind(socket_fd, (struct sockaddr *)&ra, sizeof(struct sockaddr_in)) == -1) {
|
||||||
ESP_LOGE(TAG, "Failed to bind to 53/udp");
|
ESP_LOGE(TAG, "Failed to bind to 53/udp");
|
||||||
@@ -149,7 +154,7 @@ void dns_server(void *pvParameters) {
|
|||||||
for(char* c=domain; *c != '\0'; c++){
|
for(char* c=domain; *c != '\0'; c++){
|
||||||
if(*c < ' ' || *c > 'z') *c = '.'; /* technically we should test if the first two bits are 00 (e.g. if( (*c & 0xC0) == 0x00) *c = '.') but this makes the code a lot more readable */
|
if(*c < ' ' || *c > 'z') *c = '.'; /* technically we should test if the first two bits are 00 (e.g. if( (*c & 0xC0) == 0x00) *c = '.') but this makes the code a lot more readable */
|
||||||
}
|
}
|
||||||
ESP_LOGI(TAG, "Replying to DNS request for %s from %s", domain, ip_address);
|
ESP_LOGD(TAG, "Replying to DNS request for %s from %s", domain, ip_address);
|
||||||
|
|
||||||
|
|
||||||
/* create DNS answer at the end of the query*/
|
/* create DNS answer at the end of the query*/
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ Contains the freeRTOS task for the DNS server that processes the requests.
|
|||||||
#include <esp_system.h>
|
#include <esp_system.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "squeezelite-ota.h"
|
#include "squeezelite-ota.h"
|
||||||
|
#include "esp_netif.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -128,7 +129,7 @@ typedef struct __attribute__((__packed__)) dns_answer_t{
|
|||||||
}dns_answer_t;
|
}dns_answer_t;
|
||||||
|
|
||||||
void dns_server(void *pvParameters);
|
void dns_server(void *pvParameters);
|
||||||
void dns_server_start();
|
void dns_server_start(esp_netif_t * netif);
|
||||||
void dns_server_stop();
|
void dns_server_stop();
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,34 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2017-2019 Tony Pottier
|
Copyright (c) 2017-2021 Sebastien L
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
|
|
||||||
@file http_server.c
|
|
||||||
@author Tony Pottier
|
|
||||||
@brief Defines all functions necessary for the HTTP server to run.
|
|
||||||
|
|
||||||
Contains the freeRTOS task for the HTTP listener and all necessary support
|
|
||||||
function to process requests, decode URLs, serve files, etc. etc.
|
|
||||||
|
|
||||||
@note http_server task cannot run without the wifi_manager task!
|
|
||||||
@see https://idyl.io
|
|
||||||
@see https://github.com/tonyp7/esp32-wifi-manager
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "http_server_handlers.h"
|
#include "http_server_handlers.h"
|
||||||
@@ -57,7 +28,8 @@ function to process requests, decode URLs, serve files, etc. etc.
|
|||||||
#include "webapp/webpack.h"
|
#include "webapp/webpack.h"
|
||||||
#include "network_wifi.h"
|
#include "network_wifi.h"
|
||||||
#include "network_status.h"
|
#include "network_status.h"
|
||||||
|
#include "globdefs.h"
|
||||||
|
|
||||||
#define HTTP_STACK_SIZE (5*1024)
|
#define HTTP_STACK_SIZE (5*1024)
|
||||||
const char str_na[]="N/A";
|
const char str_na[]="N/A";
|
||||||
#define STR_OR_NA(s) s?s:str_na
|
#define STR_OR_NA(s) s?s:str_na
|
||||||
@@ -104,7 +76,7 @@ char * alloc_get_http_header(httpd_req_t * req, const char * key){
|
|||||||
* extra byte for null termination */
|
* extra byte for null termination */
|
||||||
buf_len = httpd_req_get_hdr_value_len(req, key) + 1;
|
buf_len = httpd_req_get_hdr_value_len(req, key) + 1;
|
||||||
if (buf_len > 1) {
|
if (buf_len > 1) {
|
||||||
buf = malloc(buf_len);
|
buf = malloc_init_external(buf_len);
|
||||||
/* Copy null terminated value string into buffer */
|
/* Copy null terminated value string into buffer */
|
||||||
if (httpd_req_get_hdr_value_str(req, "Host", buf, buf_len) == ESP_OK) {
|
if (httpd_req_get_hdr_value_str(req, "Host", buf, buf_len) == ESP_OK) {
|
||||||
ESP_LOGD_LOC(TAG, "Found header => %s: %s",key, buf);
|
ESP_LOGD_LOC(TAG, "Found header => %s: %s",key, buf);
|
||||||
@@ -120,16 +92,14 @@ char * http_alloc_get_socket_address(httpd_req_t *req, u8_t local, in_port_t * p
|
|||||||
union sockaddr_aligned addr;
|
union sockaddr_aligned addr;
|
||||||
len = sizeof(addr);
|
len = sizeof(addr);
|
||||||
ip_addr_t * ip_addr=NULL;
|
ip_addr_t * ip_addr=NULL;
|
||||||
char * ipstr = malloc(INET6_ADDRSTRLEN);
|
char * ipstr = malloc_init_external(INET6_ADDRSTRLEN);
|
||||||
memset(ipstr,0x0,INET6_ADDRSTRLEN);
|
|
||||||
|
|
||||||
typedef int (*getaddrname_fn_t)(int s, struct sockaddr *name, socklen_t *namelen);
|
typedef int (*getaddrname_fn_t)(int s, struct sockaddr *name, socklen_t *namelen);
|
||||||
getaddrname_fn_t get_addr = NULL;
|
getaddrname_fn_t get_addr = NULL;
|
||||||
|
|
||||||
int s = httpd_req_to_sockfd(req);
|
int s = httpd_req_to_sockfd(req);
|
||||||
if(s == -1) {
|
if(s == -1) {
|
||||||
free(ipstr);
|
free(ipstr);
|
||||||
return strdup("httpd_req_to_sockfd error");
|
return strdup_psram("httpd_req_to_sockfd error");
|
||||||
}
|
}
|
||||||
ESP_LOGV_LOC(TAG,"httpd socket descriptor: %u", s);
|
ESP_LOGV_LOC(TAG,"httpd socket descriptor: %u", s);
|
||||||
|
|
||||||
@@ -192,7 +162,7 @@ bool is_captive_portal_host_name(httpd_req_t *req){
|
|||||||
ESP_LOGD_LOC(TAG, "Soft AP Host name is %s",ap_host_name);
|
ESP_LOGD_LOC(TAG, "Soft AP Host name is %s",ap_host_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
ap_ip_address = malloc(IP4ADDR_STRLEN_MAX);
|
ap_ip_address = malloc_init_external(IP4ADDR_STRLEN_MAX);
|
||||||
memset(ap_ip_address, 0x00, IP4ADDR_STRLEN_MAX);
|
memset(ap_ip_address, 0x00, IP4ADDR_STRLEN_MAX);
|
||||||
if(ap_ip_address){
|
if(ap_ip_address){
|
||||||
ESP_LOGD_LOC(TAG, "Converting soft ip address to string");
|
ESP_LOGD_LOC(TAG, "Converting soft ip address to string");
|
||||||
@@ -233,8 +203,7 @@ session_context_t* get_session_context(httpd_req_t *req){
|
|||||||
bool newConnection=false;
|
bool newConnection=false;
|
||||||
if (! req->sess_ctx) {
|
if (! req->sess_ctx) {
|
||||||
ESP_LOGD(TAG,"New connection context. Allocating session buffer");
|
ESP_LOGD(TAG,"New connection context. Allocating session buffer");
|
||||||
req->sess_ctx = malloc(sizeof(session_context_t));
|
req->sess_ctx = malloc_init_external(sizeof(session_context_t));
|
||||||
memset(req->sess_ctx,0x00,sizeof(session_context_t));
|
|
||||||
req->free_ctx = free_ctx_func;
|
req->free_ctx = free_ctx_func;
|
||||||
newConnection = true;
|
newConnection = true;
|
||||||
// get the remote IP address only once per session
|
// get the remote IP address only once per session
|
||||||
@@ -256,11 +225,13 @@ bool is_user_authenticated(httpd_req_t *req){
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGD(TAG,"Heap internal:%zu (min:%zu) external:%zu (min:%zu)",
|
ESP_LOGD(TAG, "Heap internal:%zu (min:%zu) external:%zu (min:%zu) dma:%zu (min:%zu)",
|
||||||
heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
|
heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
|
||||||
heap_caps_get_minimum_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_free_size(MALLOC_CAP_SPIRAM),
|
||||||
heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM));
|
heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM),
|
||||||
|
heap_caps_get_free_size(MALLOC_CAP_DMA),
|
||||||
|
heap_caps_get_minimum_free_size(MALLOC_CAP_DMA));
|
||||||
|
|
||||||
// todo: ask for user to authenticate
|
// todo: ask for user to authenticate
|
||||||
return false;
|
return false;
|
||||||
@@ -439,7 +410,7 @@ esp_err_t ap_scan_handler(httpd_req_t *req){
|
|||||||
// todo: redirect to login page
|
// todo: redirect to login page
|
||||||
// return ESP_OK;
|
// return ESP_OK;
|
||||||
}
|
}
|
||||||
network_manager_async_scan();
|
network_async_scan();
|
||||||
esp_err_t err = set_content_type_from_req(req);
|
esp_err_t err = set_content_type_from_req(req);
|
||||||
if(err == ESP_OK){
|
if(err == ESP_OK){
|
||||||
httpd_resp_send(req, (const char *)empty, HTTPD_RESP_USE_STRLEN);
|
httpd_resp_send(req, (const char *)empty, HTTPD_RESP_USE_STRLEN);
|
||||||
@@ -529,9 +500,9 @@ esp_err_t ap_get_handler(httpd_req_t *req){
|
|||||||
}
|
}
|
||||||
/* if we can get the mutex, write the last version of the AP list */
|
/* if we can get the mutex, write the last version of the AP list */
|
||||||
esp_err_t err = set_content_type_from_req(req);
|
esp_err_t err = set_content_type_from_req(req);
|
||||||
if( err == ESP_OK && wifi_manager_lock_json_buffer(( TickType_t ) 200/portTICK_PERIOD_MS)){
|
if( err == ESP_OK && network_status_lock_json_buffer(( TickType_t ) 200/portTICK_PERIOD_MS)){
|
||||||
char *buff = wifi_manager_alloc_get_ap_list_json();
|
char *buff = network_status_alloc_get_ap_list_json();
|
||||||
wifi_manager_unlock_json_buffer();
|
network_status_unlock_json_buffer();
|
||||||
if(buff!=NULL){
|
if(buff!=NULL){
|
||||||
httpd_resp_send(req, (const char *)buff, HTTPD_RESP_USE_STRLEN);
|
httpd_resp_send(req, (const char *)buff, HTTPD_RESP_USE_STRLEN);
|
||||||
free(buff);
|
free(buff);
|
||||||
@@ -683,7 +654,7 @@ esp_err_t config_post_handler(httpd_req_t *req){
|
|||||||
else {
|
else {
|
||||||
// we're getting a request to do an OTA from that URL
|
// we're getting a request to do an OTA from that URL
|
||||||
ESP_LOGW_LOC(TAG, "Found OTA request!");
|
ESP_LOGW_LOC(TAG, "Found OTA request!");
|
||||||
otaURL=strdup(val);
|
otaURL=strdup_psram(val);
|
||||||
bOTA=true;
|
bOTA=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -730,7 +701,7 @@ esp_err_t config_post_handler(httpd_req_t *req){
|
|||||||
ESP_LOGW_LOC(TAG, "Restarting system to process OTA for url %s",otaURL);
|
ESP_LOGW_LOC(TAG, "Restarting system to process OTA for url %s",otaURL);
|
||||||
}
|
}
|
||||||
|
|
||||||
network_manager_reboot_ota(otaURL);
|
network_reboot_ota(otaURL);
|
||||||
free(otaURL);
|
free(otaURL);
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
@@ -766,15 +737,15 @@ esp_err_t connect_post_handler(httpd_req_t *req){
|
|||||||
|
|
||||||
cJSON * ssid_object = cJSON_GetObjectItem(root, "ssid");
|
cJSON * ssid_object = cJSON_GetObjectItem(root, "ssid");
|
||||||
if(ssid_object !=NULL){
|
if(ssid_object !=NULL){
|
||||||
ssid = strdup(ssid_object->valuestring);
|
ssid = strdup_psram(ssid_object->valuestring);
|
||||||
}
|
}
|
||||||
cJSON * password_object = cJSON_GetObjectItem(root, "pwd");
|
cJSON * password_object = cJSON_GetObjectItem(root, "pwd");
|
||||||
if(password_object !=NULL){
|
if(password_object !=NULL){
|
||||||
password = strdup(password_object->valuestring);
|
password = strdup_psram(password_object->valuestring);
|
||||||
}
|
}
|
||||||
cJSON * host_name_object = cJSON_GetObjectItem(root, "host_name");
|
cJSON * host_name_object = cJSON_GetObjectItem(root, "host_name");
|
||||||
if(host_name_object !=NULL){
|
if(host_name_object !=NULL){
|
||||||
host_name = strdup(host_name_object->valuestring);
|
host_name = strdup_psram(host_name_object->valuestring);
|
||||||
}
|
}
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
|
|
||||||
@@ -785,14 +756,7 @@ esp_err_t connect_post_handler(httpd_req_t *req){
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(ssid !=NULL && strlen(ssid) <= MAX_SSID_SIZE && strlen(password) <= MAX_PASSWORD_SIZE ){
|
if(ssid !=NULL && strlen(ssid) <= MAX_SSID_SIZE && strlen(password) <= MAX_PASSWORD_SIZE ){
|
||||||
wifi_config_t* config = wifi_manager_get_wifi_sta_config();
|
network_async_connect(ssid, password);
|
||||||
memset(config, 0x00, sizeof(wifi_config_t));
|
|
||||||
strlcpy((char *)config->sta.ssid, ssid, sizeof(config->sta.ssid)+1);
|
|
||||||
if(password){
|
|
||||||
strlcpy((char *)config->sta.password, password, sizeof(config->sta.password)+1);
|
|
||||||
}
|
|
||||||
ESP_LOGD_LOC(TAG, "http_server_netconn_serve: network_manager_async_scan() call, with ssid: %s, password: %s", config->sta.ssid, config->sta.password);
|
|
||||||
network_manager_async_scan();
|
|
||||||
httpd_resp_send(req, (const char *)success, strlen(success));
|
httpd_resp_send(req, (const char *)success, strlen(success));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -816,7 +780,7 @@ esp_err_t connect_delete_handler(httpd_req_t *req){
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
httpd_resp_send(req, (const char *)success, strlen(success));
|
httpd_resp_send(req, (const char *)success, strlen(success));
|
||||||
network_manager_async_disconnect();
|
network_async_delete();
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
@@ -833,7 +797,7 @@ esp_err_t reboot_ota_post_handler(httpd_req_t *req){
|
|||||||
}
|
}
|
||||||
|
|
||||||
httpd_resp_send(req, (const char *)success, strlen(success));
|
httpd_resp_send(req, (const char *)success, strlen(success));
|
||||||
network_manager_async_reboot(OTA);
|
network_async_reboot(OTA);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
esp_err_t reboot_post_handler(httpd_req_t *req){
|
esp_err_t reboot_post_handler(httpd_req_t *req){
|
||||||
@@ -848,7 +812,7 @@ esp_err_t reboot_post_handler(httpd_req_t *req){
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
httpd_resp_send(req, (const char *)success, strlen(success));
|
httpd_resp_send(req, (const char *)success, strlen(success));
|
||||||
network_manager_async_reboot(RESTART);
|
network_async_reboot(RESTART);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
esp_err_t recovery_post_handler(httpd_req_t *req){
|
esp_err_t recovery_post_handler(httpd_req_t *req){
|
||||||
@@ -863,7 +827,7 @@ esp_err_t recovery_post_handler(httpd_req_t *req){
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
httpd_resp_send(req, (const char *)success, strlen(success));
|
httpd_resp_send(req, (const char *)success, strlen(success));
|
||||||
network_manager_async_reboot(RECOVERY);
|
network_async_reboot(RECOVERY);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -881,7 +845,7 @@ esp_err_t flash_post_handler(httpd_req_t *req){
|
|||||||
if(err != ESP_OK){
|
if(err != ESP_OK){
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
char * binary_buffer = malloc(req->content_len);
|
char * binary_buffer = malloc_init_external(req->content_len);
|
||||||
if(binary_buffer == NULL){
|
if(binary_buffer == NULL){
|
||||||
ESP_LOGE(TAG, "File too large : %d bytes", req->content_len);
|
ESP_LOGE(TAG, "File too large : %d bytes", req->content_len);
|
||||||
/* Respond with 400 Bad Request */
|
/* Respond with 400 Bad Request */
|
||||||
@@ -981,11 +945,11 @@ esp_err_t process_redirect(httpd_req_t *req, const char * status){
|
|||||||
remote_ip = http_alloc_get_socket_address(req,0, &port);
|
remote_ip = http_alloc_get_socket_address(req,0, &port);
|
||||||
|
|
||||||
size_t buf_size = strlen(redirect_payload1) +strlen(redirect_payload2) + strlen(redirect_payload3) +2*(strlen(location_prefix)+strlen(ap_ip_address))+1;
|
size_t buf_size = strlen(redirect_payload1) +strlen(redirect_payload2) + strlen(redirect_payload3) +2*(strlen(location_prefix)+strlen(ap_ip_address))+1;
|
||||||
char * redirect=malloc(buf_size);
|
char * redirect=malloc_init_external(buf_size);
|
||||||
|
|
||||||
if(strcasestr(status,"302")){
|
if(strcasestr(status,"302")){
|
||||||
size_t url_buf_size = strlen(location_prefix) + strlen(ap_ip_address)+1;
|
size_t url_buf_size = strlen(location_prefix) + strlen(ap_ip_address)+1;
|
||||||
redirect_url = malloc(url_buf_size);
|
redirect_url = malloc_init_external(url_buf_size);
|
||||||
memset(redirect_url,0x00,url_buf_size);
|
memset(redirect_url,0x00,url_buf_size);
|
||||||
snprintf(redirect_url, buf_size,"%s%s/",location_prefix, ap_ip_address);
|
snprintf(redirect_url, buf_size,"%s%s/",location_prefix, ap_ip_address);
|
||||||
ESP_LOGW_LOC(TAG, "Redirecting host [%s] to %s (from uri %s)",remote_ip, redirect_url,req->uri);
|
ESP_LOGW_LOC(TAG, "Redirecting host [%s] to %s (from uri %s)",remote_ip, redirect_url,req->uri);
|
||||||
@@ -1034,9 +998,9 @@ esp_err_t redirect_processor(httpd_req_t *req, httpd_err_code_t error){
|
|||||||
remote_ip = http_alloc_get_socket_address(req,0, &port);
|
remote_ip = http_alloc_get_socket_address(req,0, &port);
|
||||||
|
|
||||||
ESP_LOGW_LOC(TAG, "%s requested invalid URL: [%s]",remote_ip, req->uri);
|
ESP_LOGW_LOC(TAG, "%s requested invalid URL: [%s]",remote_ip, req->uri);
|
||||||
if(wifi_manager_lock_sta_ip_string(portMAX_DELAY)){
|
if(network_status_lock_sta_ip_string(portMAX_DELAY)){
|
||||||
sta_ip_address = strdup(wifi_manager_get_sta_ip_string());
|
sta_ip_address = strdup_psram(network_status_get_sta_ip_string());
|
||||||
wifi_manager_unlock_sta_ip_string();
|
network_status_unlock_sta_ip_string();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ESP_LOGE(TAG,"Unable to obtain local IP address from WiFi Manager.");
|
ESP_LOGE(TAG,"Unable to obtain local IP address from WiFi Manager.");
|
||||||
@@ -1149,9 +1113,9 @@ esp_err_t status_get_handler(httpd_req_t *req){
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(wifi_manager_lock_json_buffer(( TickType_t ) 200/portTICK_PERIOD_MS)) {
|
if(network_status_lock_json_buffer(( TickType_t ) 200/portTICK_PERIOD_MS)) {
|
||||||
char *buff = wifi_manager_alloc_get_ip_info_json();
|
char *buff = network_status_alloc_get_ip_info_json();
|
||||||
wifi_manager_unlock_json_buffer();
|
network_status_unlock_json_buffer();
|
||||||
if(buff) {
|
if(buff) {
|
||||||
httpd_resp_send(req, (const char *)buff, strlen(buff));
|
httpd_resp_send(req, (const char *)buff, strlen(buff));
|
||||||
free(buff);
|
free(buff);
|
||||||
@@ -1164,7 +1128,7 @@ esp_err_t status_get_handler(httpd_req_t *req){
|
|||||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR , "Error retrieving status object");
|
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR , "Error retrieving status object");
|
||||||
}
|
}
|
||||||
// update status for next status call
|
// update status for next status call
|
||||||
network_manager_async_update_status();
|
network_async_update_status();
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2017-2019 Tony Pottier
|
Copyright (c) 2017-2021 Sebastien L
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
|
|
||||||
@file http_server.h
|
|
||||||
@author Tony Pottier
|
|
||||||
@brief Defines all functions necessary for the HTTP server to run.
|
|
||||||
|
|
||||||
Contains the freeRTOS task for the HTTP listener and all necessary support
|
|
||||||
function to process requests, decode URLs, serve files, etc. etc.
|
|
||||||
|
|
||||||
@note http_server task cannot run without the wifi_manager task!
|
|
||||||
@see https://idyl.io
|
|
||||||
@see https://github.com/tonyp7/esp32-wifi-manager
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef HTTP_SERVER_H_INCLUDED
|
#ifndef HTTP_SERVER_H_INCLUDED
|
||||||
|
|||||||
@@ -1,38 +1,40 @@
|
|||||||
#include "esp_eth.h"
|
#include "esp_eth.h"
|
||||||
#include "network_ethernet.h"
|
#include "network_ethernet.h"
|
||||||
|
static EXT_RAM_ATTR network_ethernet_driver_t DM9051;
|
||||||
static esp_eth_mac_t* mac_new(spi_device_handle_t spi_handle, eth_config_t* ethernet_config) {
|
static esp_err_t start(spi_device_handle_t spi_handle, eth_config_t* ethernet_config) {
|
||||||
#ifdef CONFIG_ETH_SPI_ETHERNET_DM9051
|
#ifdef CONFIG_ETH_SPI_ETHERNET_DM9051
|
||||||
|
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
|
||||||
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
|
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
|
||||||
eth_dm9051_config_t eth_config = ETH_DM9051_DEFAULT_CONFIG(spi_handle);
|
eth_dm9051_config_t eth_config = ETH_DM9051_DEFAULT_CONFIG(spi_handle);
|
||||||
// we assume that isr has been installed already
|
// we assume that isr has been installed already
|
||||||
eth_config.int_gpio_num = ethernet_config->intr;
|
eth_config.int_gpio_num = ethernet_config->intr;
|
||||||
return esp_eth_mac_new_dm9051(ð_config, &mac_config);
|
phy_config.phy_addr = -1;
|
||||||
#else
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
static esp_eth_phy_t* phy_new(eth_config_t* ethernet_config) {
|
|
||||||
#ifdef CONFIG_ETH_SPI_ETHERNET_DM9051
|
|
||||||
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
|
|
||||||
phy_config.phy_addr = 1;
|
|
||||||
phy_config.reset_gpio_num = ethernet_config->rst;
|
phy_config.reset_gpio_num = ethernet_config->rst;
|
||||||
return esp_eth_phy_new_dm9051(&phy_config);
|
|
||||||
|
esp_eth_mac_t* mac = esp_eth_mac_new_dm9051(ð_config, &mac_config);
|
||||||
|
esp_eth_phy_t* phy = esp_eth_phy_new_dm9051(&phy_config);
|
||||||
|
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy);
|
||||||
|
return esp_eth_driver_install(&config, &DM9051.handle);
|
||||||
#else
|
#else
|
||||||
return NULL;
|
return ESP_ERR_NOT_SUPPORTED;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
static void init_config(eth_config_t* ethernet_config) {
|
|
||||||
}
|
|
||||||
|
|
||||||
static network_ethernet_driver_t DM9051 = {
|
static void init_config(eth_config_t* ethernet_config) {
|
||||||
.mac_new = mac_new,
|
DM9051.start = start;
|
||||||
.phy_new = phy_new,
|
DM9051.rmii = true;
|
||||||
.init_config = init_config,
|
DM9051.spi = false;
|
||||||
.valid = true,
|
DM9051.valid = true;
|
||||||
};
|
}
|
||||||
|
|
||||||
network_ethernet_driver_t* DM9051_Detect(char* Driver) {
|
network_ethernet_driver_t* DM9051_Detect(char* Driver) {
|
||||||
if (!strcasestr(Driver, "DM9051"))
|
if (!strcasestr(Driver, "DM9051"))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
#ifdef CONFIG_ETH_SPI_ETHERNET_DM9051
|
||||||
|
DM9051.valid = true;
|
||||||
|
#else
|
||||||
|
DM9051.valid = false;
|
||||||
|
#endif
|
||||||
|
DM9051.init_config = init_config;
|
||||||
return &DM9051;
|
return &DM9051;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,47 +1,40 @@
|
|||||||
#include "esp_eth.h"
|
#include "esp_eth.h"
|
||||||
#include "network_ethernet.h"
|
#include "network_ethernet.h"
|
||||||
|
|
||||||
static esp_eth_mac_t* mac_new(spi_device_handle_t spi_handle, eth_config_t* ethernet_config) {
|
static EXT_RAM_ATTR network_ethernet_driver_t LAN8720;
|
||||||
|
static esp_err_t start(spi_device_handle_t spi_handle, eth_config_t* ethernet_config) {
|
||||||
#ifdef CONFIG_ETH_PHY_INTERFACE_RMII
|
#ifdef CONFIG_ETH_PHY_INTERFACE_RMII
|
||||||
|
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
|
||||||
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
|
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
|
||||||
|
|
||||||
mac_config.smi_mdc_gpio_num = ethernet_config->mdc;
|
mac_config.smi_mdc_gpio_num = ethernet_config->mdc;
|
||||||
mac_config.smi_mdio_gpio_num = ethernet_config->mdio;
|
mac_config.smi_mdio_gpio_num = ethernet_config->mdio;
|
||||||
mac_config.sw_reset_timeout_ms = 400;
|
|
||||||
return esp_eth_mac_new_esp32(&mac_config);
|
|
||||||
#else
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
static esp_eth_phy_t* phy_new(eth_config_t* ethernet_config) {
|
|
||||||
#ifdef CONFIG_ETH_PHY_INTERFACE_RMII
|
|
||||||
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
|
|
||||||
phy_config.phy_addr = 1;
|
phy_config.phy_addr = 1;
|
||||||
phy_config.reset_gpio_num = ethernet_config->rst;
|
phy_config.reset_gpio_num = ethernet_config->rst;
|
||||||
return esp_eth_phy_new_lan8720(&phy_config);
|
|
||||||
|
esp_eth_mac_t* mac = esp_eth_mac_new_esp32(&mac_config);
|
||||||
|
esp_eth_phy_t* phy = esp_eth_phy_new_lan8720(&phy_config);
|
||||||
|
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy);
|
||||||
|
return esp_eth_driver_install(&config, &LAN8720.handle);
|
||||||
#else
|
#else
|
||||||
return NULL;
|
return ESP_ERR_NOT_SUPPORTED;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_config(eth_config_t* ethernet_config) {
|
static void init_config(eth_config_t* ethernet_config) {
|
||||||
#ifdef CONFIG_ETH_PHY_INTERFACE_RMII
|
LAN8720.start = start;
|
||||||
#else
|
LAN8720.rmii = true;
|
||||||
return NULL;
|
LAN8720.spi = false;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static network_ethernet_driver_t LAN8720 = {
|
|
||||||
|
|
||||||
.mac_new = mac_new,
|
|
||||||
.phy_new = phy_new,
|
|
||||||
.init_config = init_config,
|
|
||||||
#ifdef CONFIG_ETH_PHY_INTERFACE_RMII
|
|
||||||
.valid = true,
|
|
||||||
#else
|
|
||||||
.valid = false,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
network_ethernet_driver_t* LAN8720_Detect(char* Driver) {
|
network_ethernet_driver_t* LAN8720_Detect(char* Driver) {
|
||||||
if (!strcasestr(Driver, "LAN8720"))
|
if (!strcasestr(Driver, "LAN8720"))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
#ifdef CONFIG_ETH_PHY_INTERFACE_RMII
|
||||||
|
LAN8720.valid = true;
|
||||||
|
#else
|
||||||
|
LAN8720.valid = false;
|
||||||
|
#endif
|
||||||
|
LAN8720.init_config = init_config;
|
||||||
return &LAN8720;
|
return &LAN8720;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,43 +1,55 @@
|
|||||||
#include "esp_eth.h"
|
#include "esp_eth.h"
|
||||||
|
#include "globdefs.h"
|
||||||
#include "network_ethernet.h"
|
#include "network_ethernet.h"
|
||||||
|
static EXT_RAM_ATTR network_ethernet_driver_t W5500;
|
||||||
|
static EXT_RAM_ATTR spi_device_interface_config_t devcfg;
|
||||||
|
static EXT_RAM_ATTR esp_netif_config_t cfg_spi;
|
||||||
|
static EXT_RAM_ATTR esp_netif_inherent_config_t esp_netif_config;
|
||||||
|
|
||||||
static esp_eth_mac_t* mac_new(spi_device_handle_t spi_handle, eth_config_t* ethernet_config) {
|
static esp_err_t start(spi_device_handle_t spi_handle, eth_config_t* ethernet_config) {
|
||||||
#ifdef CONFIG_ETH_SPI_ETHERNET_W5500
|
#ifdef CONFIG_ETH_SPI_ETHERNET_W5500
|
||||||
eth_w5500_config_t eth_config = ETH_W5500_DEFAULT_CONFIG(spi_handle);
|
eth_w5500_config_t eth_config = ETH_W5500_DEFAULT_CONFIG(spi_handle);
|
||||||
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
|
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
|
||||||
// we assume that isr has been installed already
|
|
||||||
eth_config.int_gpio_num = ethernet_config->intr;
|
|
||||||
return esp_eth_mac_new_w5500(ð_config, &mac_config);
|
|
||||||
#else
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
static esp_eth_phy_t* phy_new(eth_config_t* ethernet_config) {
|
|
||||||
#ifdef CONFIG_ETH_SPI_ETHERNET_W5500
|
|
||||||
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
|
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
|
||||||
phy_config.phy_addr = 1;
|
|
||||||
|
eth_config.int_gpio_num = ethernet_config->intr;
|
||||||
|
phy_config.phy_addr = -1; // let the system automatically find out the phy address
|
||||||
phy_config.reset_gpio_num = ethernet_config->rst;
|
phy_config.reset_gpio_num = ethernet_config->rst;
|
||||||
return esp_eth_phy_new_w5500(&phy_config);
|
|
||||||
|
esp_eth_mac_t* mac = esp_eth_mac_new_w5500(ð_config, &mac_config);
|
||||||
|
esp_eth_phy_t* phy = esp_eth_phy_new_w5500(&phy_config);
|
||||||
|
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy);
|
||||||
|
return esp_eth_driver_install(&config, &W5500.handle);
|
||||||
#else
|
#else
|
||||||
return NULL;
|
return ESP_ERR_NOT_SUPPORTED;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_config(eth_config_t* ethernet_config) {
|
static void init_config(eth_config_t* ethernet_config) {
|
||||||
}
|
esp_netif_inherent_config_t loc_esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH();
|
||||||
|
devcfg.command_bits = 16; // Actually it's the address phase in W5500 SPI frame
|
||||||
|
devcfg.address_bits = 8; // Actually it's the control phase in W5500 SPI frame
|
||||||
|
devcfg.mode = 0;
|
||||||
|
devcfg.clock_speed_hz = ethernet_config->speed > 0 ? ethernet_config->speed : SPI_MASTER_FREQ_20M; // default speed
|
||||||
|
devcfg.queue_size = 20;
|
||||||
|
devcfg.spics_io_num = ethernet_config->cs;
|
||||||
|
memcpy(&esp_netif_config, &loc_esp_netif_config, sizeof(loc_esp_netif_config));
|
||||||
|
cfg_spi.base = &esp_netif_config,
|
||||||
|
cfg_spi.stack = ESP_NETIF_NETSTACK_DEFAULT_ETH;
|
||||||
|
W5500.cfg_netif = &cfg_spi;
|
||||||
|
W5500.devcfg = &devcfg;
|
||||||
|
W5500.start = start;
|
||||||
|
W5500.spi = true;
|
||||||
|
W5500.rmii = false;
|
||||||
|
|
||||||
static network_ethernet_driver_t W5500 = {
|
}
|
||||||
.mac_new = mac_new,
|
|
||||||
.phy_new = phy_new,
|
|
||||||
.init_config = init_config,
|
|
||||||
#ifdef CONFIG_ETH_SPI_ETHERNET_W5500
|
|
||||||
.valid = true,
|
|
||||||
#else
|
|
||||||
.valid = false,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
network_ethernet_driver_t* W5500_Detect(char* Driver, network_ethernet_driver_t* Device) {
|
network_ethernet_driver_t* W5500_Detect(char* Driver, network_ethernet_driver_t* Device) {
|
||||||
if (!strcasestr(Driver, "W5500"))
|
if (!strcasestr(Driver, "W5500"))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
W5500.init_config = init_config;
|
||||||
|
#ifdef CONFIG_ETH_SPI_ETHERNET_W5500
|
||||||
|
W5500.valid = true;
|
||||||
|
#else
|
||||||
|
W5500.valid = false;
|
||||||
|
#endif
|
||||||
return &W5500;
|
return &W5500;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
#ifdef NETWORK_ETHERNET_LOG_LEVEL
|
||||||
|
#define LOG_LOCAL_LEVEL NETWORK_ETHERNET_LOG_LEVEL
|
||||||
|
#endif
|
||||||
#include "network_ethernet.h"
|
#include "network_ethernet.h"
|
||||||
#include "freertos/timers.h"
|
#include "freertos/timers.h"
|
||||||
#include "globdefs.h"
|
#include "globdefs.h"
|
||||||
@@ -5,14 +8,13 @@
|
|||||||
#include "network_status.h"
|
#include "network_status.h"
|
||||||
#include "platform_config.h"
|
#include "platform_config.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
|
#include "accessors.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
|
||||||
//#include "dnserver.h"
|
//#include "dnserver.h"
|
||||||
|
|
||||||
static char TAG[] = "network_ethernet";
|
static char TAG[] = "network_ethernet";
|
||||||
TimerHandle_t ETH_timer;
|
TimerHandle_t ETH_timer;
|
||||||
esp_eth_handle_t eth_handle = NULL;
|
|
||||||
esp_netif_t* eth_netif = NULL;
|
esp_netif_t* eth_netif = NULL;
|
||||||
EventGroupHandle_t ethernet_event_group;
|
EventGroupHandle_t ethernet_event_group;
|
||||||
const int LINK_UP_BIT = BIT0;
|
const int LINK_UP_BIT = BIT0;
|
||||||
@@ -22,7 +24,6 @@ static network_ethernet_driver_t* network_driver = NULL;
|
|||||||
extern network_ethernet_detect_func_t DM9051_Detect, W5500_Detect, LAN8720_Detect;
|
extern network_ethernet_detect_func_t DM9051_Detect, W5500_Detect, LAN8720_Detect;
|
||||||
static network_ethernet_detect_func_t* drivers[] = {DM9051_Detect, W5500_Detect, LAN8720_Detect, NULL};
|
static network_ethernet_detect_func_t* drivers[] = {DM9051_Detect, W5500_Detect, LAN8720_Detect, NULL};
|
||||||
#define ETH_TIMEOUT_MS (30 * 1000)
|
#define ETH_TIMEOUT_MS (30 * 1000)
|
||||||
static void network_manager_ethernet_ip_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
|
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
*
|
*
|
||||||
@@ -67,7 +68,7 @@ bool network_ethernet_is_up() {
|
|||||||
return (xEventGroupGetBits(ethernet_event_group) & LINK_UP_BIT)!=0;
|
return (xEventGroupGetBits(ethernet_event_group) & LINK_UP_BIT)!=0;
|
||||||
}
|
}
|
||||||
bool network_ethernet_enabled() {
|
bool network_ethernet_enabled() {
|
||||||
return eth_handle != NULL;
|
return network_driver !=NULL && network_driver->handle != NULL;
|
||||||
}
|
}
|
||||||
bool network_ethernet_wait_for_link(uint16_t max_wait_ms){
|
bool network_ethernet_wait_for_link(uint16_t max_wait_ms){
|
||||||
if(!network_ethernet_enabled()) return false;
|
if(!network_ethernet_enabled()) return false;
|
||||||
@@ -89,75 +90,33 @@ bool network_ethernet_wait_for_link(uint16_t max_wait_ms){
|
|||||||
static void ETH_Timeout(void* timer_id);
|
static void ETH_Timeout(void* timer_id);
|
||||||
void destroy_network_ethernet() {
|
void destroy_network_ethernet() {
|
||||||
}
|
}
|
||||||
static void set_host_name() {
|
|
||||||
ESP_LOGE(TAG, "TODO: Find a way to set the host name here!");
|
|
||||||
// esp_err_t err;
|
|
||||||
// ESP_LOGD(TAG, "Retrieving host name from nvs");
|
|
||||||
// char* host_name = (char*)config_alloc_get(NVS_TYPE_STR, "host_name");
|
|
||||||
// if (host_name == NULL) {
|
|
||||||
// ESP_LOGE(TAG, "Could not retrieve host name from nvs");
|
|
||||||
// } else {
|
|
||||||
// if (!network_ethernet_enabled()) {
|
|
||||||
// ESP_LOGE(TAG, "Cannot set name on a disabled interface");
|
|
||||||
// } else {
|
|
||||||
// ESP_LOGD(TAG, "Setting host name to : %s", host_name);
|
|
||||||
// if ((err = esp_netif_set_hostname(eth_handle, host_name)) != ESP_OK) {
|
|
||||||
// ESP_LOGE(TAG, "Unable to set host name. Error: %s", esp_err_to_name(err));
|
|
||||||
// }
|
|
||||||
// ESP_LOGD(TAG, "Done setting host name to : %s", host_name);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// FREE_AND_NULL(host_name);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
static void network_ethernet_print_config(const eth_config_t* eth_config) {
|
static void network_ethernet_print_config(const eth_config_t* eth_config) {
|
||||||
// #if defined(CONFIG_ETH_PHY_INTERFACE_RMII)
|
ESP_LOGI(TAG,"Ethernet config: \n model: %s, valid: %s, type: %s, mdc:%d, mdio:%d, rst:%d, mosi:%d, miso:%d, intr:%d, cs:%d, speed:%d, clk:%d, host:%s(%d)",
|
||||||
// if(eth_config->)
|
eth_config->model, eth_config->valid?"YES":"NO",eth_config->spi?"SPI":"RMII", eth_config->mdc, eth_config->mdio, eth_config->rst, eth_config->mosi, eth_config->miso, eth_config->intr, eth_config->cs, eth_config->speed, eth_config->clk, eth_config->host==0?"SPI1":eth_config->host==1?"SPI2":eth_config->host==2?"SPI3":"",eth_config->host);
|
||||||
// ESP_LOGI(TAG,
|
|
||||||
// "Model: %s, rst=%d, mdc=%d, mdio=%d, host=%d, cs=%d, mosi=%d, miso=%d, intr=%d, clk=%d, speed=%d, tx_en=%d, tx0=%d, tx1=%d, rx0=%d, rx1=%d, crs_dv=%d",
|
|
||||||
// eth_config->model, eth_config->rst, eth_config->mdc, eth_config->mdio, eth_config->host, eth_config->cs,
|
|
||||||
// eth_config->mosi, eth_config->miso, eth_config->intr, eth_config->clk, eth_config->speed,
|
|
||||||
// eth_config->tx_en, eth_config->tx0, eth_config->tx1, eth_config->rx0, eth_config->rx1, eth_config->crs_dv);
|
|
||||||
// #else
|
|
||||||
// ESP_LOGI(TAG, "Model: %s, rst=%d, mdc=%d, mdio=%d, host=%d, cs=%d, mosi=%d, miso=%d, intr=%d, clk=%d, speed=%d ",
|
|
||||||
// eth_config->model, eth_config->rst, eth_config->mdc, eth_config->mdio, eth_config->host, eth_config->cs,
|
|
||||||
// eth_config->mosi, eth_config->miso, eth_config->intr, eth_config->clk, eth_config->speed);
|
|
||||||
// :
|
|
||||||
// #endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void init_network_ethernet() {
|
void init_network_ethernet() {
|
||||||
esp_err_t err = ESP_OK;
|
esp_err_t err = ESP_OK;
|
||||||
esp_eth_mac_t* mac;
|
|
||||||
esp_eth_phy_t* phy;
|
|
||||||
eth_config_t eth;
|
eth_config_t eth;
|
||||||
|
ESP_LOGI(TAG, "Attempting to initialize Ethernet");
|
||||||
config_eth_init(ð);
|
config_eth_init(ð);
|
||||||
ESP_LOGD(TAG, "Attempting to initialize Ethernet");
|
if(!eth.valid){
|
||||||
// quick check if we have a valid ethernet configuration
|
ESP_LOGI(TAG,"No Ethernet configuration, or configuration invalid");
|
||||||
if (!eth.valid) {
|
|
||||||
ESP_LOGI(TAG, "No ethernet");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
network_driver = network_ethernet_driver_autodetect(eth.model);
|
|
||||||
if (!network_driver) {
|
|
||||||
messaging_post_message(MESSAGING_ERROR, MESSAGING_CLASS_SYSTEM, "Invalid ethernet Ethernet chip %s", eth.model);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!network_driver->valid) {
|
|
||||||
messaging_post_message(MESSAGING_ERROR, MESSAGING_CLASS_SYSTEM, "Code not compiled for Ethernet chip %s", eth.model);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
network_driver->init_config(ð);
|
network_driver->init_config(ð);
|
||||||
network_ethernet_print_config(ð);
|
network_ethernet_print_config(ð);
|
||||||
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
|
|
||||||
eth_netif = esp_netif_new(&cfg);
|
eth_netif = esp_netif_new(network_driver->cfg_netif);
|
||||||
esp_eth_set_default_handlers(eth_netif);
|
esp_eth_set_default_handlers(eth_netif);
|
||||||
esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, NULL);
|
esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, NULL);
|
||||||
esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, NULL);
|
|
||||||
ethernet_event_group = xEventGroupCreate();
|
ethernet_event_group = xEventGroupCreate();
|
||||||
xEventGroupClearBits(ethernet_event_group, LINK_UP_BIT);
|
xEventGroupClearBits(ethernet_event_group, LINK_UP_BIT);
|
||||||
spi_device_handle_t spi_handle = NULL;
|
spi_device_handle_t spi_handle = NULL;
|
||||||
if (network_driver->eth_config.spi) {
|
if (network_driver->spi) {
|
||||||
spi_host_device_t host = SPI3_HOST;
|
spi_host_device_t host = SPI3_HOST;
|
||||||
|
|
||||||
if (eth.host != -1) {
|
if (eth.host != -1) {
|
||||||
@@ -169,12 +128,18 @@ void init_network_ethernet() {
|
|||||||
.quadwp_io_num = -1,
|
.quadwp_io_num = -1,
|
||||||
.quadhd_io_num = -1,
|
.quadhd_io_num = -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
// can't use SPI0
|
// can't use SPI0
|
||||||
if (eth.host == 1)
|
if (eth.host == 0)
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG,"Cannot use SPI1 host. Defaulting to SPI2");
|
||||||
host = SPI2_HOST;
|
host = SPI2_HOST;
|
||||||
ESP_LOGI(TAG, "Initializing SPI bus on host %d with mosi %d and miso %d", host, eth.mosi, eth.miso);
|
}
|
||||||
err = spi_bus_initialize(host, &buscfg, 1);
|
else {
|
||||||
|
host = eth.host;
|
||||||
|
}
|
||||||
|
ESP_LOGI(TAG, "Initializing SPI bus on host %d (SPI%d) with mosi %d and miso %d", host,host+1, eth.mosi, eth.miso);
|
||||||
|
err = spi_bus_initialize(host, &buscfg, SPI_DMA_CH_AUTO);
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "SPI bus init failed : %s", esp_err_to_name(err));
|
ESP_LOGE(TAG, "SPI bus init failed : %s", esp_err_to_name(err));
|
||||||
}
|
}
|
||||||
@@ -184,38 +149,39 @@ void init_network_ethernet() {
|
|||||||
host = spi_system_host;
|
host = spi_system_host;
|
||||||
}
|
}
|
||||||
if (err == ESP_OK) {
|
if (err == ESP_OK) {
|
||||||
spi_device_interface_config_t devcfg = {
|
ESP_LOGI(TAG, "Adding ethernet SPI on host %d (SPI%d) with mosi %d and miso %d", host,host+1, eth.mosi, eth.miso);
|
||||||
.command_bits = 1,
|
err = spi_bus_add_device(host, network_driver->devcfg, &spi_handle);
|
||||||
.address_bits = 7,
|
|
||||||
.mode = 0,
|
|
||||||
.clock_speed_hz = eth.speed,
|
|
||||||
.spics_io_num = eth.cs,
|
|
||||||
.queue_size = 20};
|
|
||||||
ESP_LOGI(TAG, "Adding ethernet SPI on host %d with mosi %d and miso %d", host, eth.mosi, eth.miso);
|
|
||||||
err = spi_bus_add_device(host, &devcfg, &spi_handle);
|
|
||||||
}
|
}
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "SPI host failed : %s", esp_err_to_name(err));
|
ESP_LOGE(TAG, "SPI host failed : %s", esp_err_to_name(err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (err == ESP_OK) {
|
if (err == ESP_OK) {
|
||||||
ESP_LOGD(TAG, "Setting up ethernet driver");
|
err = network_driver->start(spi_handle,ð);
|
||||||
mac = network_driver->mac_new(spi_handle, ð);
|
|
||||||
phy = network_driver->phy_new(ð);
|
|
||||||
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy);
|
|
||||||
err = esp_eth_driver_install(&config, ð_handle);
|
|
||||||
}
|
}
|
||||||
|
if(err == ESP_OK){
|
||||||
|
uint8_t mac_address[6];
|
||||||
|
esp_read_mac(mac_address,ESP_MAC_ETH);
|
||||||
|
char * mac_string=network_manager_alloc_get_mac_string(mac_address);
|
||||||
|
ESP_LOGD(TAG,"Assigning mac address %s to ethernet interface", STR_OR_BLANK(mac_string));
|
||||||
|
FREE_AND_NULL(mac_string);
|
||||||
|
esp_eth_ioctl(network_driver->handle, ETH_CMD_S_MAC_ADDR, mac_address);
|
||||||
|
}
|
||||||
if (err == ESP_OK) {
|
if (err == ESP_OK) {
|
||||||
ESP_LOGD(TAG, "Attaching ethernet to network interface");
|
ESP_LOGD(TAG, "Attaching ethernet to network interface");
|
||||||
err = esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handle));
|
err = esp_netif_attach(eth_netif, esp_eth_new_netif_glue(network_driver->handle));
|
||||||
}
|
}
|
||||||
if (err == ESP_OK) {
|
if (err == ESP_OK) {
|
||||||
ESP_LOGI(TAG, "Starting ethernet network");
|
ESP_LOGI(TAG, "Starting ethernet network");
|
||||||
err = esp_eth_start(eth_handle);
|
err = esp_eth_start(network_driver->handle);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
messaging_post_message(MESSAGING_ERROR, MESSAGING_CLASS_SYSTEM, "Configuring Ethernet failed: %s", esp_err_to_name(err));
|
messaging_post_message(MESSAGING_ERROR, MESSAGING_CLASS_SYSTEM, "Configuring Ethernet failed: %s", esp_err_to_name(err));
|
||||||
eth_handle = NULL;
|
if(spi_handle) {
|
||||||
|
spi_bus_remove_device(spi_handle);
|
||||||
|
}
|
||||||
|
network_driver->handle = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,18 +201,17 @@ static void eth_event_handler(void* arg, esp_event_base_t event_base, int32_t ev
|
|||||||
esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr);
|
esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr);
|
||||||
ESP_LOGI(TAG, "");
|
ESP_LOGI(TAG, "");
|
||||||
ESP_LOGI(TAG, "Ethernet Link Up, HW Addr %02x:%02x:%02x:%02x:%02x:%02x", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
|
ESP_LOGI(TAG, "Ethernet Link Up, HW Addr %02x:%02x:%02x:%02x:%02x:%02x", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
|
||||||
ESP_LOGD(TAG, "Sending EVENT_ETH_LINK_UP message to network manager");
|
network_async_link_up();
|
||||||
network_manager_async_link_up();
|
|
||||||
break;
|
break;
|
||||||
case ETHERNET_EVENT_DISCONNECTED:
|
case ETHERNET_EVENT_DISCONNECTED:
|
||||||
ESP_LOGI(TAG, "Ethernet Link Down");
|
ESP_LOGI(TAG, "Ethernet Link Down");
|
||||||
xEventGroupClearBits(ethernet_event_group, LINK_UP_BIT);
|
xEventGroupClearBits(ethernet_event_group, LINK_UP_BIT);
|
||||||
ESP_LOGD(TAG, "Sending EVENT_ETH_LINK_DOWN message to network manager");
|
network_async_link_down();
|
||||||
network_manager_async_link_down();
|
|
||||||
break;
|
break;
|
||||||
case ETHERNET_EVENT_START:
|
case ETHERNET_EVENT_START:
|
||||||
ESP_LOGI(TAG, "Ethernet Started. Setting host name");
|
ESP_LOGI(TAG, "Ethernet Started. Setting host name");
|
||||||
set_host_name();
|
network_set_hostname(eth_netif);
|
||||||
|
network_async_success();
|
||||||
break;
|
break;
|
||||||
case ETHERNET_EVENT_STOP:
|
case ETHERNET_EVENT_STOP:
|
||||||
ESP_LOGI(TAG, "Ethernet Stopped");
|
ESP_LOGI(TAG, "Ethernet Stopped");
|
||||||
@@ -254,30 +219,10 @@ static void eth_event_handler(void* arg, esp_event_base_t event_base, int32_t ev
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (event_base == IP_EVENT && event_id == IP_EVENT_ETH_GOT_IP) {
|
}
|
||||||
network_manager_ethernet_ip_event_handler(arg, event_base, event_id, event_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ETH_Timeout(void* timer_id) {
|
static void ETH_Timeout(void* timer_id) {
|
||||||
network_manager_async_fail();
|
network_async_fail();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void network_manager_ethernet_ip_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) {
|
|
||||||
if (event_base != IP_EVENT)
|
|
||||||
return;
|
|
||||||
ip_event_got_ip_t* event = (ip_event_got_ip_t*)event_data;
|
|
||||||
ip_event_got_ip_t* s = event_data;
|
|
||||||
tcpip_adapter_if_t index = s->if_index;
|
|
||||||
esp_netif_ip_info_t* ip_info = &s->ip_info;
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Got an IP address from Ethernet interface #%i. IP=" IPSTR ", Gateway=" IPSTR ", NetMask=" IPSTR ", %s",
|
|
||||||
index,
|
|
||||||
IP2STR(&ip_info->ip),
|
|
||||||
IP2STR(&ip_info->gw),
|
|
||||||
IP2STR(&ip_info->netmask),
|
|
||||||
s->ip_changed ? "Address was changed" : "Address unchanged");
|
|
||||||
ip_event_got_ip_t* parm = malloc(sizeof(ip_event_got_ip_t));
|
|
||||||
memcpy(parm, event_data, sizeof(ip_event_got_ip_t));
|
|
||||||
network_manager_async_got_ip(parm);
|
|
||||||
}
|
|
||||||
@@ -3,19 +3,26 @@
|
|||||||
#include "network_manager.h"
|
#include "network_manager.h"
|
||||||
#include "accessors.h"
|
#include "accessors.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "esp_netif_defaults.h"
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool valid;
|
bool valid;
|
||||||
eth_config_t eth_config;
|
bool rmii;
|
||||||
esp_eth_mac_t* (*mac_new)(spi_device_handle_t spi_handle, eth_config_t * eth_config);
|
bool spi;
|
||||||
esp_eth_phy_t *(*phy_new)( eth_config_t* eth_config);
|
esp_eth_handle_t handle;
|
||||||
|
esp_netif_config_t * cfg_netif;
|
||||||
|
spi_device_interface_config_t * devcfg;
|
||||||
|
// esp_eth_mac_t* (*mac_new)(spi_device_handle_t spi_handle, eth_config_t * eth_config);
|
||||||
|
// esp_eth_phy_t *(*phy_new)( eth_config_t* eth_config);
|
||||||
|
esp_err_t (*start)(spi_device_handle_t spi_handle,eth_config_t *ethernet_config);
|
||||||
void (*init_config)(eth_config_t * eth_config);
|
void (*init_config)(eth_config_t * eth_config);
|
||||||
} network_ethernet_driver_t;
|
} network_ethernet_driver_t;
|
||||||
typedef network_ethernet_driver_t* network_ethernet_detect_func_t(const char* Driver);
|
typedef network_ethernet_driver_t* network_ethernet_detect_func_t(const char* Driver);
|
||||||
|
network_ethernet_driver_t* network_ethernet_driver_autodetect(const char* Driver);
|
||||||
void destroy_network_ethernet();
|
void destroy_network_ethernet();
|
||||||
void init_network_ethernet();
|
void init_network_ethernet();
|
||||||
bool network_ethernet_wait_for_link(uint16_t max_wait_ms);
|
bool network_ethernet_wait_for_link(uint16_t max_wait_ms);
|
||||||
|
|||||||
@@ -1,34 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2017-2019 Tony Pottier
|
Copyright (c) 2017-2021 Sebastien L
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
|
|
||||||
@file wifi_manager.c
|
|
||||||
@author Tony Pottier
|
|
||||||
@brief Defines all functions necessary for esp32 to connect to a wifi/scan wifis
|
|
||||||
|
|
||||||
Contains the freeRTOS task and all necessary support
|
|
||||||
|
|
||||||
@see https://idyl.io
|
|
||||||
@see https://github.com/tonyp7/esp32-wifi-manager
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef NETWORK_MANAGER_LOG_LEVEL
|
||||||
|
#define LOG_LOCAL_LEVEL NETWORK_MANAGER_LOG_LEVEL
|
||||||
|
#endif
|
||||||
#include "network_manager.h"
|
#include "network_manager.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -37,16 +13,15 @@ Contains the freeRTOS task and all necessary support
|
|||||||
#include "network_ethernet.h"
|
#include "network_ethernet.h"
|
||||||
#include "network_status.h"
|
#include "network_status.h"
|
||||||
#include "network_wifi.h"
|
#include "network_wifi.h"
|
||||||
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
|
|
||||||
|
#include "dns_server.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "platform_esp32.h"
|
|
||||||
|
|
||||||
|
|
||||||
#include "esp_system.h"
|
#include "esp_system.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "platform_esp32.h"
|
||||||
|
|
||||||
#include "freertos/task.h"
|
|
||||||
#include "esp_netif.h"
|
#include "esp_netif.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
|
||||||
#include "cJSON.h"
|
#include "cJSON.h"
|
||||||
#include "cmd_system.h"
|
#include "cmd_system.h"
|
||||||
@@ -62,59 +37,696 @@ Contains the freeRTOS task and all necessary support
|
|||||||
#include "lwip/netdb.h"
|
#include "lwip/netdb.h"
|
||||||
#include "mdns.h"
|
#include "mdns.h"
|
||||||
#include "messaging.h"
|
#include "messaging.h"
|
||||||
#include "state_machine.h"
|
|
||||||
|
|
||||||
#include "platform_config.h"
|
#include "platform_config.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
|
||||||
#include "accessors.h"
|
#include "accessors.h"
|
||||||
|
#include "esp_err.h"
|
||||||
#include "globdefs.h"
|
#include "globdefs.h"
|
||||||
#include "http_server_handlers.h"
|
#include "http_server_handlers.h"
|
||||||
|
#include "network_manager.h"
|
||||||
|
|
||||||
|
QueueHandle_t network_queue;
|
||||||
|
BaseType_t network_task_handle;
|
||||||
|
static const char TAG[] = "network";
|
||||||
|
static TaskHandle_t task_network_manager = NULL;
|
||||||
|
RTC_NOINIT_ATTR static bool s_wifi_prioritized = false;
|
||||||
|
extern esp_reset_reason_t xReason;
|
||||||
|
typedef struct network_callback {
|
||||||
|
network_status_reached_cb cb;
|
||||||
|
nm_state_t state;
|
||||||
|
int sub_state;
|
||||||
|
const char* from;
|
||||||
|
SLIST_ENTRY(network_callback)
|
||||||
|
next; //!< next callback
|
||||||
|
} network_callback_t;
|
||||||
|
|
||||||
|
/** linked list of command structures */
|
||||||
|
static SLIST_HEAD(cb_list, network_callback) s_cb_list;
|
||||||
|
|
||||||
|
network_t NM;
|
||||||
|
|
||||||
|
|
||||||
|
//! Create and initialize the array of state machines.
|
||||||
|
state_machine_t* const SM[] = {(state_machine_t*)&NM};
|
||||||
|
static void network_timer_cb(void* timer_id);
|
||||||
|
int get_root_id(const state_t * state);
|
||||||
|
const state_t* get_root( const state_t* const state);
|
||||||
|
static void network_task(void* pvParameters);
|
||||||
|
|
||||||
|
void network_start_stop_dhcp(esp_netif_t* netif, bool start) {
|
||||||
|
tcpip_adapter_dhcp_status_t status;
|
||||||
|
esp_err_t err = ESP_OK;
|
||||||
|
ESP_LOGD(TAG, "Checking if DHCP client for STA interface is running");
|
||||||
|
if (!netif) {
|
||||||
|
ESP_LOGE(TAG, "Invalid adapter. Cannot start/stop dhcp. ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if((err=esp_netif_dhcpc_get_status(netif, &status))!=ESP_OK){
|
||||||
|
ESP_LOGE(TAG,"Error retrieving dhcp status : %s", esp_err_to_name(err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (status)
|
||||||
|
{
|
||||||
|
case ESP_NETIF_DHCP_STARTED:
|
||||||
|
if(start){
|
||||||
|
ESP_LOGD(TAG, "DHCP client already started");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ESP_LOGI(TAG, "Stopping DHCP client");
|
||||||
|
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_netif_dhcpc_stop(netif));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ESP_NETIF_DHCP_STOPPED:
|
||||||
|
if(start){
|
||||||
|
ESP_LOGI(TAG, "Starting DHCP client");
|
||||||
|
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_netif_dhcpc_start(netif));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ESP_LOGI(TAG, "DHCP client already started");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ESP_NETIF_DHCP_INIT:
|
||||||
|
if(start){
|
||||||
|
ESP_LOGI(TAG, "Starting DHCP client");
|
||||||
|
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_netif_dhcpc_start(netif));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ESP_LOGI(TAG, "Stopping DHCP client");
|
||||||
|
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_netif_dhcpc_stop(netif));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ESP_LOGW(TAG,"Unknown DHCP status");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void network_start_stop_dhcps(esp_netif_t* netif, bool start) {
|
||||||
|
tcpip_adapter_dhcp_status_t status;
|
||||||
|
esp_err_t err = ESP_OK;
|
||||||
|
ESP_LOGD(TAG, "Checking if DHCP server is running");
|
||||||
|
if (!netif) {
|
||||||
|
ESP_LOGE(TAG, "Invalid adapter. Cannot start/stop dhcp server. ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if((err=esp_netif_dhcps_get_status(netif, &status))!=ESP_OK){
|
||||||
|
ESP_LOGE(TAG,"Error retrieving dhcp server status : %s", esp_err_to_name(err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (status)
|
||||||
|
{
|
||||||
|
case ESP_NETIF_DHCP_STARTED:
|
||||||
|
if(start){
|
||||||
|
ESP_LOGD(TAG, "DHCP server already started");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ESP_LOGI(TAG, "Stopping DHCP server");
|
||||||
|
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_netif_dhcps_stop(netif));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ESP_NETIF_DHCP_STOPPED:
|
||||||
|
if(start){
|
||||||
|
ESP_LOGI(TAG, "Starting DHCP server");
|
||||||
|
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_netif_dhcps_start(netif));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ESP_LOGI(TAG, "DHCP server already stopped");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ESP_NETIF_DHCP_INIT:
|
||||||
|
if(start){
|
||||||
|
ESP_LOGI(TAG, "Starting DHCP server");
|
||||||
|
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_netif_dhcps_start(netif));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ESP_LOGI(TAG, "Stopping DHCP server");
|
||||||
|
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_netif_dhcps_stop(netif));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ESP_LOGW(TAG,"Unknown DHCP status");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*********************************************************************************************
|
||||||
|
* String conversion routines
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef STR_OR_BLANK
|
#define ADD_ROOT(name,...) CASE_TO_STR(name);
|
||||||
#define STR_OR_BLANK(p) p == NULL ? "" : p
|
#define ADD_ROOT_LEAF(name,...) CASE_TO_STR(name);
|
||||||
#endif
|
#define ADD_LEAF(name,...) CASE_TO_STR(name);
|
||||||
|
#define ADD_EVENT(name) CASE_TO_STR(name);
|
||||||
|
#define ADD_FIRST_EVENT(name) CASE_TO_STR(name);
|
||||||
|
static const char* state_to_string(const state_t * state) {
|
||||||
|
if(!state) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
switch (state->Parent?state->Parent->Id:state->Id) {
|
||||||
|
ALL_NM_STATE
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
static const char* wifi_state_to_string(mn_wifi_active_state_t state) {
|
||||||
|
switch (state) {
|
||||||
|
ALL_WIFI_STATE(,)
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
static const char* eth_state_to_string(mn_eth_active_state_t state) {
|
||||||
|
switch (state) {
|
||||||
|
ALL_ETH_STATE(,)
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
static const char* wifi_configuring_state_to_string(mn_wifi_configuring_state_t state) {
|
||||||
|
switch (state) {
|
||||||
|
ALL_WIFI_CONFIGURING_STATE(,)
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
static const char* sub_state_to_string(const state_t * state) {
|
||||||
|
if(!state) {
|
||||||
|
return "N/A";
|
||||||
|
}
|
||||||
|
int root_id = get_root_id(state);
|
||||||
|
switch (root_id)
|
||||||
|
{
|
||||||
|
case NETWORK_ETH_ACTIVE_STATE:
|
||||||
|
return eth_state_to_string(state->Id);
|
||||||
|
break;
|
||||||
|
case NETWORK_WIFI_ACTIVE_STATE:
|
||||||
|
return wifi_state_to_string(state->Id);
|
||||||
|
case NETWORK_WIFI_CONFIGURING_ACTIVE_STATE:
|
||||||
|
return wifi_configuring_state_to_string(state->Id);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return "*";
|
||||||
|
}
|
||||||
|
|
||||||
//EventGroupHandle_t wifi_manager_event_group;
|
static const char* event_to_string(network_event_t state) {
|
||||||
void (**cb_ptr_arr)(void*) = NULL;
|
switch (state) {
|
||||||
|
ALL_NM_EVENTS
|
||||||
|
|
||||||
/* @brief tag used for ESP serial console messages */
|
default:
|
||||||
//static const char TAG[] = "network_manager";
|
break;
|
||||||
|
}
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
/* @brief indicate that the ESP32 is currently connected. */
|
#undef ADD_EVENT
|
||||||
const int WIFI_MANAGER_WIFI_CONNECTED_BIT = BIT0;
|
#undef ADD_FIRST_EVENT
|
||||||
const int WIFI_MANAGER_AP_STA_CONNECTED_BIT = BIT1;
|
#undef ADD_ROOT
|
||||||
/* @brief Set automatically once the SoftAP is started */
|
#undef ADD_ROOT_LEAF
|
||||||
const int WIFI_MANAGER_AP_STARTED_BIT = BIT2;
|
#undef ADD_LEAF
|
||||||
/* @brief When set, means a client requested to connect to an access point.*/
|
|
||||||
const int WIFI_MANAGER_REQUEST_STA_CONNECT_BIT = BIT3;
|
|
||||||
/* @brief This bit is set automatically as soon as a connection was lost */
|
|
||||||
const int WIFI_MANAGER_STA_DISCONNECT_BIT = BIT4;
|
|
||||||
/* @brief When set, means the wifi manager attempts to restore a previously saved connection at startup. */
|
|
||||||
const int WIFI_MANAGER_REQUEST_RESTORE_STA_BIT = BIT5;
|
|
||||||
/* @brief When set, means a client requested to disconnect from currently connected AP. */
|
|
||||||
const int WIFI_MANAGER_REQUEST_WIFI_DISCONNECT_BIT = BIT6;
|
|
||||||
/* @brief When set, means a scan is in progress */
|
|
||||||
const int WIFI_MANAGER_SCAN_BIT = BIT7;
|
|
||||||
/* @brief When set, means user requested for a disconnect */
|
|
||||||
const int WIFI_MANAGER_REQUEST_DISCONNECT_BIT = BIT8;
|
|
||||||
/* @brief When set, means user requested connecting to a new network and it failed */
|
|
||||||
const int WIFI_MANAGER_REQUEST_STA_CONNECT_FAILED_BIT = BIT9;
|
|
||||||
|
|
||||||
/* @brief task handle for the main wifi_manager task */
|
typedef struct {
|
||||||
|
int parent_state;
|
||||||
|
int sub_state_last ;
|
||||||
|
} max_sub_states_t;
|
||||||
|
static const max_sub_states_t state_max[] = {
|
||||||
|
{ .parent_state = NETWORK_INSTANTIATED_STATE, .sub_state_last = 0 },
|
||||||
|
{.parent_state = NETWORK_ETH_ACTIVE_STATE, .sub_state_last = TOTAL_ETH_ACTIVE_STATE-1 },
|
||||||
|
{.parent_state = NETWORK_WIFI_ACTIVE_STATE, .sub_state_last = TOTAL_WIFI_ACTIVE_STATE-1 },
|
||||||
|
{.parent_state = WIFI_CONFIGURING_STATE, .sub_state_last = TOTAL_WIFI_CONFIGURING_STATE-1 },
|
||||||
|
{.parent_state = WIFI_CONFIGURING_STATE, .sub_state_last = TOTAL_WIFI_CONFIGURING_STATE-1 },
|
||||||
|
{.parent_state =-1}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void network_start() {
|
||||||
|
|
||||||
|
if(xReason == ESP_RST_POWERON ){
|
||||||
|
ESP_LOGD(TAG, "Power on reset, initializing wifi priotitized to false");
|
||||||
|
s_wifi_prioritized = false;
|
||||||
|
}
|
||||||
|
ESP_LOGD(TAG, " Creating message queue");
|
||||||
|
network_queue = xQueueCreate(3, sizeof(queue_message));
|
||||||
|
ESP_LOGD(TAG, " Creating network manager task");
|
||||||
|
network_task_handle = xTaskCreate(&network_task, "network", 4096, NULL, WIFI_MANAGER_TASK_PRIORITY, &task_network_manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void event_logger(uint32_t state_machine, uint32_t state, uint32_t event) {
|
||||||
|
ESP_LOGI(TAG, "Handling network manager event state Id %d->[%s]", state, event_to_string(event));
|
||||||
|
}
|
||||||
|
static const char * get_state_machine_result_string(state_machine_result_t result) {
|
||||||
|
switch(result) {
|
||||||
|
case EVENT_HANDLED:
|
||||||
|
return "EVENT_HANDLED";
|
||||||
|
case EVENT_UN_HANDLED:
|
||||||
|
return "EVENT_UN_HANDLED";
|
||||||
|
case TRIGGERED_TO_SELF:
|
||||||
|
return "TRIGGERED_TO_SELF";
|
||||||
|
}
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
static void result_logger(uint32_t state, state_machine_result_t result) {
|
||||||
|
ESP_LOGD(TAG, "Network Manager Result: %s, New State id: %d", get_state_machine_result_string(result) , state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void network_task(void* pvParameters) {
|
||||||
|
queue_message msg;
|
||||||
|
BaseType_t xStatus;
|
||||||
|
initialize_network_handlers((state_machine_t*)&NM);
|
||||||
|
network_async(EN_START);
|
||||||
|
|
||||||
|
/* main processing loop */
|
||||||
|
for (;;) {
|
||||||
|
xStatus = xQueueReceive(network_queue, &msg, portMAX_DELAY);
|
||||||
|
|
||||||
|
if (xStatus == pdPASS) {
|
||||||
|
// pass the event to the sync processor
|
||||||
|
NM.event_parameters = &msg;
|
||||||
|
NM.Machine.Event = msg.trigger;
|
||||||
|
if (dispatch_event(SM, 1, event_logger, result_logger) == EVENT_UN_HANDLED) {
|
||||||
|
network_manager_format_from_to_states(ESP_LOG_ERROR,"Unhandled Event",NULL,NM.Machine.State,msg.trigger,false,"network manager");
|
||||||
|
}
|
||||||
|
} /* end of if status=pdPASS */
|
||||||
|
} /* end of for loop */
|
||||||
|
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int get_max_substate(nm_state_t state){
|
||||||
|
for(int i=0;state_max[i].parent_state!=-1;i++){
|
||||||
|
if(state_max[i].parent_state == state){
|
||||||
|
return state_max[i].sub_state_last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
esp_err_t network_register_state_callback(nm_state_t state,int sub_state, const char* from, network_status_reached_cb cb) {
|
||||||
|
network_callback_t* item = NULL;
|
||||||
|
if (!cb) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
item = calloc(1, sizeof(*item));
|
||||||
|
if (item == NULL) {
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
}
|
||||||
|
if(sub_state != -1 && sub_state>get_max_substate(state)){
|
||||||
|
// sub state has to be valid
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
item->state = state;
|
||||||
|
item->cb = cb;
|
||||||
|
item->from = from;
|
||||||
|
item->sub_state=sub_state;
|
||||||
|
network_callback_t* last = SLIST_FIRST(&s_cb_list);
|
||||||
|
if (last == NULL) {
|
||||||
|
SLIST_INSERT_HEAD(&s_cb_list, item, next);
|
||||||
|
} else {
|
||||||
|
network_callback_t* it;
|
||||||
|
while ((it = SLIST_NEXT(last, next)) != NULL) {
|
||||||
|
last = it;
|
||||||
|
}
|
||||||
|
SLIST_INSERT_AFTER(last, item, next);
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
const state_t* get_root( const state_t* const state){
|
||||||
|
if(!state) return NULL;
|
||||||
|
return state->Parent==NULL?state: get_root(state->Parent);
|
||||||
|
}
|
||||||
|
int get_root_id(const state_t * state){
|
||||||
|
if(!state) return -1;
|
||||||
|
return state->Parent==NULL?state->Id: get_root_id(state->Parent);
|
||||||
|
}
|
||||||
|
|
||||||
void wifi_manager_set_callback(message_code_t message_code, void (*func_ptr)(void*)) {
|
static bool is_root_state(const state_t * state){
|
||||||
if (cb_ptr_arr && message_code < MESSAGE_CODE_COUNT) {
|
return state->Parent==NULL;
|
||||||
cb_ptr_arr[message_code] = func_ptr;
|
}
|
||||||
|
static bool is_current_state(const state_t* state, nm_state_t state_id, int sub_state_id){
|
||||||
|
return get_root(state)->Id == state_id && (sub_state_id==-1 || (!is_root_state(state) && state->Id == sub_state_id) );
|
||||||
|
}
|
||||||
|
void network_execute_cb(state_machine_t* const state_machine, const char * caller) {
|
||||||
|
network_callback_t* it;
|
||||||
|
SLIST_FOREACH(it, &s_cb_list, next) {
|
||||||
|
if (is_current_state(state_machine->State,it->state, it->sub_state)) {
|
||||||
|
char * cb_prefix= messaging_alloc_format_string("BEGIN Executing Callback %s", it->from) ;
|
||||||
|
NETWORK_DEBUG_STATE_MACHINE(true,STR_OR_BLANK(cb_prefix),state_machine,false, STR_OR_BLANK(caller));
|
||||||
|
FREE_AND_NULL(cb_prefix);
|
||||||
|
it->cb((nm_state_t)get_root(state_machine->State)->Id, is_root_state(state_machine->State)?-1:state_machine->State->Id);
|
||||||
|
cb_prefix= messaging_alloc_format_string("END Executing Callback %s", it->from) ;
|
||||||
|
NETWORK_DEBUG_STATE_MACHINE(false,STR_OR_BLANK(cb_prefix),state_machine,false, STR_OR_BLANK(caller));
|
||||||
|
FREE_AND_NULL(cb_prefix);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool network_is_wifi_prioritized() {
|
||||||
|
eth_config_t eth_config;
|
||||||
|
config_eth_init(ð_config);
|
||||||
|
// char* prioritize = (char*)config_alloc_get_default(NVS_TYPE_STR, "prio_wifi", "N", 0);
|
||||||
|
// bool result = strcasecmp("N", prioritize);
|
||||||
|
bool result = s_wifi_prioritized;
|
||||||
|
if(result){
|
||||||
|
result = network_wifi_get_known_count()>0 || !eth_config.valid;
|
||||||
|
ESP_LOGD(TAG,"Wifi is prioritized with %d known access points.%s %s",network_wifi_get_known_count(),eth_config.valid?" And a valid ethernet adapter":"",result?"Wifi prioritized":"Ethernet prioritized");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void network_prioritize_wifi(bool activate) {
|
||||||
|
if(s_wifi_prioritized == activate) return;
|
||||||
|
s_wifi_prioritized = activate;
|
||||||
|
ESP_LOGI(TAG,"Wifi is %s prioritized",activate?"":"not");
|
||||||
|
// if (network_is_wifi_prioritized() != activate) {
|
||||||
|
// ESP_LOGW(TAG, "Wifi will %s be prioritized on next boot", activate ? "" : "NOT");
|
||||||
|
// config_set_value(NVS_TYPE_STR, "prio_wifi", activate ? "Y" : "N");
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void network_manager_format_state_machine(esp_log_level_t level, const char* prefix, state_machine_t* state_machine, bool show_source, const char * caller) {
|
||||||
|
state_t const* source_state = NULL;
|
||||||
|
state_t const* current_state = NULL;
|
||||||
|
network_event_t event = -1;
|
||||||
|
MEMTRACE_PRINT_DELTA();
|
||||||
|
if (state_machine) {
|
||||||
|
source_state = ((network_t *)state_machine)->source_state;
|
||||||
|
current_state = state_machine->State;
|
||||||
|
event = state_machine->Event;
|
||||||
|
network_manager_format_from_to_states(level, prefix, source_state, current_state, event, show_source,caller);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ESP_LOG_LEVEL(level, TAG, "%s - %s -> [%s]",
|
||||||
|
STR_OR_BLANK(caller),
|
||||||
|
prefix,
|
||||||
|
event_to_string(event));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
void network_manager_format_from_to_states(esp_log_level_t level, const char* prefix, const state_t * from_state,const state_t * current_state, network_event_t event,bool show_source, const char * caller) {
|
||||||
|
const char* source_state = "";
|
||||||
|
const char* source_sub_state = "";
|
||||||
|
const char* state = "N/A";
|
||||||
|
const char* sub_state = "N/A";
|
||||||
|
|
||||||
|
if (current_state) {
|
||||||
|
state = state_to_string(current_state);
|
||||||
|
sub_state = sub_state_to_string(current_state);
|
||||||
|
}
|
||||||
|
if (!from_state) {
|
||||||
|
source_state = "N/A";
|
||||||
|
} else {
|
||||||
|
source_state = state_to_string(from_state);
|
||||||
|
source_sub_state = sub_state_to_string(from_state);
|
||||||
|
}
|
||||||
|
if (show_source) {
|
||||||
|
ESP_LOG_LEVEL(level, TAG, "%s %s %s(%s)->%s(%s) [%s]",
|
||||||
|
STR_OR_BLANK(caller),
|
||||||
|
prefix,
|
||||||
|
source_state,
|
||||||
|
source_sub_state,
|
||||||
|
state,
|
||||||
|
sub_state,
|
||||||
|
event_to_string(event));
|
||||||
|
} else {
|
||||||
|
ESP_LOG_LEVEL(level, TAG, "%s %s %s(%s) [%s]",
|
||||||
|
STR_OR_BLANK(caller),
|
||||||
|
prefix,
|
||||||
|
state,
|
||||||
|
sub_state,
|
||||||
|
event_to_string(event));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void network_async(network_event_t trigger) {
|
||||||
|
queue_message msg;
|
||||||
|
memset(&msg,0x00,sizeof(msg));
|
||||||
|
msg.trigger = trigger;
|
||||||
|
ESP_LOGD(TAG, "Posting event %s directly", event_to_string(trigger));
|
||||||
|
xQueueSendToBack(network_queue, &msg, portMAX_DELAY);
|
||||||
|
}
|
||||||
|
void network_async_fail() {
|
||||||
|
network_async(EN_FAIL);
|
||||||
|
}
|
||||||
|
void network_async_success() {
|
||||||
|
network_async(EN_SUCCESS);
|
||||||
|
}
|
||||||
|
void network_async_connected(){
|
||||||
|
network_async(EN_CONNECTED);
|
||||||
|
}
|
||||||
|
void network_async_link_up() {
|
||||||
|
network_async(EN_LINK_UP);
|
||||||
|
}
|
||||||
|
void network_async_link_down() {
|
||||||
|
network_async(EN_LINK_DOWN);
|
||||||
|
}
|
||||||
|
void network_async_configure() {
|
||||||
|
network_async(EN_CONFIGURE);
|
||||||
|
}
|
||||||
|
void network_async_got_ip() {
|
||||||
|
network_async(EN_GOT_IP);
|
||||||
|
}
|
||||||
|
void network_async_eth_got_ip() {
|
||||||
|
network_async(EN_ETH_GOT_IP);
|
||||||
|
}
|
||||||
|
void network_async_timer() {
|
||||||
|
network_async(EN_TIMER);
|
||||||
|
}
|
||||||
|
void network_async_start() {
|
||||||
|
network_async(EN_START);
|
||||||
|
}
|
||||||
|
void network_async_scan() {
|
||||||
|
network_async(EN_SCAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void network_async_update_status() {
|
||||||
|
network_async(EN_UPDATE_STATUS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void network_async_delete() {
|
||||||
|
network_async(EN_DELETE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void network_async_scan_done() {
|
||||||
|
network_async(EN_SCAN_DONE);
|
||||||
|
}
|
||||||
|
void network_async_connect(const char * ssid, const char * password) {
|
||||||
|
queue_message msg;
|
||||||
|
memset(&msg,0x00,sizeof(msg));
|
||||||
|
msg.trigger = EN_CONNECT_NEW;
|
||||||
|
msg.ssid = strdup_psram(ssid);
|
||||||
|
if(password && strlen(password) >0){
|
||||||
|
msg.password = strdup_psram(password);
|
||||||
|
}
|
||||||
|
ESP_LOGD(TAG, "Posting event %s", event_to_string(msg.trigger));
|
||||||
|
xQueueSendToBack(network_queue, &msg, portMAX_DELAY);
|
||||||
|
}
|
||||||
|
void network_async_lost_connection(wifi_event_sta_disconnected_t* disconnected_event) {
|
||||||
|
queue_message msg;
|
||||||
|
memset(&msg,0x00,sizeof(msg));
|
||||||
|
msg.trigger = EN_LOST_CONNECTION;
|
||||||
|
ESP_LOGD(TAG, "Posting event %s", event_to_string(msg.trigger));
|
||||||
|
msg.disconnected_event = malloc_init_external(sizeof(wifi_event_sta_disconnected_t));
|
||||||
|
if(msg.disconnected_event){
|
||||||
|
memcpy(msg.disconnected_event, disconnected_event,sizeof(wifi_event_sta_disconnected_t));
|
||||||
|
xQueueSendToBack(network_queue, &msg, portMAX_DELAY);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ESP_LOGE(TAG,"Unable to post lost connection event.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void network_async_reboot(reboot_type_t rtype) {
|
||||||
|
queue_message msg;
|
||||||
|
memset(&msg,0x00,sizeof(msg));
|
||||||
|
msg.trigger = EN_REBOOT;
|
||||||
|
msg.rtype = rtype;
|
||||||
|
ESP_LOGD(TAG, "Posting event %s - type %d", event_to_string(msg.trigger),rtype);
|
||||||
|
xQueueSendToBack(network_queue, &msg, portMAX_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void network_reboot_ota(char* url) {
|
||||||
|
queue_message msg;
|
||||||
|
memset(&msg,0x00,sizeof(msg));
|
||||||
|
|
||||||
|
if (url == NULL) {
|
||||||
|
msg.trigger = EN_REBOOT;
|
||||||
|
msg.rtype = OTA;
|
||||||
|
ESP_LOGD(TAG, "Posting event %s - type %d", event_to_string(msg.trigger),msg.rtype);
|
||||||
|
} else {
|
||||||
|
msg.trigger = EN_REBOOT_URL;
|
||||||
|
ESP_LOGD(TAG, "Posting event %s - type reboot URL", event_to_string(msg.trigger));
|
||||||
|
msg.strval = strdup_psram(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
xQueueSendToBack(network_queue, &msg, portMAX_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
network_t* network_get_state_machine() {
|
||||||
|
return &NM;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void network_timer_cb(void* timer_id) {
|
||||||
|
network_async_timer();
|
||||||
|
}
|
||||||
|
esp_netif_t* network_get_active_interface() {
|
||||||
|
if (NM.wifi_ap_netif && (network_wifi_is_ap_mode() || network_wifi_is_ap_sta_mode())) {
|
||||||
|
return NM.wifi_ap_netif;
|
||||||
|
} else if (NM.wifi_netif && network_wifi_is_sta_mode()) {
|
||||||
|
return NM.wifi_netif;
|
||||||
|
}
|
||||||
|
return NM.eth_netif;
|
||||||
|
}
|
||||||
|
bool network_is_interface_connected(esp_netif_t* interface) {
|
||||||
|
esp_err_t err = ESP_OK;
|
||||||
|
tcpip_adapter_ip_info_t ipInfo;
|
||||||
|
if(!interface){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
err = network_get_ip_info_for_netif(interface, &ipInfo);
|
||||||
|
if(err != ESP_OK){
|
||||||
|
ESP_LOGD(TAG,"network_get_ip_info_for_netif returned %s", esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
return ((err == ESP_OK) && (ipInfo.ip.addr != IPADDR_ANY));
|
||||||
|
}
|
||||||
|
static esp_netif_t* get_connected_interface() {
|
||||||
|
esp_netif_t* interface = NULL;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
switch (i) {
|
||||||
|
case 0:
|
||||||
|
// try the active interface
|
||||||
|
interface = network_get_active_interface();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
interface = NM.wifi_ap_netif;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
interface = NM.wifi_netif;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
interface = NM.eth_netif;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (interface && network_is_interface_connected(interface)) {
|
||||||
|
ESP_LOGD(TAG,"Found connected interface in iteration #%d",i);
|
||||||
|
return interface;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ESP_LOGD(TAG,"No connected interface found");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
esp_err_t network_get_ip_info_for_netif(esp_netif_t* netif, tcpip_adapter_ip_info_t* ipInfo) {
|
||||||
|
esp_netif_ip_info_t loc_ip_info;
|
||||||
|
if (!ipInfo ) {
|
||||||
|
ESP_LOGE(TAG, "Invalid pointer for ipInfo");
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
if (!netif) {
|
||||||
|
ESP_LOGE(TAG, "Invalid pointer for netif");
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
memset(ipInfo,0x00,sizeof(tcpip_adapter_ip_info_t));
|
||||||
|
esp_err_t err= esp_netif_get_ip_info(netif, &loc_ip_info);
|
||||||
|
if(err==ESP_OK){
|
||||||
|
ip4_addr_set(&(ipInfo->ip),&loc_ip_info.ip);
|
||||||
|
ip4_addr_set(&(ipInfo->gw),&loc_ip_info.gw);
|
||||||
|
ip4_addr_set(&(ipInfo->netmask),&loc_ip_info.netmask);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
esp_err_t network_get_ip_info(tcpip_adapter_ip_info_t* ipInfo) {
|
||||||
|
esp_netif_t* netif= get_connected_interface();
|
||||||
|
if(netif){
|
||||||
|
return network_get_ip_info_for_netif(netif,ipInfo);
|
||||||
|
}
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t network_get_hostname(const char** hostname) {
|
||||||
|
return esp_netif_get_hostname(get_connected_interface(), hostname);
|
||||||
|
}
|
||||||
|
|
||||||
|
void network_set_timer(uint16_t duration) {
|
||||||
|
if (duration > 0) {
|
||||||
|
if (!NM.state_timer) {
|
||||||
|
ESP_LOGD(TAG, "Starting new pulse check timer with period of %u ms.", duration);
|
||||||
|
NM.state_timer = xTimerCreate("background STA", pdMS_TO_TICKS(duration), pdFALSE, NULL, network_timer_cb);
|
||||||
|
} else {
|
||||||
|
ESP_LOGD(TAG, "Changing the pulse timer period to %u ms.", duration);
|
||||||
|
xTimerChangePeriod(NM.state_timer, pdMS_TO_TICKS(duration), portMAX_DELAY);
|
||||||
|
}
|
||||||
|
xTimerStart(NM.state_timer, portMAX_DELAY);
|
||||||
|
} else if (NM.state_timer) {
|
||||||
|
ESP_LOGD(TAG, "Stopping timer");
|
||||||
|
xTimerStop(NM.state_timer, portMAX_DELAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void network_ip_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) {
|
||||||
|
ip_event_got_ip_t* s = NULL;
|
||||||
|
esp_netif_ip_info_t* ip_info = NULL;
|
||||||
|
|
||||||
|
if (event_base != IP_EVENT)
|
||||||
|
return;
|
||||||
|
switch (event_id) {
|
||||||
|
case IP_EVENT_ETH_GOT_IP:
|
||||||
|
case IP_EVENT_STA_GOT_IP:
|
||||||
|
s = (ip_event_got_ip_t*)event_data;
|
||||||
|
ip_info = &s->ip_info;
|
||||||
|
ESP_LOGI(TAG, "Got an IP address from interface %s. IP=" IPSTR ", Gateway=" IPSTR ", NetMask=" IPSTR ", %s",
|
||||||
|
event_id == IP_EVENT_ETH_GOT_IP ? "Eth" : event_id == IP_EVENT_STA_GOT_IP ? "Wifi"
|
||||||
|
: "Unknown",
|
||||||
|
IP2STR(&ip_info->ip),
|
||||||
|
IP2STR(&ip_info->gw),
|
||||||
|
IP2STR(&ip_info->netmask),
|
||||||
|
s->ip_changed ? "Address was changed" : "Address unchanged");
|
||||||
|
network_async(event_id == IP_EVENT_ETH_GOT_IP ? EN_ETH_GOT_IP : EN_GOT_IP);
|
||||||
|
break;
|
||||||
|
case IP_EVENT_STA_LOST_IP:
|
||||||
|
ESP_LOGD(TAG, "IP_EVENT_STA_LOST_IP");
|
||||||
|
break;
|
||||||
|
case IP_EVENT_AP_STAIPASSIGNED:
|
||||||
|
ESP_LOGD(TAG, "IP_EVENT_AP_STAIPASSIGNED");
|
||||||
|
break;
|
||||||
|
case IP_EVENT_GOT_IP6:
|
||||||
|
ESP_LOGD(TAG, "IP_EVENT_GOT_IP6");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void network_set_hostname(esp_netif_t* interface) {
|
||||||
|
esp_err_t err;
|
||||||
|
ESP_LOGD(TAG, "Retrieving host name from nvs");
|
||||||
|
char* host_name = (char*)config_alloc_get(NVS_TYPE_STR, "host_name");
|
||||||
|
if (host_name == NULL) {
|
||||||
|
ESP_LOGE(TAG, "Could not retrieve host name from nvs");
|
||||||
|
} else {
|
||||||
|
ESP_LOGD(TAG, "Setting host name to : %s", host_name);
|
||||||
|
if ((err = esp_netif_set_hostname(interface, host_name)) != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Unable to set host name. Error: %s", esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
free(host_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#define LOCAL_MAC_SIZE 20
|
||||||
|
char* network_manager_alloc_get_mac_string(uint8_t mac[6]) {
|
||||||
|
char* macStr = malloc_init_external(LOCAL_MAC_SIZE);
|
||||||
|
if(macStr){
|
||||||
|
snprintf(macStr, LOCAL_MAC_SIZE, MACSTR, MAC2STR(mac));
|
||||||
|
}
|
||||||
|
return macStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,41 +1,5 @@
|
|||||||
/*
|
#pragma once
|
||||||
Copyright (c) 2017-2019 Tony Pottier
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
|
|
||||||
@file network_manager.h
|
|
||||||
@author Tony Pottier
|
|
||||||
@brief Defines all functions necessary for esp32 to connect to a wifi/scan wifis
|
|
||||||
|
|
||||||
Contains the freeRTOS task and all necessary support
|
|
||||||
|
|
||||||
@see https://idyl.io
|
|
||||||
@see https://github.com/tonyp7/esp32-wifi-manager
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef WIFI_MANAGER_H_INCLUDED
|
|
||||||
#define WIFI_MANAGER_H_INCLUDED
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
#include "esp_system.h"
|
#include "esp_system.h"
|
||||||
#include "esp_wifi.h"
|
#include "esp_wifi.h"
|
||||||
#include "esp_wifi_types.h"
|
#include "esp_wifi_types.h"
|
||||||
@@ -43,8 +7,192 @@ extern "C" {
|
|||||||
#include "cJSON.h"
|
#include "cJSON.h"
|
||||||
#include "esp_eth.h"
|
#include "esp_eth.h"
|
||||||
#include "freertos/event_groups.h"
|
#include "freertos/event_groups.h"
|
||||||
#include "state_machine.h"
|
#include "hsm.h"
|
||||||
#include "state_machine.h"
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define STA_POLLING_MIN (15 * 1000)
|
||||||
|
#define STA_POLLING_MAX (10 * 60 * 1000)
|
||||||
|
#define ETH_LINK_DOWN_REBOOT (2 * 1000)
|
||||||
|
#define ETH_DHCP_FAIL (6 * 1000)
|
||||||
|
#define WIFI_DHCP_FAIL (6 * 1000)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --------------------- ENUMERATION ---------------------
|
||||||
|
*/
|
||||||
|
//#define ADD_ROOT(NAME, HANDLER, ENTRY, EXIT, CHILD)
|
||||||
|
//#define ADD_ROOT(NAME, HANDLER, ENTRY, EXIT, CHILD)
|
||||||
|
//#define ADD_LEAF(NAME, HANDLER, ENTRY, EXIT, PARENT, LEVEL)
|
||||||
|
|
||||||
|
#define ALL_NM_STATE \
|
||||||
|
ADD_ROOT_LEAF(NETWORK_INSTANTIATED_STATE)\
|
||||||
|
ADD_ROOT_LEAF(NETWORK_INITIALIZING_STATE)\
|
||||||
|
ADD_ROOT(NETWORK_ETH_ACTIVE_STATE, Eth_Active_State)\
|
||||||
|
ADD_ROOT(NETWORK_WIFI_ACTIVE_STATE, Wifi_Active_State)\
|
||||||
|
ADD_ROOT(NETWORK_WIFI_CONFIGURING_ACTIVE_STATE, Wifi_Configuring_State)
|
||||||
|
|
||||||
|
#define ALL_ETH_STATE(PARENT, LEVEL)\
|
||||||
|
ADD_LEAF(ETH_STARTING_STATE,PARENT,LEVEL)\
|
||||||
|
ADD_LEAF(ETH_ACTIVE_LINKUP_STATE,PARENT,LEVEL)\
|
||||||
|
ADD_LEAF(ETH_ACTIVE_LINKDOWN_STATE,PARENT,LEVEL)\
|
||||||
|
ADD_LEAF(ETH_ACTIVE_CONNECTED_STATE,PARENT,LEVEL)\
|
||||||
|
ADD_LEAF(ETH_CONNECTING_NEW_STATE,PARENT,LEVEL)
|
||||||
|
|
||||||
|
#define ALL_WIFI_STATE(PARENT, LEVEL)\
|
||||||
|
ADD_LEAF(WIFI_INITIALIZING_STATE,PARENT,LEVEL)\
|
||||||
|
ADD_LEAF(WIFI_CONNECTING_STATE,PARENT,LEVEL)\
|
||||||
|
ADD_LEAF(WIFI_CONNECTING_NEW_STATE,PARENT,LEVEL)\
|
||||||
|
ADD_LEAF(WIFI_CONNECTING_NEW_FAILED_STATE,PARENT,LEVEL)\
|
||||||
|
ADD_LEAF(WIFI_CONNECTED_STATE,PARENT,LEVEL)\
|
||||||
|
ADD_LEAF(WIFI_USER_DISCONNECTED_STATE,PARENT,LEVEL)\
|
||||||
|
ADD_LEAF(WIFI_LOST_CONNECTION_STATE,PARENT,LEVEL)
|
||||||
|
|
||||||
|
#define ALL_WIFI_CONFIGURING_STATE(PARENT, LEVEL)\
|
||||||
|
ADD_LEAF(WIFI_CONFIGURING_STATE,PARENT,LEVEL)\
|
||||||
|
ADD_LEAF(WIFI_CONFIGURING_CONNECT_STATE,PARENT,LEVEL)\
|
||||||
|
ADD_LEAF(WIFI_CONFIGURING_CONNECT_SUCCESS_STATE,PARENT,LEVEL)\
|
||||||
|
ADD_LEAF(WIFI_CONFIGURING_CONNECT_SUCCESS_GOTOSTA_STATE,PARENT,LEVEL)
|
||||||
|
|
||||||
|
|
||||||
|
#define ADD_ROOT(name, ...) name,
|
||||||
|
#define ADD_ROOT_LEAF(name, ...) name,
|
||||||
|
#define ADD_LEAF(name, ...) name,
|
||||||
|
typedef enum {
|
||||||
|
ALL_NM_STATE
|
||||||
|
TOTAL_NM_STATE
|
||||||
|
} nm_state_t;
|
||||||
|
typedef enum {
|
||||||
|
ALL_WIFI_STATE(,)
|
||||||
|
TOTAL_WIFI_ACTIVE_STATE
|
||||||
|
} mn_wifi_active_state_t;
|
||||||
|
typedef enum {
|
||||||
|
ALL_ETH_STATE(,)
|
||||||
|
TOTAL_ETH_ACTIVE_STATE
|
||||||
|
} mn_eth_active_state_t;
|
||||||
|
typedef enum {
|
||||||
|
ALL_WIFI_CONFIGURING_STATE(,)
|
||||||
|
TOTAL_WIFI_CONFIGURING_STATE
|
||||||
|
} mn_wifi_configuring_state_t;
|
||||||
|
|
||||||
|
#undef ADD_STATE
|
||||||
|
#undef ADD_ROOT
|
||||||
|
#undef ADD_ROOT_LEAF
|
||||||
|
#undef ADD_LEAF
|
||||||
|
|
||||||
|
typedef void (*network_status_reached_cb)(nm_state_t state_id, int sub_state );
|
||||||
|
//! List of oven events
|
||||||
|
#define ALL_NM_EVENTS \
|
||||||
|
ADD_FIRST_EVENT(EN_LINK_UP) \
|
||||||
|
ADD_EVENT(EN_LINK_DOWN)\
|
||||||
|
ADD_EVENT(EN_CONFIGURE)\
|
||||||
|
ADD_EVENT(EN_GOT_IP)\
|
||||||
|
ADD_EVENT(EN_ETH_GOT_IP)\
|
||||||
|
ADD_EVENT(EN_DELETE)\
|
||||||
|
ADD_EVENT(EN_TIMER)\
|
||||||
|
ADD_EVENT(EN_START)\
|
||||||
|
ADD_EVENT(EN_SCAN)\
|
||||||
|
ADD_EVENT(EN_FAIL)\
|
||||||
|
ADD_EVENT(EN_SUCCESS)\
|
||||||
|
ADD_EVENT(EN_SCAN_DONE)\
|
||||||
|
ADD_EVENT(EN_CONNECT)\
|
||||||
|
ADD_EVENT(EN_CONNECT_NEW)\
|
||||||
|
ADD_EVENT(EN_REBOOT)\
|
||||||
|
ADD_EVENT(EN_REBOOT_URL)\
|
||||||
|
ADD_EVENT(EN_LOST_CONNECTION)\
|
||||||
|
ADD_EVENT(EN_ETHERNET_FALLBACK)\
|
||||||
|
ADD_EVENT(EN_UPDATE_STATUS)\
|
||||||
|
ADD_EVENT(EN_CONNECTED)
|
||||||
|
#define ADD_EVENT(name) name,
|
||||||
|
#define ADD_FIRST_EVENT(name) name=1,
|
||||||
|
typedef enum {
|
||||||
|
ALL_NM_EVENTS
|
||||||
|
} network_event_t;
|
||||||
|
#undef ADD_EVENT
|
||||||
|
#undef ADD_FIRST_EVENT
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
OTA,
|
||||||
|
RECOVERY,
|
||||||
|
RESTART,
|
||||||
|
} reboot_type_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
network_event_t trigger;
|
||||||
|
char * ssid;
|
||||||
|
char * password;
|
||||||
|
reboot_type_t rtype;
|
||||||
|
char* strval;
|
||||||
|
wifi_event_sta_disconnected_t* disconnected_event;
|
||||||
|
esp_netif_t *netif;
|
||||||
|
} queue_message;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
state_machine_t Machine; //!< Abstract state machine
|
||||||
|
const state_t* source_state;
|
||||||
|
bool ethernet_connected;
|
||||||
|
TimerHandle_t state_timer;
|
||||||
|
uint32_t STA_duration;
|
||||||
|
int32_t total_connected_time;
|
||||||
|
int64_t last_connected;
|
||||||
|
uint16_t num_disconnect;
|
||||||
|
uint16_t retries;
|
||||||
|
bool wifi_connected;
|
||||||
|
esp_netif_t *wifi_netif;
|
||||||
|
esp_netif_t *eth_netif;
|
||||||
|
esp_netif_t *wifi_ap_netif;
|
||||||
|
queue_message * event_parameters;
|
||||||
|
} network_t;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --------------------- External function prototype ---------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
void network_start();
|
||||||
|
network_t * network_get_state_machine();
|
||||||
|
void network_event_simple(network_event_t trigger);
|
||||||
|
void network_event(network_event_t trigger, void* param);
|
||||||
|
void network_async_event(network_event_t trigger, void* param);
|
||||||
|
void network_async(network_event_t trigger);
|
||||||
|
void network_async_fail();
|
||||||
|
void network_async_success();
|
||||||
|
void network_async_link_up();
|
||||||
|
void network_async_link_down();
|
||||||
|
void network_async_configure();
|
||||||
|
void network_async_got_ip();
|
||||||
|
void network_async_timer();
|
||||||
|
void network_async_start();
|
||||||
|
void network_async_scan();
|
||||||
|
void network_async_scan_done();
|
||||||
|
void network_async_connect(const char * ssid, const char * password);
|
||||||
|
void network_async_lost_connection(wifi_event_sta_disconnected_t * disconnected_event);
|
||||||
|
void network_async_reboot(reboot_type_t rtype);
|
||||||
|
void network_reboot_ota(char* url);
|
||||||
|
void network_async_delete();
|
||||||
|
void network_async_update_status();
|
||||||
|
void network_async_eth_got_ip();
|
||||||
|
void network_ip_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
|
||||||
|
bool network_is_interface_connected(esp_netif_t * interface);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --------------------- Inline functions ---------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Defines the maximum size of a SSID name. 32 is IEEE standard.
|
* @brief Defines the maximum size of a SSID name. 32 is IEEE standard.
|
||||||
* @warning limit is also hard coded in wifi_config_t. Never extend this value.
|
* @warning limit is also hard coded in wifi_config_t. Never extend this value.
|
||||||
@@ -149,96 +297,23 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
#define DEFAULT_STA_POWER_SAVE WIFI_PS_MIN_MODEM
|
#define DEFAULT_STA_POWER_SAVE WIFI_PS_MIN_MODEM
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Defines the maximum length in bytes of a JSON representation of an access point.
|
|
||||||
*
|
|
||||||
* maximum ap string length with full 32 char ssid: 75 + \\n + \0 = 77\n
|
|
||||||
* example: {"ssid":"abcdefghijklmnopqrstuvwxyz012345","chan":12,"rssi":-100,"auth":4},\n
|
|
||||||
* BUT: we need to escape JSON. Imagine a ssid full of \" ? so it's 32 more bytes hence 77 + 32 = 99.\n
|
|
||||||
* this is an edge case but I don't think we should crash in a catastrophic manner just because
|
|
||||||
* someone decided to have a funny wifi name.
|
|
||||||
*/
|
|
||||||
#define JSON_ONE_APP_SIZE 99
|
|
||||||
|
|
||||||
/**
|
void network_reboot_ota(char * url);
|
||||||
* @brief Defines the complete list of all messages that the wifi_manager can process.
|
|
||||||
*
|
|
||||||
* Some of these message are events ("EVENT"), and some of them are action ("ORDER")
|
|
||||||
* Each of these messages can trigger a callback function and each callback function is stored
|
|
||||||
* in a function pointer array for convenience. Because of this behavior, it is extremely important
|
|
||||||
* to maintain a strict sequence and the top level special element 'MESSAGE_CODE_COUNT'
|
|
||||||
*
|
|
||||||
* @see wifi_manager_set_callback
|
|
||||||
*/
|
|
||||||
typedef enum message_code_t {
|
|
||||||
NONE = 0,
|
|
||||||
ORDER_START_HTTP_SERVER = 1,
|
|
||||||
ORDER_STOP_HTTP_SERVER = 2,
|
|
||||||
ORDER_START_DNS_SERVICE = 3,
|
|
||||||
ORDER_STOP_DNS_SERVICE = 4,
|
|
||||||
ORDER_START_WIFI_SCAN = 5,
|
|
||||||
ORDER_LOAD_AND_RESTORE_STA = 6,
|
|
||||||
ORDER_CONNECT_STA = 7,
|
|
||||||
ORDER_DISCONNECT_STA = 8,
|
|
||||||
ORDER_START_AP = 9,
|
|
||||||
ORDER_START_HTTP = 10,
|
|
||||||
ORDER_START_DNS_HIJACK = 11,
|
|
||||||
EVENT_STA_DISCONNECTED = 12,
|
|
||||||
EVENT_SCAN_DONE = 13,
|
|
||||||
EVENT_GOT_IP = 14,
|
|
||||||
ORDER_RESTART_OTA = 15,
|
|
||||||
ORDER_RESTART_RECOVERY = 16,
|
|
||||||
ORDER_RESTART_OTA_URL = 17,
|
|
||||||
ORDER_RESTART = 18,
|
|
||||||
ORDER_UPDATE_STATUS = 19,
|
|
||||||
EVENT_ETH_GOT_IP = 20,
|
|
||||||
EVENT_ETH_TIMEOUT = 21,
|
|
||||||
EVENT_ETH_LINK_UP = 22,
|
|
||||||
EVENT_ETH_LINK_DOWN = 23,
|
|
||||||
MESSAGE_CODE_COUNT = 24 /* important for the callback array */
|
|
||||||
}message_code_t;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* @brief indicate that the ESP32 is currently connected. */
|
|
||||||
extern const int WIFI_MANAGER_WIFI_CONNECTED_BIT;
|
|
||||||
|
|
||||||
extern const int WIFI_MANAGER_AP_STA_CONNECTED_BIT;
|
|
||||||
|
|
||||||
/* @brief Set automatically once the SoftAP is started */
|
|
||||||
extern const int WIFI_MANAGER_AP_STARTED_BIT;
|
|
||||||
|
|
||||||
/* @brief When set, means a client requested to connect to an access point.*/
|
|
||||||
extern const int WIFI_MANAGER_REQUEST_STA_CONNECT_BIT;
|
|
||||||
|
|
||||||
/* @brief This bit is set automatically as soon as a connection was lost */
|
|
||||||
extern const int WIFI_MANAGER_STA_DISCONNECT_BIT ;
|
|
||||||
|
|
||||||
/* @brief When set, means the wifi manager attempts to restore a previously saved connection at startup. */
|
|
||||||
extern const int WIFI_MANAGER_REQUEST_RESTORE_STA_BIT ;
|
|
||||||
|
|
||||||
/* @brief When set, means a client requested to disconnect from currently connected AP. */
|
|
||||||
extern const int WIFI_MANAGER_REQUEST_WIFI_DISCONNECT_BIT ;
|
|
||||||
|
|
||||||
/* @brief When set, means a scan is in progress */
|
|
||||||
extern const int WIFI_MANAGER_SCAN_BIT ;
|
|
||||||
|
|
||||||
/* @brief When set, means user requested for a disconnect */
|
|
||||||
extern const int WIFI_MANAGER_REQUEST_DISCONNECT_BIT ;
|
|
||||||
|
|
||||||
/* @brief When set, means user requested connecting to a new network and it failed */
|
|
||||||
extern const int WIFI_MANAGER_REQUEST_STA_CONNECT_FAILED_BIT ;
|
|
||||||
|
|
||||||
void network_manager_reboot_ota(char * url);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief simplified reason codes for a lost connection.
|
* @brief simplified reason codes for a lost connection.
|
||||||
*
|
*
|
||||||
* esp-idf maintains a big list of reason codes which in practice are useless for most typical application.
|
* esp-idf maintains a big list of reason codes which in practice are useless for most typical application.
|
||||||
|
* UPDATE_CONNECTION_OK - Web UI expects this when attempting to connect to a new access point succeeds
|
||||||
|
* UPDATE_FAILED_ATTEMPT - Web UI expects this when attempting to connect to a new access point fails
|
||||||
|
* UPDATE_USER_DISCONNECT = 2,
|
||||||
|
* UPDATE_LOST_CONNECTION = 3,
|
||||||
|
* UPDATE_FAILED_ATTEMPT_AND_RESTORE - Web UI expects this when attempting to connect to a new access point fails and previous connection is restored
|
||||||
|
* UPDATE_ETHERNET_CONNECTED = 5
|
||||||
*/
|
*/
|
||||||
typedef enum update_reason_code_t {
|
typedef enum update_reason_code_t {
|
||||||
UPDATE_CONNECTION_OK = 0,
|
UPDATE_CONNECTION_OK = 0, // expected when
|
||||||
UPDATE_FAILED_ATTEMPT = 1,
|
UPDATE_FAILED_ATTEMPT = 1,
|
||||||
UPDATE_USER_DISCONNECT = 2,
|
UPDATE_USER_DISCONNECT = 2,
|
||||||
UPDATE_LOST_CONNECTION = 3,
|
UPDATE_LOST_CONNECTION = 3,
|
||||||
@@ -247,33 +322,6 @@ typedef enum update_reason_code_t {
|
|||||||
|
|
||||||
}update_reason_code_t;
|
}update_reason_code_t;
|
||||||
|
|
||||||
typedef enum connection_request_made_by_code_t{
|
|
||||||
CONNECTION_REQUEST_NONE = 0,
|
|
||||||
CONNECTION_REQUEST_USER = 1,
|
|
||||||
CONNECTION_REQUEST_AUTO_RECONNECT = 2,
|
|
||||||
CONNECTION_REQUEST_RESTORE_CONNECTION = 3,
|
|
||||||
CONNECTION_REQUEST_MAX_FAILED = 4,
|
|
||||||
CONNECTION_REQUEST_MAX = 0x7fffffff /*force the creation of this enum as a 32 bit int */
|
|
||||||
}connection_request_made_by_code_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The wifi manager settings in use
|
|
||||||
*/
|
|
||||||
//struct wifi_settings_t{
|
|
||||||
// bool sta_only;
|
|
||||||
// bool sta_static_ip;
|
|
||||||
// wifi_ps_type_t sta_power_save;
|
|
||||||
// tcpip_adapter_ip_info_t sta_static_ip_config;
|
|
||||||
//};
|
|
||||||
//extern struct wifi_settings_t wifi_settings;
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * @brief Structure used to store one message in the queue.
|
|
||||||
// */
|
|
||||||
// typedef struct{
|
|
||||||
// message_code_t code;
|
|
||||||
// void *param;
|
|
||||||
// } queue_message;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -284,59 +332,95 @@ typedef enum connection_request_made_by_code_t{
|
|||||||
/**
|
/**
|
||||||
* Frees up all memory allocated by the wifi_manager and kill the task.
|
* Frees up all memory allocated by the wifi_manager and kill the task.
|
||||||
*/
|
*/
|
||||||
void network_manager_destroy();
|
void network_destroy();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters the AP scan list to unique SSIDs
|
* Filters the AP scan list to unique SSIDs
|
||||||
*/
|
*/
|
||||||
void 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 network_manager( void * pvParameters );
|
|
||||||
|
|
||||||
|
char* network_status_alloc_get_ap_list_json();
|
||||||
char* wifi_manager_alloc_get_ap_list_json();
|
cJSON * network_manager_clear_ap_list_json(cJSON **old);
|
||||||
cJSON * wifi_manager_clear_ap_list_json(cJSON **old);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A standard wifi event handler as recommended by Espressif
|
* @brief A standard wifi event handler as recommended by Espressif
|
||||||
*/
|
*/
|
||||||
esp_err_t wifi_manager_event_handler(void *ctx, system_event_t *event);
|
esp_err_t network_manager_event_handler(void *ctx, system_event_t *event);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Clears the connection status json.
|
* @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.
|
* @note This is not thread-safe and should be called only if network_status_lock_json_buffer call is successful.
|
||||||
*/
|
*/
|
||||||
cJSON * wifi_manager_clear_ip_info_json(cJSON **old);
|
cJSON * network_status_clear_ip_info_json(cJSON **old);
|
||||||
cJSON * wifi_manager_get_new_json(cJSON **old);
|
cJSON * network_status_get_new_json(cJSON **old);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Start the mDNS service
|
* @brief Start the mDNS service
|
||||||
*/
|
*/
|
||||||
void wifi_manager_initialise_mdns();
|
void network_manager_initialise_mdns();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Register a callback to a custom function when specific event message_code happens.
|
* @brief Register a callback to a custom function when specific network manager states are reached.
|
||||||
*/
|
*/
|
||||||
void wifi_manager_set_callback(message_code_t message_code, void (*func_ptr)(void*) );
|
esp_err_t network_register_state_callback(nm_state_t state, int sub_state, const char* from, network_status_reached_cb cb);
|
||||||
|
bool network_is_wifi_prioritized();
|
||||||
|
esp_netif_t * network_get_active_interface();
|
||||||
|
esp_err_t network_get_hostname( const char **hostname);
|
||||||
|
esp_err_t network_get_ip_info(tcpip_adapter_ip_info_t* ipInfo);
|
||||||
|
void network_set_timer(uint16_t duration);
|
||||||
|
void network_set_hostname(esp_netif_t * netif);
|
||||||
|
esp_err_t network_get_ip_info_for_netif(esp_netif_t* netif, tcpip_adapter_ip_info_t* ipInfo);
|
||||||
|
void network_start_stop_dhcp(esp_netif_t* netif, bool start);
|
||||||
|
void network_start_stop_dhcps(esp_netif_t* netif, bool start);
|
||||||
|
void network_prioritize_wifi(bool activate);
|
||||||
|
#define ADD_ROOT_FORWARD_DECLARATION(name, ...) ADD_STATE_FORWARD_DECLARATION_(name)
|
||||||
|
#define ADD_ROOT_LEAF_FORWARD_DECLARATION(name, ...) ADD_STATE_FORWARD_DECLARATION_(name)
|
||||||
|
#define ADD_LEAF_FORWARD_DECLARATION(name, ...) ADD_STATE_FORWARD_DECLARATION_(name)
|
||||||
|
#define ADD_STATE_FORWARD_DECLARATION_(name) \
|
||||||
|
static state_machine_result_t name##_handler(state_machine_t* const State_Machine); \
|
||||||
|
static state_machine_result_t name##_entry_handler(state_machine_t* const State_Machine); \
|
||||||
|
static state_machine_result_t name##_exit_handler(state_machine_t* const State_Machine);
|
||||||
|
|
||||||
|
void initialize_network_handlers(state_machine_t* state_machine);
|
||||||
|
void network_manager_format_from_to_states(esp_log_level_t level, const char* prefix, state_t const * from_state, state_t const* current_state, network_event_t event,bool show_source, const char * caller );
|
||||||
|
void network_manager_format_state_machine(esp_log_level_t level, const char* prefix, state_machine_t * state_machine, bool show_source, const char * caller) ;
|
||||||
|
char* network_manager_alloc_get_mac_string(uint8_t mac[6]);
|
||||||
|
|
||||||
bool network_manager_is_flag_set(EventBits_t bit);
|
#if defined(LOG_LOCAL_LEVEL) && LOG_LOCAL_LEVEL >=ESP_LOG_VERBOSE
|
||||||
void network_manager_set_flag(EventBits_t bit);
|
#define NETWORK_PRINT_TRANSITION(begin, prefix, source,target, event, print_source,caller ) network_manager_format_from_to_states(ESP_LOG_VERBOSE, prefix, source,target, event, print_source,caller )
|
||||||
void network_manager_clear_flag(EventBits_t bit);
|
#define NETWORK_DEBUG_STATE_MACHINE(begin, cb_prefix,state_machine,print_from,caller) network_manager_format_state_machine(ESP_LOG_DEBUG,cb_prefix,state_machine,print_from,caller)
|
||||||
|
#define NETWORK_EXECUTE_CB(mch) network_execute_cb(mch,__FUNCTION__);
|
||||||
|
#define network_handler_entry_print(State_Machine, begin) network_manager_format_state_machine(ESP_LOG_DEBUG,begin?"ENTRY START":"ENTRY END",State_Machine,false,__FUNCTION__)
|
||||||
|
#define network_exit_handler_print(State_Machine, begin) network_manager_format_state_machine(ESP_LOG_DEBUG,begin?"EXIT START":"END END",State_Machine,false,__FUNCTION__)
|
||||||
|
#define network_handler_print(State_Machine, begin) network_manager_format_state_machine(ESP_LOG_DEBUG,begin?"HANDLER START":"HANDLER END",State_Machine,false,__FUNCTION__)
|
||||||
|
|
||||||
|
#elif defined(LOG_LOCAL_LEVEL) && LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG
|
||||||
|
#define network_handler_entry_print(State_Machine, begin) if(begin) network_manager_format_state_machine(ESP_LOG_DEBUG,begin?"BEGIN ENTRY":"END ENTRY",State_Machine,false,__FUNCTION__)
|
||||||
|
#define network_exit_handler_print(State_Machine, begin) if(begin) network_manager_format_state_machine(ESP_LOG_DEBUG,begin?"BEGIN EXIT":"END EXIT",State_Machine,false,__FUNCTION__)
|
||||||
|
#define network_handler_print(State_Machine, begin) if(begin) network_manager_format_state_machine(ESP_LOG_DEBUG,begin?"HANDLER START":"HANDLER END",State_Machine,false,__FUNCTION__)
|
||||||
|
|
||||||
|
#define NETWORK_PRINT_TRANSITION(begin, prefix, source,target, event, print_source,caller ) if(begin) network_manager_format_from_to_states(ESP_LOG_DEBUG, prefix, source,target, event, print_source,caller )#define NETWORK_EXECUTE_CB(mch) network_execute_cb(mch,__FUNCTION__);
|
||||||
|
#define NETWORK_DEBUG_STATE_MACHINE(begin, cb_prefix,state_machine,print_from,caller) if(begin) network_manager_format_state_machine(ESP_LOG_DEBUG,cb_prefix,state_machine,print_from,caller)
|
||||||
|
#else
|
||||||
|
#define network_exit_handler_print(nm, begin)
|
||||||
|
#define network_handler_entry_print(State_Machine, begin)
|
||||||
|
#define network_handler_print(State_Machine, begin)
|
||||||
|
#define NETWORK_EXECUTE_CB(mch) network_execute_cb(mch,NULL)
|
||||||
|
#define NETWORK_PRINT_TRANSITION(prefix, source,target, event, print_source,caller )
|
||||||
|
#define NETWORK_DEBUG_STATE_MACHINE(begin, cb_prefix,state_machine,print_from,caller)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* WIFI_MANAGER_H_INCLUDED */
|
|
||||||
|
|||||||
1155
components/wifi-manager/network_manager_handlers.c
Normal file
1155
components/wifi-manager/network_manager_handlers.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,7 @@
|
|||||||
|
#ifdef NETWORK_STATUS_LOG_LEVEL
|
||||||
|
#define LOG_LOCAL_LEVEL NETWORK_STATUS_LOG_LEVEL
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "network_status.h"
|
#include "network_status.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "bt_app_core.h"
|
#include "bt_app_core.h"
|
||||||
@@ -16,10 +20,12 @@
|
|||||||
#define CONFIG_SQUEEZELITE_ESP32_RELEASE_URL "https://github.com/sle118/squeezelite-esp32/releases"
|
#define CONFIG_SQUEEZELITE_ESP32_RELEASE_URL "https://github.com/sle118/squeezelite-esp32/releases"
|
||||||
#endif
|
#endif
|
||||||
static const char TAG[] = "network_status";
|
static const char TAG[] = "network_status";
|
||||||
SemaphoreHandle_t wifi_manager_json_mutex = NULL;
|
SemaphoreHandle_t network_status_json_mutex = NULL;
|
||||||
SemaphoreHandle_t wifi_manager_sta_ip_mutex = NULL;
|
static TaskHandle_t network_json_locked_task = NULL;
|
||||||
|
SemaphoreHandle_t network_status_ip_address_mutex = NULL;
|
||||||
|
static TaskHandle_t network_status_ip_address_locked_task = NULL;
|
||||||
char* release_url = NULL;
|
char* release_url = NULL;
|
||||||
char* wifi_manager_sta_ip = NULL;
|
char* network_status_ip_address = NULL;
|
||||||
char* ip_info_json = NULL;
|
char* ip_info_json = NULL;
|
||||||
cJSON* ip_info_cjson = NULL;
|
cJSON* ip_info_cjson = NULL;
|
||||||
static char lms_server_ip[IP4ADDR_STRLEN_MAX] = {0};
|
static char lms_server_ip[IP4ADDR_STRLEN_MAX] = {0};
|
||||||
@@ -33,11 +39,11 @@ void init_network_status() {
|
|||||||
chained_notify = server_notify;
|
chained_notify = server_notify;
|
||||||
server_notify = connect_notify;
|
server_notify = connect_notify;
|
||||||
ESP_LOGD(TAG, "init_network_status. Creating mutexes");
|
ESP_LOGD(TAG, "init_network_status. Creating mutexes");
|
||||||
wifi_manager_json_mutex = xSemaphoreCreateMutex();
|
network_status_json_mutex = xSemaphoreCreateMutex();
|
||||||
wifi_manager_sta_ip_mutex = xSemaphoreCreateMutex();
|
network_status_ip_address_mutex = xSemaphoreCreateMutex();
|
||||||
ip_info_json = NULL;
|
ip_info_json = NULL;
|
||||||
ESP_LOGD(TAG, "init_network_status. Creating status json structure");
|
ESP_LOGD(TAG, "init_network_status. Creating status json structure");
|
||||||
ip_info_cjson = wifi_manager_clear_ip_info_json(&ip_info_cjson);
|
ip_info_cjson = network_status_clear_ip_info_json(&ip_info_cjson);
|
||||||
ESP_LOGD(TAG, "Getting release url ");
|
ESP_LOGD(TAG, "Getting release url ");
|
||||||
char* release_url = (char*)config_alloc_get_default(NVS_TYPE_STR, "release_url", QUOTE(CONFIG_SQUEEZELITE_ESP32_RELEASE_URL), 0);
|
char* release_url = (char*)config_alloc_get_default(NVS_TYPE_STR, "release_url", QUOTE(CONFIG_SQUEEZELITE_ESP32_RELEASE_URL), 0);
|
||||||
if (release_url == NULL) {
|
if (release_url == NULL) {
|
||||||
@@ -46,57 +52,73 @@ void init_network_status() {
|
|||||||
ESP_LOGD(TAG, "Found release url %s", release_url);
|
ESP_LOGD(TAG, "Found release url %s", release_url);
|
||||||
}
|
}
|
||||||
ESP_LOGD(TAG, "About to set the STA IP String to 0.0.0.0");
|
ESP_LOGD(TAG, "About to set the STA IP String to 0.0.0.0");
|
||||||
wifi_manager_sta_ip = (char*)malloc(STA_IP_LEN);
|
network_status_ip_address = (char*)malloc_init_external(STA_IP_LEN);
|
||||||
wifi_manager_safe_update_sta_ip_string(NULL);
|
network_status_safe_update_sta_ip_string(NULL);
|
||||||
}
|
}
|
||||||
void destroy_network_status() {
|
void destroy_network_status() {
|
||||||
FREE_AND_NULL(release_url);
|
FREE_AND_NULL(release_url);
|
||||||
FREE_AND_NULL(ip_info_json);
|
FREE_AND_NULL(ip_info_json);
|
||||||
FREE_AND_NULL(wifi_manager_sta_ip);
|
FREE_AND_NULL(network_status_ip_address);
|
||||||
cJSON_Delete(ip_info_cjson);
|
cJSON_Delete(ip_info_cjson);
|
||||||
vSemaphoreDelete(wifi_manager_json_mutex);
|
vSemaphoreDelete(network_status_json_mutex);
|
||||||
wifi_manager_json_mutex = NULL;
|
network_status_json_mutex = NULL;
|
||||||
vSemaphoreDelete(wifi_manager_sta_ip_mutex);
|
vSemaphoreDelete(network_status_ip_address_mutex);
|
||||||
wifi_manager_sta_ip_mutex = NULL;
|
network_status_ip_address_mutex = NULL;
|
||||||
ip_info_cjson = NULL;
|
ip_info_cjson = NULL;
|
||||||
}
|
}
|
||||||
cJSON* wifi_manager_get_new_json(cJSON** old) {
|
cJSON* network_status_get_new_json(cJSON** old) {
|
||||||
ESP_LOGV(TAG, "wifi_manager_get_new_json called");
|
ESP_LOGV(TAG, "network_status_get_new_json called");
|
||||||
cJSON* root = *old;
|
cJSON* root = *old;
|
||||||
if (root != NULL) {
|
if (root != NULL) {
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
*old = NULL;
|
*old = NULL;
|
||||||
}
|
}
|
||||||
ESP_LOGV(TAG, "wifi_manager_get_new_json done");
|
ESP_LOGV(TAG, "network_status_get_new_json done");
|
||||||
return cJSON_CreateObject();
|
return cJSON_CreateObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
cJSON* wifi_manager_clear_ip_info_json(cJSON** old) {
|
cJSON* network_status_clear_ip_info_json(cJSON** old) {
|
||||||
ESP_LOGV(TAG, "wifi_manager_clear_ip_info_json called");
|
ESP_LOGV(TAG, "network_status_clear_ip_info_json called");
|
||||||
cJSON* root = wifi_manager_get_basic_info(old);
|
cJSON* root = network_status_get_basic_info(old);
|
||||||
ESP_LOGV(TAG, "wifi_manager_clear_ip_info_json done");
|
cJSON_DeleteItemFromObjectCaseSensitive(root, "ip");
|
||||||
|
cJSON_DeleteItemFromObjectCaseSensitive(root, "netmask");
|
||||||
|
cJSON_DeleteItemFromObjectCaseSensitive(root, "gw");
|
||||||
|
cJSON_DeleteItemFromObjectCaseSensitive(root, "rssi");
|
||||||
|
cJSON_DeleteItemFromObjectCaseSensitive(root, "ssid");
|
||||||
|
cJSON_DeleteItemFromObjectCaseSensitive(root, "eth");
|
||||||
|
|
||||||
|
ESP_LOGV(TAG, "network_status_clear_ip_info_json done");
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
void network_status_clear_ip() {
|
void network_status_clear_ip() {
|
||||||
if (wifi_manager_lock_json_buffer(portMAX_DELAY)) {
|
if (network_status_lock_json_buffer(portMAX_DELAY)) {
|
||||||
ip_info_cjson = wifi_manager_clear_ip_info_json(&ip_info_cjson);
|
ip_info_cjson = network_status_clear_ip_info_json(&ip_info_cjson);
|
||||||
wifi_manager_unlock_json_buffer();
|
network_status_unlock_json_buffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
char* wifi_manager_alloc_get_ip_info_json() {
|
char* network_status_alloc_get_ip_info_json() {
|
||||||
return cJSON_PrintUnformatted(ip_info_cjson);
|
return cJSON_PrintUnformatted(ip_info_cjson);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wifi_manager_unlock_json_buffer() {
|
void network_status_unlock_json_buffer() {
|
||||||
ESP_LOGV(TAG, "Unlocking json buffer!");
|
ESP_LOGV(TAG, "Unlocking json buffer!");
|
||||||
xSemaphoreGive(wifi_manager_json_mutex);
|
network_json_locked_task = NULL;
|
||||||
|
xSemaphoreGive(network_status_json_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wifi_manager_lock_json_buffer(TickType_t xTicksToWait) {
|
bool network_status_lock_json_buffer(TickType_t xTicksToWait) {
|
||||||
ESP_LOGV(TAG, "Locking json buffer");
|
ESP_LOGV(TAG, "Locking json buffer");
|
||||||
if (wifi_manager_json_mutex) {
|
|
||||||
if (xSemaphoreTake(wifi_manager_json_mutex, xTicksToWait) == pdTRUE) {
|
TaskHandle_t calling_task = xTaskGetCurrentTaskHandle();
|
||||||
|
if (calling_task == network_json_locked_task) {
|
||||||
|
ESP_LOGV(TAG, "json buffer already locked to current task");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (network_status_json_mutex) {
|
||||||
|
if (xSemaphoreTake(network_status_json_mutex, xTicksToWait) == pdTRUE) {
|
||||||
ESP_LOGV(TAG, "Json buffer locked!");
|
ESP_LOGV(TAG, "Json buffer locked!");
|
||||||
|
network_json_locked_task = calling_task;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGE(TAG, "Semaphore take failed. Unable to lock json buffer mutex");
|
ESP_LOGE(TAG, "Semaphore take failed. Unable to lock json buffer mutex");
|
||||||
@@ -108,9 +130,15 @@ bool wifi_manager_lock_json_buffer(TickType_t xTicksToWait) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wifi_manager_lock_sta_ip_string(TickType_t xTicksToWait) {
|
bool network_status_lock_sta_ip_string(TickType_t xTicksToWait) {
|
||||||
if (wifi_manager_sta_ip_mutex) {
|
TaskHandle_t calling_task = xTaskGetCurrentTaskHandle();
|
||||||
if (xSemaphoreTake(wifi_manager_sta_ip_mutex, xTicksToWait) == pdTRUE) {
|
if (calling_task == network_status_ip_address_locked_task) {
|
||||||
|
ESP_LOGD(TAG, "json buffer already locked to current task ");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (network_status_ip_address_mutex) {
|
||||||
|
if (xSemaphoreTake(network_status_ip_address_mutex, xTicksToWait) == pdTRUE) {
|
||||||
|
network_status_ip_address_locked_task = calling_task;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@@ -120,26 +148,27 @@ bool wifi_manager_lock_sta_ip_string(TickType_t xTicksToWait) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wifi_manager_unlock_sta_ip_string() {
|
void network_status_unlock_sta_ip_string() {
|
||||||
xSemaphoreGive(wifi_manager_sta_ip_mutex);
|
network_status_ip_address_locked_task = NULL;
|
||||||
|
xSemaphoreGive(network_status_ip_address_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wifi_manager_safe_update_sta_ip_string(esp_ip4_addr_t* ip4) {
|
void network_status_safe_update_sta_ip_string(esp_ip4_addr_t* ip4) {
|
||||||
if (wifi_manager_lock_sta_ip_string(portMAX_DELAY)) {
|
if (network_status_lock_sta_ip_string(portMAX_DELAY)) {
|
||||||
strcpy(wifi_manager_sta_ip, ip4 != NULL ? ip4addr_ntoa(ip4) : "0.0.0.0");
|
strcpy(network_status_ip_address, ip4 != NULL ? ip4addr_ntoa((ip4_addr_t*)ip4) : "0.0.0.0");
|
||||||
ESP_LOGD(TAG, "Set STA IP String to: %s", wifi_manager_sta_ip);
|
ESP_LOGD(TAG, "Set STA IP String to: %s", network_status_ip_address);
|
||||||
wifi_manager_unlock_sta_ip_string();
|
network_status_unlock_sta_ip_string();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void wifi_manager_safe_reset_sta_ip_string() {
|
void network_status_safe_reset_sta_ip_string() {
|
||||||
if (wifi_manager_lock_sta_ip_string(portMAX_DELAY)) {
|
if (network_status_lock_sta_ip_string(portMAX_DELAY)) {
|
||||||
strcpy(wifi_manager_sta_ip, "0.0.0.0");
|
strcpy(network_status_ip_address, "0.0.0.0");
|
||||||
ESP_LOGD(TAG, "Set STA IP String to: %s", wifi_manager_sta_ip);
|
ESP_LOGD(TAG, "Set STA IP String to: %s", network_status_ip_address);
|
||||||
wifi_manager_unlock_sta_ip_string();
|
network_status_unlock_sta_ip_string();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
char* wifi_manager_get_sta_ip_string() {
|
char* network_status_get_sta_ip_string() {
|
||||||
return wifi_manager_sta_ip;
|
return network_status_ip_address;
|
||||||
}
|
}
|
||||||
void set_lms_server_details(in_addr_t ip, u16_t hport, u16_t cport) {
|
void set_lms_server_details(in_addr_t ip, u16_t hport, u16_t cport) {
|
||||||
strncpy(lms_server_ip, inet_ntoa(ip), sizeof(lms_server_ip));
|
strncpy(lms_server_ip, inet_ntoa(ip), sizeof(lms_server_ip));
|
||||||
@@ -152,98 +181,47 @@ static void connect_notify(in_addr_t ip, u16_t hport, u16_t cport) {
|
|||||||
set_lms_server_details(ip, hport, cport);
|
set_lms_server_details(ip, hport, cport);
|
||||||
if (chained_notify)
|
if (chained_notify)
|
||||||
(*chained_notify)(ip, hport, cport);
|
(*chained_notify)(ip, hport, cport);
|
||||||
network_manager_async_update_status();
|
network_async_update_status();
|
||||||
}
|
}
|
||||||
void wifi_manager_update_basic_info() {
|
|
||||||
int32_t total_connected_time = 0;
|
|
||||||
int64_t last_connected = 0;
|
|
||||||
uint16_t num_disconnect = 0;
|
|
||||||
network_wifi_get_stats(&total_connected_time, &last_connected, &num_disconnect);
|
|
||||||
if (wifi_manager_lock_json_buffer(portMAX_DELAY)) {
|
|
||||||
monitor_gpio_t* mgpio = get_jack_insertion_gpio();
|
|
||||||
|
|
||||||
cJSON* voltage = cJSON_GetObjectItemCaseSensitive(ip_info_cjson, "Voltage");
|
void network_status_update_basic_info() {
|
||||||
if (voltage) {
|
// locking happens below this level
|
||||||
cJSON_SetNumberValue(voltage, battery_value_svc());
|
network_status_get_basic_info(&ip_info_cjson);
|
||||||
}
|
|
||||||
cJSON* bt_status = cJSON_GetObjectItemCaseSensitive(ip_info_cjson, "bt_status");
|
|
||||||
if (bt_status) {
|
|
||||||
cJSON_SetNumberValue(bt_status, bt_app_source_get_a2d_state());
|
|
||||||
}
|
|
||||||
cJSON* bt_sub_status = cJSON_GetObjectItemCaseSensitive(ip_info_cjson, "bt_sub_status");
|
|
||||||
if (bt_sub_status) {
|
|
||||||
cJSON_SetNumberValue(bt_sub_status, bt_app_source_get_media_state());
|
|
||||||
}
|
|
||||||
cJSON* jack = cJSON_GetObjectItemCaseSensitive(ip_info_cjson, "Jack");
|
|
||||||
if (jack) {
|
|
||||||
jack->type = mgpio->gpio >= 0 && jack_inserted_svc() ? cJSON_True : cJSON_False;
|
|
||||||
}
|
|
||||||
cJSON* disconnect_count = cJSON_GetObjectItemCaseSensitive(ip_info_cjson, "disconnect_count");
|
|
||||||
if (disconnect_count) {
|
|
||||||
cJSON_SetNumberValue(disconnect_count, num_disconnect);
|
|
||||||
}
|
|
||||||
cJSON* avg_conn_time = cJSON_GetObjectItemCaseSensitive(ip_info_cjson, "avg_conn_time");
|
|
||||||
if (avg_conn_time) {
|
|
||||||
cJSON_SetNumberValue(avg_conn_time, num_disconnect > 0 ? (total_connected_time / num_disconnect) : 0);
|
|
||||||
}
|
|
||||||
if (lms_server_cport > 0) {
|
|
||||||
cJSON* value = cJSON_GetObjectItemCaseSensitive(ip_info_cjson, "lms_cport");
|
|
||||||
if (value) {
|
|
||||||
cJSON_SetNumberValue(value, lms_server_cport);
|
|
||||||
} else {
|
|
||||||
cJSON_AddNumberToObject(ip_info_cjson, "lms_cport", lms_server_cport);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lms_server_port > 0) {
|
|
||||||
cJSON* value = cJSON_GetObjectItemCaseSensitive(ip_info_cjson, "lms_port");
|
|
||||||
if (value) {
|
|
||||||
cJSON_SetNumberValue(value, lms_server_port);
|
|
||||||
} else {
|
|
||||||
cJSON_AddNumberToObject(ip_info_cjson, "lms_port", lms_server_port);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen(lms_server_ip) > 0) {
|
|
||||||
cJSON* value = cJSON_GetObjectItemCaseSensitive(ip_info_cjson, "lms_ip");
|
|
||||||
if (!value) {
|
|
||||||
// only create if it does not exist. Since we're creating a reference
|
|
||||||
// to a char buffer, updates to cJSON aren't needed
|
|
||||||
cJSON_AddItemToObject(ip_info_cjson, "lms_ip", cJSON_CreateStringReference(lms_server_ip));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (network_ethernet_enabled()) {
|
|
||||||
cJSON* eth = cJSON_GetObjectItemCaseSensitive(ip_info_cjson, "eth_up");
|
|
||||||
if (eth) {
|
|
||||||
eth->type = network_ethernet_is_up() ? cJSON_True : cJSON_False;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wifi_manager_unlock_json_buffer();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
cJSON* network_status_update_string(cJSON** root, const char* key, const char* value) {
|
cJSON* network_status_update_string(cJSON** root, const char* key, const char* value) {
|
||||||
if (*root == NULL) {
|
if (network_status_lock_json_buffer(portMAX_DELAY)) {
|
||||||
*root = cJSON_CreateObject();
|
if (*root == NULL) {
|
||||||
}
|
*root = cJSON_CreateObject();
|
||||||
|
if (*root == NULL) {
|
||||||
|
ESP_LOGE(TAG, "Error creating cJSON object!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!key || !value || strlen(key) == 0)
|
if (!key || !value || strlen(key) == 0) {
|
||||||
return *root;
|
ESP_LOGE(TAG, "network_status_update_string. Invalid key or value passed! key: %s, value: %s", STR_OR_ALT(key, ""), STR_OR_ALT(value, ""));
|
||||||
cJSON* cjsonvalue = cJSON_GetObjectItemCaseSensitive(*root, key);
|
network_status_unlock_json_buffer();
|
||||||
if (cjsonvalue && strcasecmp(cJSON_GetStringValue(cjsonvalue), value) != 0) {
|
return *root;
|
||||||
ESP_LOGD(TAG, "Value %s changed from %s to %s", key, cJSON_GetStringValue(cjsonvalue), value);
|
}
|
||||||
cJSON_SetValuestring(cjsonvalue, value);
|
cJSON* cjsonvalue = cJSON_GetObjectItemCaseSensitive(*root, key);
|
||||||
|
if (cjsonvalue && strcasecmp(cJSON_GetStringValue(cjsonvalue), value) != 0) {
|
||||||
|
ESP_LOGD(TAG, "Value %s changed from %s to %s", key, cJSON_GetStringValue(cjsonvalue), value);
|
||||||
|
cJSON_SetValuestring(cjsonvalue, value);
|
||||||
|
} else {
|
||||||
|
cJSON_AddItemToObject(*root, key, cJSON_CreateString(value));
|
||||||
|
}
|
||||||
|
network_status_unlock_json_buffer();
|
||||||
} else {
|
} else {
|
||||||
cJSON_AddItemToObject(*root, key, cJSON_CreateString(value));
|
ESP_LOGW(TAG, "Unable to lock status json buffer. ");
|
||||||
}
|
}
|
||||||
return *root;
|
return *root;
|
||||||
}
|
}
|
||||||
cJSON* network_status_update_number(cJSON** root, const char* key, int value) {
|
cJSON* network_status_update_number(cJSON** root, const char* key, int value) {
|
||||||
if (wifi_manager_lock_json_buffer(portMAX_DELAY)) {
|
if (network_status_lock_json_buffer(portMAX_DELAY)) {
|
||||||
if (*root == NULL) {
|
if (*root == NULL) {
|
||||||
*root = cJSON_CreateObject();
|
*root = cJSON_CreateObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key && value && strlen(key) != 0) {
|
if (key && strlen(key) != 0) {
|
||||||
cJSON* cjsonvalue = cJSON_GetObjectItemCaseSensitive(*root, key);
|
cJSON* cjsonvalue = cJSON_GetObjectItemCaseSensitive(*root, key);
|
||||||
if (cjsonvalue) {
|
if (cjsonvalue) {
|
||||||
cJSON_SetNumberValue(cjsonvalue, value);
|
cJSON_SetNumberValue(cjsonvalue, value);
|
||||||
@@ -251,14 +229,14 @@ cJSON* network_status_update_number(cJSON** root, const char* key, int value) {
|
|||||||
cJSON_AddNumberToObject(*root, key, value);
|
cJSON_AddNumberToObject(*root, key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wifi_manager_unlock_json_buffer();
|
network_status_unlock_json_buffer();
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGW(TAG, "Unable to lock status json buffer. ");
|
ESP_LOGW(TAG, "Unable to lock status json buffer. ");
|
||||||
}
|
}
|
||||||
return *root;
|
return *root;
|
||||||
}
|
}
|
||||||
cJSON* network_status_update_float(cJSON** root, const char* key, float value) {
|
cJSON* network_status_update_float(cJSON** root, const char* key, float value) {
|
||||||
if (wifi_manager_lock_json_buffer(portMAX_DELAY)) {
|
if (network_status_lock_json_buffer(portMAX_DELAY)) {
|
||||||
if (*root == NULL) {
|
if (*root == NULL) {
|
||||||
*root = cJSON_CreateObject();
|
*root = cJSON_CreateObject();
|
||||||
}
|
}
|
||||||
@@ -271,14 +249,14 @@ cJSON* network_status_update_float(cJSON** root, const char* key, float value) {
|
|||||||
cJSON_AddNumberToObject(*root, key, value);
|
cJSON_AddNumberToObject(*root, key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wifi_manager_unlock_json_buffer();
|
network_status_unlock_json_buffer();
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGW(TAG, "Unable to lock status json buffer. ");
|
ESP_LOGW(TAG, "Unable to lock status json buffer. ");
|
||||||
}
|
}
|
||||||
return *root;
|
return *root;
|
||||||
}
|
}
|
||||||
cJSON* network_status_update_bool(cJSON** root, const char* key, bool value) {
|
cJSON* network_status_update_bool(cJSON** root, const char* key, bool value) {
|
||||||
if (wifi_manager_lock_json_buffer(portMAX_DELAY)) {
|
if (network_status_lock_json_buffer(portMAX_DELAY)) {
|
||||||
if (*root == NULL) {
|
if (*root == NULL) {
|
||||||
*root = cJSON_CreateObject();
|
*root = cJSON_CreateObject();
|
||||||
}
|
}
|
||||||
@@ -291,91 +269,110 @@ cJSON* network_status_update_bool(cJSON** root, const char* key, bool value) {
|
|||||||
cJSON_AddBoolToObject(*root, key, value);
|
cJSON_AddBoolToObject(*root, key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wifi_manager_unlock_json_buffer();
|
network_status_unlock_json_buffer();
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGW(TAG, "Unable to lock status json buffer. ");
|
ESP_LOGW(TAG, "Unable to lock status json buffer. ");
|
||||||
}
|
}
|
||||||
return *root;
|
return *root;
|
||||||
}
|
}
|
||||||
cJSON* wifi_manager_get_basic_info(cJSON** old) {
|
cJSON* network_status_get_basic_info(cJSON** old) {
|
||||||
int32_t total_connected_time = 0;
|
if (network_status_lock_json_buffer(portMAX_DELAY)) {
|
||||||
int64_t last_connected = 0;
|
network_t* nm = network_get_state_machine();
|
||||||
uint16_t num_disconnect = 0;
|
monitor_gpio_t* mgpio = get_jack_insertion_gpio();
|
||||||
network_wifi_get_stats(&total_connected_time, &last_connected, &num_disconnect);
|
const esp_app_desc_t* desc = esp_ota_get_app_description();
|
||||||
|
|
||||||
monitor_gpio_t* mgpio = get_jack_insertion_gpio();
|
*old = network_status_update_string(old, "project_name", desc->project_name);
|
||||||
const esp_app_desc_t* desc = esp_ota_get_app_description();
|
|
||||||
ESP_LOGV(TAG, "wifi_manager_get_basic_info called");
|
|
||||||
cJSON* root = network_status_update_string(&root, "project_name", desc->project_name);
|
|
||||||
#ifdef CONFIG_FW_PLATFORM_NAME
|
#ifdef CONFIG_FW_PLATFORM_NAME
|
||||||
root = network_status_update_string(&root, "platform_name", CONFIG_FW_PLATFORM_NAME);
|
*old = network_status_update_string(old, "platform_name", CONFIG_FW_PLATFORM_NAME);
|
||||||
#endif
|
#endif
|
||||||
root = network_status_update_string(&root, "version", desc->version);
|
*old = network_status_update_string(old, "version", desc->version);
|
||||||
if (release_url != NULL)
|
if (release_url != NULL)
|
||||||
root = network_status_update_string(&root, "release_url", release_url);
|
*old = network_status_update_string(old, "release_url", release_url);
|
||||||
root = network_status_update_number(&root, "recovery", is_recovery_running ? 1 : 0);
|
*old = network_status_update_number(old, "recovery", is_recovery_running ? 1 : 0);
|
||||||
root = network_status_update_bool(&root, "Jack", mgpio->gpio >= 0 && jack_inserted_svc());
|
*old = network_status_update_bool(old, "Jack", mgpio->gpio >= 0 && jack_inserted_svc());
|
||||||
root = network_status_update_float(&root, "Voltage", battery_value_svc());
|
*old = network_status_update_float(old, "Voltage", battery_value_svc());
|
||||||
root = network_status_update_number(&root, "disconnect_count", num_disconnect);
|
*old = network_status_update_number(old, "disconnect_count", nm->num_disconnect);
|
||||||
root = network_status_update_float(&root, "avg_conn_time", num_disconnect > 0 ? (total_connected_time / num_disconnect) : 0);
|
*old = network_status_update_float(old, "avg_conn_time", nm->num_disconnect > 0 ? (nm->total_connected_time / nm->num_disconnect) : 0);
|
||||||
root = network_status_update_number(&root, "bt_status", bt_app_source_get_a2d_state());
|
*old = network_status_update_number(old, "bt_status", bt_app_source_get_a2d_state());
|
||||||
root = network_status_update_number(&root, "bt_sub_status", bt_app_source_get_media_state());
|
*old = network_status_update_number(old, "bt_sub_status", bt_app_source_get_media_state());
|
||||||
|
|
||||||
#if CONFIG_I2C_LOCKED
|
#if CONFIG_I2C_LOCKED
|
||||||
root = network_status_update_bool(&root, "is_i2c_locked", true);
|
*old = network_status_update_bool(old, "is_i2c_locked", true);
|
||||||
#else
|
#else
|
||||||
root = network_status_update_bool(&root, "is_i2c_locked", false);
|
*old = network_status_update_bool(old, "is_i2c_locked", false);
|
||||||
#endif
|
#endif
|
||||||
if (network_ethernet_enabled()) {
|
if (network_ethernet_enabled()) {
|
||||||
root = network_status_update_bool(&root, "eth_up", network_ethernet_is_up());
|
*old = network_status_update_bool(old, "eth_up", network_ethernet_is_up());
|
||||||
}
|
}
|
||||||
ESP_LOGV(TAG, "wifi_manager_get_basic_info done");
|
if (lms_server_cport > 0) {
|
||||||
return root;
|
*old = network_status_update_number(old, "lms_cport", lms_server_cport);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wifi_manager_generate_ip_info_json(update_reason_code_t update_reason_code) {
|
if (lms_server_port > 0) {
|
||||||
ESP_LOGD(TAG, "wifi_manager_generate_ip_info_json called");
|
*old = network_status_update_number(old, "lms_port", lms_server_port);
|
||||||
|
}
|
||||||
|
|
||||||
if (wifi_manager_lock_json_buffer(portMAX_DELAY)) {
|
if (strlen(lms_server_ip) > 0) {
|
||||||
/* generate the connection info with success */
|
*old = network_status_update_string(old, "lms_ip", lms_server_ip);
|
||||||
|
}
|
||||||
ip_info_cjson = wifi_manager_get_basic_info(&ip_info_cjson);
|
ESP_LOGV(TAG, "network_status_get_basic_info done");
|
||||||
wifi_manager_unlock_json_buffer();
|
network_status_unlock_json_buffer();
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGW(TAG, "Unable to lock status json buffer. ");
|
ESP_LOGW(TAG, "Unable to lock status json buffer. ");
|
||||||
}
|
}
|
||||||
ip_info_cjson = network_status_update_number(&ip_info_cjson, "urc", update_reason_code);
|
return *old;
|
||||||
if (update_reason_code == UPDATE_CONNECTION_OK || update_reason_code == UPDATE_ETHERNET_CONNECTED) {
|
}
|
||||||
/* rest of the information is copied after the ssid */
|
void network_status_update_address(cJSON* root, esp_netif_ip_info_t* ip_info) {
|
||||||
tcpip_adapter_ip_info_t ip_info;
|
if (!root || !ip_info) {
|
||||||
esp_netif_get_ip_info(network_wifi_get_interface(), &ip_info);
|
ESP_LOGE(TAG, "Cannor update IP address. JSON structure or ip_info is null");
|
||||||
|
return;
|
||||||
network_status_update_string(&ip_info_cjson, "ip", ip4addr_ntoa((ip4_addr_t*)&ip_info.ip));
|
}
|
||||||
network_status_update_string(&ip_info_cjson, "netmask", ip4addr_ntoa((ip4_addr_t*)&ip_info.netmask));
|
network_status_update_string(&root, "ip", ip4addr_ntoa((ip4_addr_t*)&ip_info->ip));
|
||||||
network_status_update_string(&ip_info_cjson, "gw", ip4addr_ntoa((ip4_addr_t*)&ip_info.gw));
|
network_status_update_string(&root, "netmask", ip4addr_ntoa((ip4_addr_t*)&ip_info->netmask));
|
||||||
wifi_mode_t mode;
|
network_status_update_string(&root, "gw", ip4addr_ntoa((ip4_addr_t*)&ip_info->gw));
|
||||||
if (esp_wifi_get_mode(&mode) == ESP_OK && (mode == WIFI_MODE_STA || mode == WIFI_MODE_APSTA)) {
|
}
|
||||||
/* wifi is active, and associated to an AP */
|
void network_status_update_ip_info(update_reason_code_t update_reason_code) {
|
||||||
wifi_ap_record_t ap;
|
ESP_LOGV(TAG, "network_status_update_ip_info called");
|
||||||
esp_wifi_sta_get_ap_info(&ap);
|
esp_netif_ip_info_t ip_info;
|
||||||
network_status_update_string(&ip_info_cjson, "ssid", ((char*)ap.ssid));
|
if (network_status_lock_json_buffer(portMAX_DELAY)) {
|
||||||
network_status_update_number(&ip_info_cjson, "rssi", ap.rssi);
|
/* generate the connection info with success */
|
||||||
}
|
|
||||||
if (network_ethernet_is_up()) {
|
ip_info_cjson = network_status_get_basic_info(&ip_info_cjson);
|
||||||
esp_netif_get_ip_info(network_ethernet_get_interface(), &ip_info);
|
ip_info_cjson = network_status_update_number(&ip_info_cjson, "urc", update_reason_code);
|
||||||
cJSON* ethernet_ip = cJSON_CreateObject();
|
ESP_LOGD(TAG,"Updating ip info with reason code %d. Checking if Wifi interface is connected",update_reason_code);
|
||||||
cJSON_AddItemToObject(ethernet_ip, "ip", cJSON_CreateString(ip4addr_ntoa((ip4_addr_t*)&ip_info.ip)));
|
if (network_is_interface_connected(network_wifi_get_interface())) {
|
||||||
cJSON_AddItemToObject(ethernet_ip, "netmask", cJSON_CreateString(ip4addr_ntoa((ip4_addr_t*)&ip_info.netmask)));
|
|
||||||
cJSON_AddItemToObject(ethernet_ip, "gw", cJSON_CreateString(ip4addr_ntoa((ip4_addr_t*)&ip_info.gw)));
|
esp_netif_get_ip_info(network_wifi_get_interface(), &ip_info);
|
||||||
cJSON_AddItemToObject(ip_info_cjson, "eth", ethernet_ip);
|
network_status_update_address(ip_info_cjson, &ip_info);
|
||||||
}
|
if (!network_wifi_is_ap_mode()) {
|
||||||
} else {
|
/* wifi is active, and associated to an AP */
|
||||||
cJSON_DeleteItemFromObjectCaseSensitive(ip_info_cjson, "ip");
|
wifi_ap_record_t ap;
|
||||||
cJSON_DeleteItemFromObjectCaseSensitive(ip_info_cjson, "netmask");
|
esp_wifi_sta_get_ap_info(&ap);
|
||||||
cJSON_DeleteItemFromObjectCaseSensitive(ip_info_cjson, "gw");
|
network_status_update_string(&ip_info_cjson, "ssid", ((char*)ap.ssid));
|
||||||
cJSON_DeleteItemFromObjectCaseSensitive(ip_info_cjson, "rssi");
|
network_status_update_number(&ip_info_cjson, "rssi", ap.rssi);
|
||||||
cJSON_DeleteItemFromObjectCaseSensitive(ip_info_cjson, "ssid");
|
}
|
||||||
cJSON_DeleteItemFromObjectCaseSensitive(ip_info_cjson, "eth");
|
|
||||||
}
|
} else {
|
||||||
ESP_LOGV(TAG, "wifi_manager_generate_ip_info_json done");
|
cJSON_DeleteItemFromObjectCaseSensitive(ip_info_cjson, "ip");
|
||||||
|
cJSON_DeleteItemFromObjectCaseSensitive(ip_info_cjson, "netmask");
|
||||||
|
cJSON_DeleteItemFromObjectCaseSensitive(ip_info_cjson, "gw");
|
||||||
|
cJSON_DeleteItemFromObjectCaseSensitive(ip_info_cjson, "rssi");
|
||||||
|
cJSON_DeleteItemFromObjectCaseSensitive(ip_info_cjson, "ssid");
|
||||||
|
}
|
||||||
|
ESP_LOGD(TAG,"Checking if ethernet interface is connected");
|
||||||
|
if (network_is_interface_connected(network_ethernet_get_interface())) {
|
||||||
|
cJSON* ethernet_ip = cJSON_GetObjectItem(ip_info_cjson, "eth");
|
||||||
|
if (!ethernet_ip) {
|
||||||
|
ethernet_ip = cJSON_CreateObject();
|
||||||
|
cJSON_AddItemToObject(ip_info_cjson, "eth", ethernet_ip);
|
||||||
|
}
|
||||||
|
esp_netif_get_ip_info(network_ethernet_get_interface(), &ip_info);
|
||||||
|
network_status_update_address(ethernet_ip, &ip_info);
|
||||||
|
} else {
|
||||||
|
cJSON_DeleteItemFromObjectCaseSensitive(ip_info_cjson, "eth");
|
||||||
|
}
|
||||||
|
network_status_unlock_json_buffer();
|
||||||
|
} else {
|
||||||
|
ESP_LOGW(TAG, "Unable to lock status json buffer. ");
|
||||||
|
}
|
||||||
|
ESP_LOGV(TAG, "wifi_status_generate_ip_info_json done");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
char* wifi_manager_alloc_get_ip_info_json();
|
char* network_status_alloc_get_ip_info_json();
|
||||||
/**
|
/**
|
||||||
* @brief Tries to get access to json buffer mutex.
|
* @brief Tries to get access to json buffer mutex.
|
||||||
*
|
*
|
||||||
@@ -21,39 +21,39 @@ char* wifi_manager_alloc_get_ip_info_json();
|
|||||||
* @param xTicksToWait The time in ticks to wait for the semaphore to become available.
|
* @param xTicksToWait The time in ticks to wait for the semaphore to become available.
|
||||||
* @return true in success, false otherwise.
|
* @return true in success, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool wifi_manager_lock_json_buffer(TickType_t xTicksToWait);
|
bool network_status_lock_json_buffer(TickType_t xTicksToWait);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Releases the json buffer mutex.
|
* @brief Releases the json buffer mutex.
|
||||||
*/
|
*/
|
||||||
void wifi_manager_unlock_json_buffer();
|
void network_status_unlock_json_buffer();
|
||||||
|
|
||||||
bool wifi_manager_lock_sta_ip_string(TickType_t xTicksToWait);
|
bool network_status_lock_sta_ip_string(TickType_t xTicksToWait);
|
||||||
void wifi_manager_unlock_sta_ip_string();
|
void network_status_unlock_sta_ip_string();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief gets the string representation of the STA IP address, e.g.: "192.168.1.69"
|
* @brief gets the string representation of the STA IP address, e.g.: "192.168.1.69"
|
||||||
*/
|
*/
|
||||||
char* wifi_manager_get_sta_ip_string();
|
char* network_status_get_sta_ip_string();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief thread safe char representation of the STA IP update
|
* @brief thread safe char representation of the STA IP update
|
||||||
*/
|
*/
|
||||||
void wifi_manager_safe_update_sta_ip_string(esp_ip4_addr_t * ip4);
|
void network_status_safe_update_sta_ip_string(esp_ip4_addr_t * ip4);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Generates the connection status json: ssid and IP addresses.
|
* @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.
|
* @note This is not thread-safe and should be called only if network_status_lock_json_buffer call is successful.
|
||||||
*/
|
*/
|
||||||
void wifi_manager_generate_ip_info_json(update_reason_code_t update_reason_code);
|
void network_status_update_ip_info(update_reason_code_t update_reason_code);
|
||||||
|
|
||||||
void init_network_status();
|
void init_network_status();
|
||||||
void destroy_network_status();
|
void destroy_network_status();
|
||||||
cJSON* wifi_manager_get_basic_info(cJSON** old);
|
cJSON* network_status_get_basic_info(cJSON** old);
|
||||||
|
|
||||||
void wifi_manager_update_basic_info();
|
void network_status_update_basic_info();
|
||||||
void network_status_clear_ip();
|
void network_status_clear_ip();
|
||||||
void wifi_manager_safe_reset_sta_ip_string();
|
void network_status_safe_reset_sta_ip_string();
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
void init_network_wifi();
|
esp_netif_t * network_wifi_start();
|
||||||
void destroy_network_wifi();
|
void destroy_network_wifi();
|
||||||
/**
|
/**
|
||||||
* @brief saves the current STA wifi config to flash ram storage.
|
* @brief saves the current STA wifi config to flash ram storage.
|
||||||
@@ -16,46 +16,59 @@ esp_err_t network_wifi_save_sta_config();
|
|||||||
* @brief fetch a previously STA wifi config in the flash ram storage.
|
* @brief fetch a previously STA wifi config in the flash ram storage.
|
||||||
* @return true if a previously saved config was found, false otherwise.
|
* @return true if a previously saved config was found, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool wifi_manager_fetch_wifi_sta_config();
|
bool network_wifi_load_wifi_sta_config();
|
||||||
|
|
||||||
wifi_config_t* wifi_manager_get_wifi_sta_config();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Registers handler for wifi and ip events
|
* @brief Registers handler for wifi and ip events
|
||||||
*/
|
*/
|
||||||
void wifi_manager_register_handlers();
|
void network_wifi_register_handlers();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Generates the list of access points after a wifi scan.
|
* @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.
|
* @note This is not thread-safe and should be called only if network_status_lock_json_buffer call is successful.
|
||||||
*/
|
*/
|
||||||
void wifi_manager_generate_access_points_json(cJSON ** ap_list);
|
void network_wifi_generate_access_points_json(cJSON ** ap_list);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Clear the list of access points.
|
* @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.
|
* @note This is not thread-safe and should be called only if network_status_lock_json_buffer call is successful.
|
||||||
*/
|
*/
|
||||||
void wifi_manager_clear_access_points_json();
|
void network_wifi_clear_access_points_json();
|
||||||
|
|
||||||
|
|
||||||
void wifi_manager_config_ap();
|
esp_netif_t * network_wifi_config_ap();
|
||||||
|
|
||||||
void wifi_manager_filter_unique( wifi_ap_record_t * aplist, uint16_t * aps);
|
void network_wifi_filter_unique( wifi_ap_record_t * aplist, uint16_t * aps);
|
||||||
esp_err_t wifi_scan_done(queue_message *msg);
|
esp_err_t wifi_scan_done();
|
||||||
esp_err_t network_wifi_start_scan(queue_message *msg);
|
esp_err_t network_wifi_start_scan();
|
||||||
esp_err_t network_wifi_load_restore(queue_message *msg);
|
esp_err_t network_wifi_load_restore(queue_message *msg);
|
||||||
esp_err_t network_wifi_order_connect(queue_message *msg);
|
esp_err_t network_wifi_order_connect(queue_message *msg);
|
||||||
esp_err_t network_wifi_disconnected(queue_message *msg);
|
esp_err_t network_wifi_disconnected(queue_message *msg);
|
||||||
esp_err_t network_wifi_start_ap(queue_message *msg);
|
esp_err_t network_wifi_start_ap(queue_message *msg);
|
||||||
bool wifi_manager_load_wifi_sta_config(wifi_config_t* config );
|
bool network_wifi_get_config_for_ssid(wifi_config_t* config, const char * ssid);
|
||||||
esp_err_t network_wifi_handle_event(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
|
esp_err_t network_wifi_handle_event(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
|
||||||
esp_err_t network_wifi_connect(wifi_config_t * cfg);
|
|
||||||
bool is_wifi_up();
|
bool is_wifi_up();
|
||||||
|
wifi_config_t* network_wifi_set_wifi_sta_config(const char * ssid, const char * password) ;
|
||||||
void network_wifi_clear_config();
|
void network_wifi_clear_config();
|
||||||
esp_netif_t *network_wifi_get_interface();
|
esp_netif_t *network_wifi_get_interface();
|
||||||
|
esp_netif_t *network_wifi_get_ap_interface();
|
||||||
|
bool network_wifi_is_ap_sta_mode();
|
||||||
|
bool network_wifi_is_sta_mode();
|
||||||
|
bool network_wifi_is_ap_mode();
|
||||||
bool network_wifi_sta_config_changed();
|
bool network_wifi_sta_config_changed();
|
||||||
void network_wifi_get_stats( int32_t * ret_total_connected_time, int64_t * ret_last_connected, uint16_t * ret_num_disconnect);
|
void network_wifi_global_init();
|
||||||
|
bool network_wifi_is_known_ap(const char * ssid);
|
||||||
|
esp_err_t network_wifi_connect(const char * ssid, const char * password);
|
||||||
|
esp_err_t network_wifi_erase_legacy();
|
||||||
|
esp_err_t network_wifi_connect_ssid(const char * ssid);
|
||||||
|
esp_err_t network_wifi_connect_active_ssid();
|
||||||
|
esp_err_t network_wifi_erase_known_ap();
|
||||||
|
esp_err_t network_wifi_set_sta_mode();
|
||||||
|
size_t network_wifi_get_known_count();
|
||||||
|
esp_err_t network_wifi_built_known_ap_list();
|
||||||
|
|
||||||
|
const wifi_sta_config_t* network_wifi_load_active_config();
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 901 B |
@@ -1,793 +0,0 @@
|
|||||||
#include <state_machine.hpp>
|
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
|
||||||
#include "cmd_system.h"
|
|
||||||
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
|
|
||||||
#include "esp_log.h"
|
|
||||||
#include "esp_wifi_types.h"
|
|
||||||
#include "http_server_handlers.h"
|
|
||||||
#include "messaging.h"
|
|
||||||
#include "network_ethernet.h"
|
|
||||||
#include "network_status.h"
|
|
||||||
#include "network_wifi.h"
|
|
||||||
#include "state_machine.h"
|
|
||||||
#include "trace.h"
|
|
||||||
#include "dns_server.h"
|
|
||||||
BaseType_t network_manager_task;
|
|
||||||
/* objects used to manipulate the main queue of events */
|
|
||||||
QueueHandle_t network_manager_queue;
|
|
||||||
|
|
||||||
using namespace stateless;
|
|
||||||
using namespace std::placeholders;
|
|
||||||
static const char TAG[] = "network_manager";
|
|
||||||
static TaskHandle_t task_network_manager = NULL;
|
|
||||||
TimerHandle_t STA_timer = NULL;
|
|
||||||
uint32_t STA_duration;
|
|
||||||
|
|
||||||
static int32_t total_connected_time = 0;
|
|
||||||
static int64_t last_connected = 0;
|
|
||||||
static uint16_t num_disconnect = 0;
|
|
||||||
void network_wifi_get_stats(int32_t* ret_total_connected_time, int64_t* ret_last_connected, uint16_t* ret_num_disconnect) {
|
|
||||||
*ret_total_connected_time = total_connected_time;
|
|
||||||
*ret_last_connected = last_connected;
|
|
||||||
*ret_num_disconnect = num_disconnect;
|
|
||||||
}
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, const state_t s) {
|
|
||||||
//static const char* name[] = { "idle", "stopped", "started", "running" };
|
|
||||||
static const char* name[] = {
|
|
||||||
|
|
||||||
"initializing",
|
|
||||||
"global",
|
|
||||||
"eth_starting",
|
|
||||||
"eth_active",
|
|
||||||
"eth_active_linkup",
|
|
||||||
"eth_active_connected",
|
|
||||||
"eth_active_linkdown",
|
|
||||||
"wifi_up",
|
|
||||||
"wifi_initializing",
|
|
||||||
"network_manager_async",
|
|
||||||
"wifi_connecting_scanning",
|
|
||||||
"wifi_connecting",
|
|
||||||
"wifi_connected",
|
|
||||||
"wifi_disconnecting",
|
|
||||||
"wifi_user_disconnected",
|
|
||||||
"wifi_connected_waiting_for_ip",
|
|
||||||
"wifi_connected_scanning",
|
|
||||||
"wifi_lost_connection",
|
|
||||||
"wifi_ap_mode",
|
|
||||||
"wifi_ap_mode_scanning",
|
|
||||||
"wifi_ap_mode_scan_done",
|
|
||||||
"wifi_ap_mode_connecting",
|
|
||||||
"wifi_ap_mode_connected",
|
|
||||||
"system_rebooting"};
|
|
||||||
os << name[(int)s];
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* trigger_to_string(trig_t trigger) {
|
|
||||||
switch (trigger) {
|
|
||||||
ENUM_TO_STRING(t_link_up);
|
|
||||||
ENUM_TO_STRING(t_link_down);
|
|
||||||
ENUM_TO_STRING(t_configure);
|
|
||||||
ENUM_TO_STRING(t_got_ip);
|
|
||||||
ENUM_TO_STRING(t_next);
|
|
||||||
ENUM_TO_STRING(t_start);
|
|
||||||
ENUM_TO_STRING(t_scan);
|
|
||||||
ENUM_TO_STRING(t_fail);
|
|
||||||
ENUM_TO_STRING(t_success);
|
|
||||||
ENUM_TO_STRING(t_scan_done);
|
|
||||||
ENUM_TO_STRING(t_connect);
|
|
||||||
ENUM_TO_STRING(t_reboot);
|
|
||||||
ENUM_TO_STRING(t_reboot_url);
|
|
||||||
ENUM_TO_STRING(t_lost_connection);
|
|
||||||
ENUM_TO_STRING(t_update_status);
|
|
||||||
ENUM_TO_STRING(t_disconnect);
|
|
||||||
default:
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return "Unknown trigger";
|
|
||||||
}
|
|
||||||
std::ostream& operator<<(std::ostream& os, const trig_t & t) {
|
|
||||||
//static const char* name[] = { "start", "stop", "set_speed", "halt" };
|
|
||||||
os << trigger_to_string(t);
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
// namespace stateless
|
|
||||||
// {
|
|
||||||
|
|
||||||
// template<> void print_state<state>(std::ostream& os, const state& s)
|
|
||||||
// { os << s; }
|
|
||||||
|
|
||||||
// template<> void print_trigger<trigger_t_t(std::ostream& os, const trigger& t)
|
|
||||||
// { os << t; }
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
// namespace
|
|
||||||
// {
|
|
||||||
|
|
||||||
// class network_manager
|
|
||||||
// {
|
|
||||||
// public:
|
|
||||||
// network_manager()
|
|
||||||
// : sm_(state_t::initializing)
|
|
||||||
// ,
|
|
||||||
// {
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
// sm_.configure(state_t::idle)
|
|
||||||
// .permit(trig_t::t_start, state_t::started);
|
|
||||||
|
|
||||||
// sm_.configure(state_t::stopped)
|
|
||||||
// .on_entry([=](const TTransition&) { speed_ = 0; })
|
|
||||||
// .permit(trig_t::t_halt, state_t::idle);
|
|
||||||
|
|
||||||
// sm_.configure(state_t::started)
|
|
||||||
// .permit(trig_t::t_set_speed, state_t::running)
|
|
||||||
// .permit(trig_t::t_stop, state_t::stopped);
|
|
||||||
|
|
||||||
// sm_.configure(state_t::running)
|
|
||||||
// .on_entry_from(
|
|
||||||
// set_speed_trigger_,
|
|
||||||
// [=](const TTransition& t, int speed) { speed_ = speed; })
|
|
||||||
// .permit(trig_t::t_stop, state_t::stopped)
|
|
||||||
// .permit_reentry(trig_t::t_set_speed);
|
|
||||||
|
|
||||||
// void start(int speed)
|
|
||||||
// {
|
|
||||||
// sm_.fire(trig_t::t_start);
|
|
||||||
// set_speed(speed);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// void stop()
|
|
||||||
// {
|
|
||||||
// sm_.fire(trig_t::t_stop);
|
|
||||||
// sm_.fire(trig_t::t_halt);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// void set_speed(int speed)
|
|
||||||
// {
|
|
||||||
// sm_.fire(set_speed_trigger_, speed);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// std::string print() const
|
|
||||||
// {
|
|
||||||
// std::ostringstream oss;
|
|
||||||
// print(oss);
|
|
||||||
// return oss.str();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// void print(std::ostream& os) const
|
|
||||||
// {
|
|
||||||
// os << "Motor " << sm_ << " speed = " << speed_;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// private:
|
|
||||||
|
|
||||||
// //typedef std::shared_ptr<stateless::trigger_with_parameters<trigger_t, int>> TSetSpeedTrigger;
|
|
||||||
|
|
||||||
// wifi_config_t * wifi_config;
|
|
||||||
// TStateMachine sm_;
|
|
||||||
// ;
|
|
||||||
// ;
|
|
||||||
// };
|
|
||||||
|
|
||||||
// std::ostream& operator<<(std::ostream& os, const motor& m)
|
|
||||||
// {
|
|
||||||
// m.print(os);
|
|
||||||
// return os;
|
|
||||||
// }
|
|
||||||
|
|
||||||
//}
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
typedef state_machine<state_t, trig_t> TStateMachine;
|
|
||||||
typedef TStateMachine::TTransition TTransition;
|
|
||||||
typedef std::shared_ptr<stateless::trigger_with_parameters<trig_t, wifi_config_t*>> TConnectTrigger;
|
|
||||||
typedef std::shared_ptr<stateless::trigger_with_parameters<trig_t, reboot_type_t>> TRebootTrigger;
|
|
||||||
typedef std::shared_ptr<stateless::trigger_with_parameters<trig_t, char*>> TRebootOTATrigger;
|
|
||||||
typedef std::shared_ptr<stateless::trigger_with_parameters<trig_t, wifi_event_sta_disconnected_t*>> TDisconnectTrigger;
|
|
||||||
|
|
||||||
}; // namespace
|
|
||||||
|
|
||||||
class NetworkManager {
|
|
||||||
public:
|
|
||||||
NetworkManager()
|
|
||||||
: sm_(state_t::instantiated),
|
|
||||||
connect_trigger_(sm_.set_trigger_parameters<wifi_config_t*>(trig_t::t_connect)),
|
|
||||||
reboot_trigger_(sm_.set_trigger_parameters<reboot_type_t>(trig_t::t_reboot)),
|
|
||||||
reboot_ota_(sm_.set_trigger_parameters<char*>(trig_t::t_reboot)),
|
|
||||||
disconnected_(sm_.set_trigger_parameters<wifi_event_sta_disconnected_t*>(trig_t::t_lost_connection)) {
|
|
||||||
sm_.configure(state_t::instantiated)
|
|
||||||
.permit(trig_t::t_start, state_t::initializing);
|
|
||||||
sm_.configure(state_t::global)
|
|
||||||
.permit(trig_t::t_reboot, state_t::system_rebooting)
|
|
||||||
.permit(trig_t::t_reboot_url, state_t::system_rebooting)
|
|
||||||
.permit_reentry(trig_t::t_update_status)
|
|
||||||
.on_entry_from(trig_t::t_update_status,
|
|
||||||
[=](const TTransition& t) {
|
|
||||||
wifi_manager_update_basic_info();
|
|
||||||
});
|
|
||||||
sm_.configure(state_t::system_rebooting)
|
|
||||||
.on_entry_from(reboot_ota_, [=](const TTransition& t, char* url) {
|
|
||||||
if (url) {
|
|
||||||
start_ota(url, NULL, 0);
|
|
||||||
free(url);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.on_entry_from(reboot_trigger_, [=](const TTransition& t, reboot_type_t reboot_type) {
|
|
||||||
switch (reboot_type) {
|
|
||||||
case reboot_type_t::OTA:
|
|
||||||
ESP_LOGD(TAG, "Calling guided_restart_ota.");
|
|
||||||
guided_restart_ota();
|
|
||||||
break;
|
|
||||||
case reboot_type_t::RECOVERY:
|
|
||||||
ESP_LOGD(TAG, "Calling guided_factory.");
|
|
||||||
guided_factory();
|
|
||||||
break;
|
|
||||||
case reboot_type_t::RESTART:
|
|
||||||
ESP_LOGD(TAG, "Calling simple_restart.");
|
|
||||||
simple_restart();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
sm_.configure(state_t::initializing)
|
|
||||||
.on_entry([=](const TTransition& t) {
|
|
||||||
/* memory allocation */
|
|
||||||
ESP_LOGD(TAG, "network_manager_start. Creating message queue");
|
|
||||||
network_manager_queue = xQueueCreate(3, sizeof(queue_message));
|
|
||||||
ESP_LOGD(TAG, "network_manager_start. Allocating memory for callback functions registration");
|
|
||||||
// todo: allow registration of event callbacks
|
|
||||||
ESP_LOGD(TAG, "Initializing tcp_ip adapter");
|
|
||||||
esp_netif_init();
|
|
||||||
ESP_LOGD(TAG, "Creating the default event loop");
|
|
||||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
|
||||||
init_network_status();
|
|
||||||
ESP_LOGD(TAG, "Initializing network. done");
|
|
||||||
|
|
||||||
/* start wifi manager task */
|
|
||||||
ESP_LOGD(TAG, "Creating network manager task");
|
|
||||||
network_manager_task = xTaskCreate(&network_manager, "network_manager", 4096, NULL, WIFI_MANAGER_TASK_PRIORITY, &task_network_manager);
|
|
||||||
// send a message to start the connections
|
|
||||||
})
|
|
||||||
.permit(trig_t::t_start, state_t::eth_starting);
|
|
||||||
sm_.configure(state_t::eth_starting)
|
|
||||||
.on_entry([=](const TTransition& t) {
|
|
||||||
/* start http server */
|
|
||||||
http_server_start();
|
|
||||||
ESP_LOGD(TAG, "network_manager task started. Configuring Network Interface");
|
|
||||||
init_network_ethernet();
|
|
||||||
})
|
|
||||||
.permit(trig_t::t_fail, state_t::wifi_initializing)
|
|
||||||
.permit(trig_t::t_success, state_t::eth_active);
|
|
||||||
|
|
||||||
sm_.configure(state_t::eth_active)
|
|
||||||
.permit(trig_t::t_link_up, state_t::eth_active_linkup)
|
|
||||||
.permit(trig_t::t_got_ip, state_t::eth_active_connected)
|
|
||||||
.permit(trig_t::t_link_down, state_t::eth_active_linkdown)
|
|
||||||
.permit(trig_t::t_fail, state_t::wifi_initializing);
|
|
||||||
|
|
||||||
sm_.configure(state_t::eth_active_linkup)
|
|
||||||
.sub_state_of(state_t::eth_active)
|
|
||||||
.on_entry([=](const TTransition& t) {
|
|
||||||
// Anything we need to do on link becoming active?
|
|
||||||
});
|
|
||||||
sm_.configure(state_t::eth_active_linkdown)
|
|
||||||
.sub_state_of(state_t::eth_active)
|
|
||||||
.on_entry([=](const TTransition& t) {
|
|
||||||
// If not connected after a certain time, start
|
|
||||||
// wifi
|
|
||||||
});
|
|
||||||
sm_.configure(state_t::eth_active_connected)
|
|
||||||
.sub_state_of(state_t::eth_active)
|
|
||||||
.on_entry([=](const TTransition& t) {
|
|
||||||
|
|
||||||
})
|
|
||||||
.on_exit([=](const TTransition& t) {
|
|
||||||
|
|
||||||
});
|
|
||||||
sm_.configure(state_t::wifi_up)
|
|
||||||
.on_entry([=](const TTransition& t) {
|
|
||||||
|
|
||||||
})
|
|
||||||
.on_exit([=](const TTransition& t) {
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
sm_.configure(state_t::wifi_initializing)
|
|
||||||
.sub_state_of(state_t::wifi_up)
|
|
||||||
.on_entry([=](const TTransition& t) {
|
|
||||||
esp_err_t err = ESP_OK;
|
|
||||||
ESP_LOGD(TAG, "network_wifi_load_restore");
|
|
||||||
if (!is_wifi_up()) {
|
|
||||||
messaging_post_message(MESSAGING_WARNING, MESSAGING_CLASS_SYSTEM, "Wifi not started. Load Configuration");
|
|
||||||
return ESP_FAIL;
|
|
||||||
}
|
|
||||||
if (wifi_manager_fetch_wifi_sta_config()) {
|
|
||||||
ESP_LOGI(TAG, "Saved wifi found on startup. Will attempt to connect.");
|
|
||||||
network_manager_async_connect(wifi_manager_get_wifi_sta_config());
|
|
||||||
} else {
|
|
||||||
/* no wifi saved: start soft AP! This is what should happen during a first run */
|
|
||||||
ESP_LOGD(TAG, "No saved wifi. Starting AP.");
|
|
||||||
network_manager_async_configure();
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
})
|
|
||||||
.permit(trig_t::t_configure, state_t::wifi_ap_mode)
|
|
||||||
.permit(trig_t::t_connect, state_t::wifi_connecting_scanning);
|
|
||||||
|
|
||||||
sm_.configure(state_t::wifi_connecting_scanning)
|
|
||||||
.sub_state_of(state_t::wifi_up)
|
|
||||||
.on_entry_from(connect_trigger_, [=](const TTransition& t, wifi_config_t* wifi_config) {
|
|
||||||
if (network_wifi_connect(wifi_config) == ESP_OK) {
|
|
||||||
network_manager_async_connect(wifi_config);
|
|
||||||
} else {
|
|
||||||
network_manager_async_fail();
|
|
||||||
}
|
|
||||||
|
|
||||||
// STA_duration = STA_POLLING_MIN;
|
|
||||||
// /* create timer for background STA connection */
|
|
||||||
// if (!STA_timer) {
|
|
||||||
// STA_timer = xTimerCreate("background STA", pdMS_TO_TICKS(STA_duration), pdFALSE, NULL, polling_STA);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// setup a timeout here. On timeout,
|
|
||||||
// check reconnect_attempts and
|
|
||||||
// fire trig_t::t_scan if we have more attempts to try
|
|
||||||
// fire trig_t::t_fail otherwise
|
|
||||||
})
|
|
||||||
.permit_reentry_if(trig_t::t_scan, [&]() {
|
|
||||||
return ++reconnect_attempt < 3;
|
|
||||||
})
|
|
||||||
.permit(trig_t::t_connect, state_t::wifi_connecting)
|
|
||||||
.permit(trig_t::t_fail, state_t::wifi_lost_connection);
|
|
||||||
|
|
||||||
sm_.configure(state_t::wifi_connecting)
|
|
||||||
.on_entry_from(connect_trigger_, [=](const TTransition& t, wifi_config_t* wifi_config) {
|
|
||||||
// setup a timeout here. On timeout,
|
|
||||||
// check reconnect_attempts and
|
|
||||||
// fire trig_t::t_wifi_connecting_existing if we have more attempts to try
|
|
||||||
// fire trig_t::t_fail otherwise
|
|
||||||
})
|
|
||||||
.permit(trig_t::t_success, state_t::wifi_connected_waiting_for_ip)
|
|
||||||
.permit(trig_t::t_got_ip, state_t::wifi_connected)
|
|
||||||
.permit(trig_t::t_lost_connection, state_t::wifi_ap_mode);
|
|
||||||
sm_.configure(state_t::wifi_connected_waiting_for_ip)
|
|
||||||
.permit(trig_t::t_got_ip, state_t::wifi_connected);
|
|
||||||
|
|
||||||
sm_.configure(state_t::wifi_ap_mode)
|
|
||||||
.on_entry([=](const TTransition& t) {
|
|
||||||
wifi_manager_config_ap();
|
|
||||||
ESP_LOGD(TAG, "AP Starting, requesting wifi scan.");
|
|
||||||
network_manager_async_scan();
|
|
||||||
})
|
|
||||||
.on_entry_from(disconnected_, [=](const TTransition& t, wifi_event_sta_disconnected_t* disconnected_event) {
|
|
||||||
if(disconnected_event){
|
|
||||||
free(disconnected_event);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.permit(trig_t::t_scan, state_t::wifi_ap_mode_scanning);
|
|
||||||
|
|
||||||
sm_.configure(state_t::wifi_ap_mode_scanning)
|
|
||||||
.on_entry([=](const TTransition& t) {
|
|
||||||
// build a list of found AP
|
|
||||||
})
|
|
||||||
.permit(trig_t::t_scan_done, state_t::wifi_ap_mode_scan_done);
|
|
||||||
|
|
||||||
sm_.configure(state_t::wifi_ap_mode_scan_done)
|
|
||||||
.permit(trig_t::t_connect, state_t::wifi_ap_mode_connecting);
|
|
||||||
sm_.configure(state_t::wifi_ap_mode_connecting)
|
|
||||||
.on_entry_from(connect_trigger_, [=](const TTransition& t, wifi_config_t* wifi_config) {
|
|
||||||
|
|
||||||
})
|
|
||||||
.permit(trig_t::t_got_ip, state_t::wifi_ap_mode_connected)
|
|
||||||
.permit(trig_t::t_fail, state_t::wifi_ap_mode);
|
|
||||||
|
|
||||||
sm_.configure(state_t::wifi_ap_mode_connected)
|
|
||||||
.on_entry([=](const TTransition& t) {
|
|
||||||
|
|
||||||
})
|
|
||||||
.permit(trig_t::t_success, state_t::wifi_connected);
|
|
||||||
|
|
||||||
sm_.configure(state_t::wifi_connected)
|
|
||||||
.on_entry([&](const TTransition& t) {
|
|
||||||
last_connected = esp_timer_get_time();
|
|
||||||
/* bring down DNS hijack */
|
|
||||||
ESP_LOGD(TAG, "Stopping DNS.");
|
|
||||||
dns_server_stop();
|
|
||||||
if (network_wifi_sta_config_changed()) {
|
|
||||||
network_wifi_save_sta_config();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* stop AP mode */
|
|
||||||
esp_wifi_set_mode(WIFI_MODE_STA);
|
|
||||||
})
|
|
||||||
.permit_reentry(trig_t::t_scan_done)
|
|
||||||
.permit(trig_t::t_lost_connection, state_t::wifi_lost_connection)
|
|
||||||
.permit(trig_t::t_scan, state_t::wifi_connected_scanning)
|
|
||||||
.permit(trig_t::t_disconnect, state_t::wifi_disconnecting)
|
|
||||||
.permit(trig_t::t_connect, state_t::wifi_connecting);
|
|
||||||
|
|
||||||
sm_.configure(state_t::wifi_disconnecting)
|
|
||||||
.permit(trig_t::t_lost_connection, state_t::wifi_user_disconnected);
|
|
||||||
sm_.configure(state_t::wifi_user_disconnected)
|
|
||||||
.on_entry_from(disconnected_,
|
|
||||||
[=](const TTransition& t, wifi_event_sta_disconnected_t* disconnected_event) {
|
|
||||||
ESP_LOGD(TAG, "WiFi disconnected by user");
|
|
||||||
network_wifi_clear_config();
|
|
||||||
wifi_manager_generate_ip_info_json(UPDATE_USER_DISCONNECT);
|
|
||||||
network_manager_async_configure();
|
|
||||||
if (disconnected_event) {
|
|
||||||
free(disconnected_event);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.permit(trig_t::t_configure, state_t::wifi_ap_mode);
|
|
||||||
sm_.configure(state_t::wifi_lost_connection)
|
|
||||||
.on_entry_from(disconnected_,
|
|
||||||
[=](const TTransition& t, wifi_event_sta_disconnected_t* disconnected_event) {
|
|
||||||
ESP_LOGE(TAG, "WiFi Connection lost.");
|
|
||||||
messaging_post_message(MESSAGING_WARNING, MESSAGING_CLASS_SYSTEM, "WiFi Connection lost");
|
|
||||||
wifi_manager_generate_ip_info_json(UPDATE_LOST_CONNECTION);
|
|
||||||
if (last_connected > 0)
|
|
||||||
total_connected_time += ((esp_timer_get_time() - last_connected) / (1000 * 1000));
|
|
||||||
last_connected = 0;
|
|
||||||
num_disconnect++;
|
|
||||||
ESP_LOGW(TAG, "Wifi disconnected. Number of disconnects: %d, Average time connected: %d", num_disconnect, num_disconnect > 0 ? (total_connected_time / num_disconnect) : 0);
|
|
||||||
//network_manager_async_connect(wifi_manager_get_wifi_sta_config());
|
|
||||||
if (retries < WIFI_MANAGER_MAX_RETRY) {
|
|
||||||
ESP_LOGD(TAG, "Issuing ORDER_CONNECT_STA to retry connection.");
|
|
||||||
retries++;
|
|
||||||
network_manager_async_connect(wifi_manager_get_wifi_sta_config());
|
|
||||||
free(disconnected_event);
|
|
||||||
} else {
|
|
||||||
/* In this scenario the connection was lost beyond repair: kick start the AP! */
|
|
||||||
retries = 0;
|
|
||||||
wifi_mode_t mode;
|
|
||||||
ESP_LOGW(TAG, "All connect retry attempts failed.");
|
|
||||||
|
|
||||||
/* put us in softAP mode first */
|
|
||||||
esp_wifi_get_mode(&mode);
|
|
||||||
if (WIFI_MODE_APSTA != mode) {
|
|
||||||
STA_duration = STA_POLLING_MIN;
|
|
||||||
network_manager_async_lost_connection(disconnected_event);
|
|
||||||
} else if (STA_duration < STA_POLLING_MAX) {
|
|
||||||
STA_duration *= 1.25;
|
|
||||||
free(disconnected_event);
|
|
||||||
}
|
|
||||||
/* keep polling for existing connection */
|
|
||||||
xTimerChangePeriod(STA_timer, pdMS_TO_TICKS(STA_duration), portMAX_DELAY);
|
|
||||||
xTimerStart(STA_timer, portMAX_DELAY);
|
|
||||||
ESP_LOGD(TAG, "STA search slow polling of %d", STA_duration);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.on_entry([=](const TTransition& t) {
|
|
||||||
wifi_manager_safe_reset_sta_ip_string();
|
|
||||||
})
|
|
||||||
.permit(trig_t::t_connect, state_t::wifi_connecting)
|
|
||||||
.permit(trig_t::t_lost_connection, state_t::wifi_ap_mode);
|
|
||||||
// Register a callback for state transitions (the default does nothing).
|
|
||||||
sm_.on_transition([](const TTransition& t) {
|
|
||||||
std::cout << "transition from [" << t.source() << "] to ["
|
|
||||||
<< t.destination() << "] via trigger [" << t.trigger() << "]"
|
|
||||||
<< std::endl;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Override the default behaviour of throwing when a trigger is unhandled.
|
|
||||||
sm_.on_unhandled_trigger([](const state_t s, const trig_t t) {
|
|
||||||
std::cerr << "ignore unhandled trigger [" << t << "] in state [" << s
|
|
||||||
<< "]" << std::endl;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool
|
|
||||||
Allowed(trig_t trigger) {
|
|
||||||
if (!sm_.can_fire(trigger)) {
|
|
||||||
ESP_LOGW(TAG, "Network manager might not be able to process trigger %s", trigger_to_string(trigger));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool Fire(trig_t trigger) {
|
|
||||||
try {
|
|
||||||
sm_.fire(trigger);
|
|
||||||
return true;
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
std::cerr << e.what() << '\n';
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool Event(queue_message& msg) {
|
|
||||||
trig_t trigger = msg.trigger;
|
|
||||||
try {
|
|
||||||
if (trigger == trig_t::t_connect) {
|
|
||||||
sm_.fire(connect_trigger_, msg.wifi_config);
|
|
||||||
} else if (trigger == trig_t::t_reboot) {
|
|
||||||
sm_.fire(reboot_trigger_, msg.rtype);
|
|
||||||
} else if (trigger == trig_t::t_reboot_url) {
|
|
||||||
sm_.fire(reboot_ota_, msg.strval);
|
|
||||||
} else if (trigger == trig_t::t_lost_connection) {
|
|
||||||
sm_.fire(disconnected_, msg.disconnected_event);
|
|
||||||
} else {
|
|
||||||
sm_.fire(trigger);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
std::cerr << e.what() << '\n';
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint8_t reconnect_attempt = 0;
|
|
||||||
bool existing_connection = false;
|
|
||||||
uint8_t retries = 0;
|
|
||||||
TStateMachine sm_;
|
|
||||||
TConnectTrigger connect_trigger_;
|
|
||||||
TRebootTrigger reboot_trigger_;
|
|
||||||
TRebootOTATrigger reboot_ota_;
|
|
||||||
TDisconnectTrigger disconnected_;
|
|
||||||
};
|
|
||||||
|
|
||||||
NetworkManager nm;
|
|
||||||
void network_manager_start() {
|
|
||||||
nm.Fire(trig_t::t_start);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool network_manager_async(trig_t trigger) {
|
|
||||||
queue_message msg;
|
|
||||||
msg.trigger = trigger;
|
|
||||||
if (nm.Allowed(trigger)) {
|
|
||||||
return xQueueSendToFront(network_manager_queue, &msg, portMAX_DELAY);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool network_manager_async_fail() {
|
|
||||||
return network_manager_async(trig_t::t_fail);
|
|
||||||
}
|
|
||||||
bool network_manager_async_success() {
|
|
||||||
return network_manager_async(trig_t::t_success);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool network_manager_async_link_up() {
|
|
||||||
return network_manager_async(trig_t::t_link_up);
|
|
||||||
}
|
|
||||||
bool network_manager_async_link_down() {
|
|
||||||
return network_manager_async(trig_t::t_link_down);
|
|
||||||
}
|
|
||||||
bool network_manager_async_configure() {
|
|
||||||
return network_manager_async(trig_t::t_configure);
|
|
||||||
}
|
|
||||||
bool network_manager_async_got_ip() {
|
|
||||||
return network_manager_async(trig_t::t_got_ip);
|
|
||||||
}
|
|
||||||
bool network_manager_async_next() {
|
|
||||||
return network_manager_async(trig_t::t_next);
|
|
||||||
}
|
|
||||||
bool network_manager_async_start() {
|
|
||||||
return network_manager_async(trig_t::t_start);
|
|
||||||
}
|
|
||||||
bool network_manager_async_scan() {
|
|
||||||
return network_manager_async(trig_t::t_scan);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool network_manager_async_update_status() {
|
|
||||||
return network_manager_async(trig_t::t_update_status);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool network_manager_async_disconnect() {
|
|
||||||
return network_manager_async(trig_t::t_disconnect);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool network_manager_async_scan_done() {
|
|
||||||
return network_manager_async(trig_t::t_scan_done);
|
|
||||||
}
|
|
||||||
bool network_manager_async_connect(wifi_config_t* wifi_config) {
|
|
||||||
queue_message msg;
|
|
||||||
msg.trigger = trig_t::t_connect;
|
|
||||||
msg.wifi_config = wifi_config;
|
|
||||||
if (nm.Allowed(msg.trigger)) {
|
|
||||||
return xQueueSendToFront(network_manager_queue, &msg, portMAX_DELAY);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool network_manager_async_lost_connection(wifi_event_sta_disconnected_t* disconnected_event) {
|
|
||||||
queue_message msg;
|
|
||||||
msg.trigger = trig_t::t_lost_connection;
|
|
||||||
msg.disconnected_event = disconnected_event;
|
|
||||||
if (nm.Allowed(msg.trigger)) {
|
|
||||||
return xQueueSendToFront(network_manager_queue, &msg, portMAX_DELAY);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool network_manager_async_reboot(reboot_type_t rtype) {
|
|
||||||
queue_message msg;
|
|
||||||
msg.trigger = trig_t::t_reboot;
|
|
||||||
msg.rtype = rtype;
|
|
||||||
if (nm.Allowed(msg.trigger)) {
|
|
||||||
return xQueueSendToFront(network_manager_queue, &msg, portMAX_DELAY);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void network_manager_reboot_ota(char* url) {
|
|
||||||
queue_message msg;
|
|
||||||
|
|
||||||
if (url == NULL) {
|
|
||||||
msg.trigger = trig_t::t_reboot;
|
|
||||||
msg.rtype = reboot_type_t::OTA;
|
|
||||||
} else {
|
|
||||||
msg.trigger = trig_t::t_reboot_url;
|
|
||||||
msg.strval = strdup(url);
|
|
||||||
}
|
|
||||||
if (nm.Allowed(msg.trigger)) {
|
|
||||||
xQueueSendToFront(network_manager_queue, &msg, portMAX_DELAY);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// switch (msg.code) {
|
|
||||||
// case EVENT_SCAN_DONE:
|
|
||||||
// err = wifi_scan_done(&msg);
|
|
||||||
// /* callback */
|
|
||||||
// if (cb_ptr_arr[msg.code]) {
|
|
||||||
// ESP_LOGD(TAG, "Invoking SCAN DONE callback");
|
|
||||||
// (*cb_ptr_arr[msg.code])(NULL);
|
|
||||||
// ESP_LOGD(TAG, "Done Invoking SCAN DONE callback");
|
|
||||||
// }
|
|
||||||
// break;
|
|
||||||
// case ORDER_START_WIFI_SCAN:
|
|
||||||
// err = network_wifi_start_scan(&msg);
|
|
||||||
// /* callback */
|
|
||||||
// if (cb_ptr_arr[msg.code])
|
|
||||||
// (*cb_ptr_arr[msg.code])(NULL);
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// case ORDER_LOAD_AND_RESTORE_STA:
|
|
||||||
// err = network_wifi_load_restore(&msg);
|
|
||||||
// /* callback */
|
|
||||||
// if (cb_ptr_arr[msg.code])
|
|
||||||
// (*cb_ptr_arr[msg.code])(NULL);
|
|
||||||
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// case ORDER_CONNECT_STA:
|
|
||||||
// err = network_wifi_order_connect(&msg);
|
|
||||||
// /* callback */
|
|
||||||
// if (cb_ptr_arr[msg.code])
|
|
||||||
// (*cb_ptr_arr[msg.code])(NULL);
|
|
||||||
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// case EVENT_STA_DISCONNECTED:
|
|
||||||
// err = network_wifi_disconnected(&msg);
|
|
||||||
// /* callback */
|
|
||||||
// if (cb_ptr_arr[msg.code])
|
|
||||||
// (*cb_ptr_arr[msg.code])(NULL);
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// case ORDER_START_AP:
|
|
||||||
// err = network_wifi_start_ap(&msg);
|
|
||||||
// /* callback */
|
|
||||||
// if (cb_ptr_arr[msg.code])
|
|
||||||
// (*cb_ptr_arr[msg.code])(NULL);
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// case EVENT_GOT_IP:
|
|
||||||
// ESP_LOGD(TAG, "MESSAGE: EVENT_GOT_IP");
|
|
||||||
// /* save IP as a string for the HTTP server host */
|
|
||||||
// //s->ip_info.ip.addr
|
|
||||||
// ip_event_got_ip_t* event = (ip_event_got_ip_t*)msg.param;
|
|
||||||
// wifi_manager_safe_update_sta_ip_string(&(event->ip_info.ip));
|
|
||||||
// wifi_manager_generate_ip_info_json(network_manager_is_flag_set(WIFI_MANAGER_REQUEST_STA_CONNECT_FAILED_BIT)? UPDATE_FAILED_ATTEMPT_AND_RESTORE : UPDATE_CONNECTION_OK, event->esp_netif, event->ip_changed);
|
|
||||||
// free(msg.param);
|
|
||||||
// /* callback */
|
|
||||||
// if (cb_ptr_arr[msg.code])
|
|
||||||
// (*cb_ptr_arr[msg.code])(NULL);
|
|
||||||
// break;
|
|
||||||
// case UPDATE_CONNECTION_OK:
|
|
||||||
// messaging_post_message(MESSAGING_ERROR, MESSAGING_CLASS_SYSTEM, "UPDATE_CONNECTION_OK not implemented");
|
|
||||||
// break;
|
|
||||||
// case ORDER_DISCONNECT_STA:
|
|
||||||
// ESP_LOGD(TAG, "MESSAGE: ORDER_DISCONNECT_STA. Calling esp_wifi_disconnect()");
|
|
||||||
|
|
||||||
// /* precise this is coming from a user request */
|
|
||||||
// xEventGroupSetBits(wifi_manager_event_group, WIFI_MANAGER_REQUEST_DISCONNECT_BIT);
|
|
||||||
|
|
||||||
// /* order wifi discconect */
|
|
||||||
// ESP_ERROR_CHECK(esp_wifi_disconnect());
|
|
||||||
|
|
||||||
// /* callback */
|
|
||||||
// if (cb_ptr_arr[msg.code])
|
|
||||||
// (*cb_ptr_arr[msg.code])(NULL);
|
|
||||||
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// case ORDER_RESTART_OTA_URL:
|
|
||||||
// ESP_LOGD(TAG, "Calling start_ota.");
|
|
||||||
// start_ota(msg.param, NULL, 0);
|
|
||||||
// free(msg.param);
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// case ORDER_RESTART_RECOVERY:
|
|
||||||
|
|
||||||
// break;
|
|
||||||
// case ORDER_RESTART:
|
|
||||||
// ESP_LOGD(TAG, "Calling simple_restart.");
|
|
||||||
// simple_restart();
|
|
||||||
// break;
|
|
||||||
// case ORDER_UPDATE_STATUS:
|
|
||||||
// ;
|
|
||||||
// break;
|
|
||||||
// case EVENT_ETH_TIMEOUT:
|
|
||||||
// ESP_LOGW(TAG, "Ethernet connection timeout. Rebooting with WiFi Active");
|
|
||||||
// network_manager_reboot(RESTART);
|
|
||||||
// break;
|
|
||||||
// case EVENT_ETH_LINK_UP:
|
|
||||||
// /* callback */
|
|
||||||
// ESP_LOGD(TAG,"EVENT_ETH_LINK_UP message received");
|
|
||||||
// if (cb_ptr_arr[msg.code])
|
|
||||||
// (*cb_ptr_arr[msg.code])(NULL);
|
|
||||||
// break;
|
|
||||||
// case EVENT_ETH_LINK_DOWN:
|
|
||||||
// /* callback */
|
|
||||||
// if (cb_ptr_arr[msg.code])
|
|
||||||
// (*cb_ptr_arr[msg.code])(NULL);
|
|
||||||
// break;
|
|
||||||
// default:
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// } /* end of switch/case */
|
|
||||||
|
|
||||||
// if (!network_ethernet_wait_for_link(500)) {
|
|
||||||
// if(network_ethernet_enabled()){
|
|
||||||
// ESP_LOGW(TAG, "Ethernet not connected. Starting Wifi");
|
|
||||||
// }
|
|
||||||
// init_network_wifi();
|
|
||||||
// wifi_manager_send_message(ORDER_LOAD_AND_RESTORE_STA, NULL);
|
|
||||||
// }
|
|
||||||
|
|
||||||
void network_manager(void* pvParameters) {
|
|
||||||
queue_message msg;
|
|
||||||
esp_err_t err = ESP_OK;
|
|
||||||
BaseType_t xStatus;
|
|
||||||
network_manager_async(trig_t::t_start);
|
|
||||||
|
|
||||||
/* main processing loop */
|
|
||||||
for (;;) {
|
|
||||||
xStatus = xQueueReceive(network_manager_queue, &msg, portMAX_DELAY);
|
|
||||||
|
|
||||||
if (xStatus == pdPASS) {
|
|
||||||
// pass the event to the sync processor
|
|
||||||
nm.Event(msg);
|
|
||||||
} /* end of if status=pdPASS */
|
|
||||||
} /* end of for loop */
|
|
||||||
|
|
||||||
vTaskDelete(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void network_manager_destroy() {
|
|
||||||
vTaskDelete(task_network_manager);
|
|
||||||
task_network_manager = NULL;
|
|
||||||
/* heap buffers */
|
|
||||||
destroy_network_status();
|
|
||||||
destroy_network_wifi();
|
|
||||||
destroy_network_status();
|
|
||||||
/* RTOS objects */
|
|
||||||
vQueueDelete(network_manager_queue);
|
|
||||||
network_manager_queue = NULL;
|
|
||||||
}
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "esp_wifi.h"
|
|
||||||
#include "esp_wifi_types.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define STA_POLLING_MIN (15 * 1000)
|
|
||||||
#define STA_POLLING_MAX (10 * 60 * 1000)
|
|
||||||
|
|
||||||
//enum class state { idle, stopped, started, running };
|
|
||||||
|
|
||||||
//enum class trigger { start, stop, set_speed, halt };
|
|
||||||
typedef enum {
|
|
||||||
t_link_up,
|
|
||||||
t_link_down,
|
|
||||||
t_configure,
|
|
||||||
t_got_ip,
|
|
||||||
t_disconnect,
|
|
||||||
t_next,
|
|
||||||
t_start,
|
|
||||||
t_scan,
|
|
||||||
t_fail,
|
|
||||||
t_success,
|
|
||||||
t_scan_done,
|
|
||||||
t_connect,
|
|
||||||
t_reboot,
|
|
||||||
t_reboot_url,
|
|
||||||
t_lost_connection,
|
|
||||||
t_update_status
|
|
||||||
} trig_t;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
instantiated,
|
|
||||||
initializing,
|
|
||||||
global,
|
|
||||||
eth_starting,
|
|
||||||
eth_active,
|
|
||||||
eth_active_linkup,
|
|
||||||
eth_active_connected,
|
|
||||||
eth_active_linkdown,
|
|
||||||
wifi_up,
|
|
||||||
wifi_initializing,
|
|
||||||
wifi_connecting_scanning,
|
|
||||||
wifi_connecting,
|
|
||||||
wifi_connected,
|
|
||||||
wifi_disconnecting,
|
|
||||||
wifi_user_disconnected,
|
|
||||||
wifi_connected_waiting_for_ip,
|
|
||||||
wifi_connected_scanning,
|
|
||||||
wifi_lost_connection,
|
|
||||||
wifi_ap_mode,
|
|
||||||
wifi_ap_mode_scanning,
|
|
||||||
wifi_ap_mode_scan_done,
|
|
||||||
wifi_ap_mode_connecting,
|
|
||||||
wifi_ap_mode_connected,
|
|
||||||
system_rebooting
|
|
||||||
} state_t;
|
|
||||||
typedef enum {
|
|
||||||
OTA,
|
|
||||||
RECOVERY,
|
|
||||||
RESTART,
|
|
||||||
} reboot_type_t;
|
|
||||||
typedef struct {
|
|
||||||
trig_t trigger;
|
|
||||||
union
|
|
||||||
{
|
|
||||||
wifi_config_t* wifi_config;
|
|
||||||
reboot_type_t rtype;
|
|
||||||
char * strval;
|
|
||||||
wifi_event_sta_disconnected_t * disconnected_event;
|
|
||||||
} ;
|
|
||||||
|
|
||||||
|
|
||||||
} queue_message;
|
|
||||||
|
|
||||||
bool network_manager_event_simple(trig_t trigger);
|
|
||||||
bool network_manager_event(trig_t trigger, void* param);
|
|
||||||
bool network_t_connect_event(wifi_config_t* wifi_config);
|
|
||||||
bool network_t_link_event(bool link_up);
|
|
||||||
bool network_manager_async_event(trig_t trigger, void* param);
|
|
||||||
bool network_manager_async(trig_t trigger);
|
|
||||||
bool network_manager_async_fail();
|
|
||||||
bool network_manager_async_success();
|
|
||||||
bool network_manager_async_link_up();
|
|
||||||
bool network_manager_async_link_down();
|
|
||||||
bool network_manager_async_configure();
|
|
||||||
bool network_manager_async_got_ip();
|
|
||||||
bool network_manager_async_next();
|
|
||||||
bool network_manager_async_start();
|
|
||||||
bool network_manager_async_scan();
|
|
||||||
bool network_manager_async_scan_done();
|
|
||||||
bool network_manager_async_connect(wifi_config_t* wifi_config);
|
|
||||||
bool network_manager_async_lost_connection(wifi_event_sta_disconnected_t * disconnected_event);
|
|
||||||
bool network_manager_async_reboot(reboot_type_t rtype);
|
|
||||||
void network_manager_reboot_ota(char* url);
|
|
||||||
bool network_manager_async_disconnect();
|
|
||||||
bool network_manager_async_update_status();
|
|
||||||
/**
|
|
||||||
* Allocate heap memory for the wifi manager and start the wifi_manager RTOS task
|
|
||||||
*/
|
|
||||||
void network_manager_start();
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
[
|
[
|
||||||
{"ssid":"Pantum-AP-A6D49F","chan":11,"rssi":-55,"auth":4},
|
{"ssid":"Pantum-AP-A6D49F","chan":11,"rssi":-55,"auth":4, "known":false},
|
||||||
{"ssid":"a0308","chan":1,"rssi":-56,"auth":3},
|
{"ssid":"a0308","chan":1,"rssi":-56,"auth":3, "known":false},
|
||||||
{"ssid":"dlink-D9D8","chan":11,"rssi":-82,"auth":4},
|
{"ssid":"dlink-D9D8","chan":11,"rssi":-82,"auth":4, "known":false},
|
||||||
{"ssid":"Linksys06730","chan":7,"rssi":-85,"auth":3},
|
{"ssid":"Linksys06730","chan":7,"rssi":-85,"auth":3, "known":false},
|
||||||
{"ssid":"SINGTEL-5171","chan":9,"rssi":-88,"auth":4},
|
{"ssid":"SINGTEL-5171","chan":9,"rssi":-88,"auth":4, "known":false},
|
||||||
{"ssid":"1126-1","chan":11,"rssi":-89,"auth":4},
|
{"ssid":"1126-1","chan":11,"rssi":-89,"auth":4, "known":false},
|
||||||
{"ssid":"The Shah 5GHz-2","chan":1,"rssi":-90,"auth":3},
|
{"ssid":"The Shah 5GHz-2","chan":1,"rssi":-90,"auth":3, "known":false},
|
||||||
{"ssid":"SINGTEL-1D28 (2G)","chan":11,"rssi":-91,"auth":3},
|
{"ssid":"SINGTEL-1D28 (2G)","chan":11,"rssi":-91,"auth":3, "known":false},
|
||||||
{"ssid":"dlink-F864","chan":1,"rssi":-92,"auth":4},
|
{"ssid":"dlink-F864","chan":1,"rssi":-92,"auth":4, "known":false},
|
||||||
{"ssid":"dlink-74F0","chan":1,"rssi":-93,"auth":4},
|
{"ssid":"dlink-74F0","chan":1,"rssi":-93,"auth":4, "known":false},
|
||||||
{"ssid":"MyTestSSID","chan":2,"rssi":-53,"auth":4}
|
{"ssid":"MyTestSSID","chan":2,"rssi":-53,"auth":4, "known":true}
|
||||||
]
|
]
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
"current_time": 147319
|
"current_time": 147319
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"message": "Wifi connected",
|
"message": "Network connected",
|
||||||
"type": "MESSAGING_INFO",
|
"type": "MESSAGING_INFO",
|
||||||
"class": "MESSAGING_CLASS_SYSTEM",
|
"class": "MESSAGING_CLASS_SYSTEM",
|
||||||
"sent_time": 141256,
|
"sent_time": 141256,
|
||||||
|
|||||||
@@ -1098,7 +1098,7 @@ function rssiToIcon(rssi) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function refreshAP() {
|
function refreshAP() {
|
||||||
$.getJSON('/scan.json', async function() {
|
$.getJSON('/scan.json', async function() {
|
||||||
await sleep(2000);
|
await sleep(2000);
|
||||||
$.getJSON('/ap.json', function(data) {
|
$.getJSON('/ap.json', function(data) {
|
||||||
if (data.length > 0) {
|
if (data.length > 0) {
|
||||||
@@ -1335,6 +1335,7 @@ function handleRecoveryMode(data) {
|
|||||||
$('#boot-form').attr('action', '/recovery.json');
|
$('#boot-form').attr('action', '/recovery.json');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasConnectionChanged(data){
|
function hasConnectionChanged(data){
|
||||||
// gw: "192.168.10.1"
|
// gw: "192.168.10.1"
|
||||||
// ip: "192.168.10.225"
|
// ip: "192.168.10.225"
|
||||||
@@ -1366,10 +1367,10 @@ function handleWifiDialog(data){
|
|||||||
$('.connecting-status').show();
|
$('.connecting-status').show();
|
||||||
}
|
}
|
||||||
if(SystemConfig.ap_ssid){
|
if(SystemConfig.ap_ssid){
|
||||||
$('#apName').text(SystemConfig.ap_ssid);
|
$('#apName').text(SystemConfig.ap_ssid.value);
|
||||||
}
|
}
|
||||||
if(SystemConfig.ap_pwd){
|
if(SystemConfig.ap_pwd){
|
||||||
$('#apPass').text(SystemConfig.ap_pwd);
|
$('#apPass').text(SystemConfig.ap_pwd.value);
|
||||||
}
|
}
|
||||||
if(!data)
|
if(!data)
|
||||||
{
|
{
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 605 B |
Binary file not shown.
|
Before Width: | Height: | Size: 613 B |
Binary file not shown.
|
Before Width: | Height: | Size: 615 B |
Binary file not shown.
|
Before Width: | Height: | Size: 605 B |
Binary file not shown.
|
Before Width: | Height: | Size: 656 B |
@@ -31,11 +31,13 @@
|
|||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "messaging.h"
|
#include "messaging.h"
|
||||||
#include "platform_esp32.h"
|
#include "platform_esp32.h"
|
||||||
|
#include "globdefs.h"
|
||||||
|
#include "trace.h"
|
||||||
static const char TAG[] = "http_server";
|
static const char TAG[] = "http_server";
|
||||||
|
|
||||||
static httpd_handle_t _server = NULL;
|
EXT_RAM_ATTR static httpd_handle_t _server = NULL;
|
||||||
rest_server_context_t *rest_context = NULL;
|
EXT_RAM_ATTR rest_server_context_t *rest_context = NULL;
|
||||||
RingbufHandle_t messaging=NULL;
|
EXT_RAM_ATTR RingbufHandle_t messaging=NULL;
|
||||||
|
|
||||||
void register_common_handlers(httpd_handle_t server){
|
void register_common_handlers(httpd_handle_t server){
|
||||||
httpd_uri_t css_get = { .uri = "/css/*", .method = HTTP_GET, .handler = resource_filehandler, .user_ctx = rest_context };
|
httpd_uri_t css_get = { .uri = "/css/*", .method = HTTP_GET, .handler = resource_filehandler, .user_ctx = rest_context };
|
||||||
@@ -46,7 +48,6 @@ void register_common_handlers(httpd_handle_t server){
|
|||||||
httpd_register_uri_handler(server, &icon_get);
|
httpd_register_uri_handler(server, &icon_get);
|
||||||
httpd_uri_t png_get = { .uri = "/favicon*", .method = HTTP_GET, .handler = resource_filehandler, .user_ctx = rest_context };
|
httpd_uri_t png_get = { .uri = "/favicon*", .method = HTTP_GET, .handler = resource_filehandler, .user_ctx = rest_context };
|
||||||
httpd_register_uri_handler(server, &png_get);
|
httpd_register_uri_handler(server, &png_get);
|
||||||
|
|
||||||
}
|
}
|
||||||
void register_regular_handlers(httpd_handle_t server){
|
void register_regular_handlers(httpd_handle_t server){
|
||||||
httpd_uri_t root_get = { .uri = "/", .method = HTTP_GET, .handler = root_get_handler, .user_ctx = rest_context };
|
httpd_uri_t root_get = { .uri = "/", .method = HTTP_GET, .handler = root_get_handler, .user_ctx = rest_context };
|
||||||
@@ -124,13 +125,17 @@ void register_regular_handlers(httpd_handle_t server){
|
|||||||
|
|
||||||
esp_err_t http_server_start()
|
esp_err_t http_server_start()
|
||||||
{
|
{
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Initializing HTTP Server");
|
ESP_LOGI(TAG, "Initializing HTTP Server");
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("Registering messaging subscriber");
|
||||||
messaging = messaging_register_subscriber(10, "http_server");
|
messaging = messaging_register_subscriber(10, "http_server");
|
||||||
rest_context = calloc(1, sizeof(rest_server_context_t));
|
MEMTRACE_PRINT_DELTA_MESSAGE("Allocating RAM for server context");
|
||||||
|
rest_context = malloc_init_external( sizeof(rest_server_context_t));
|
||||||
if(rest_context==NULL){
|
if(rest_context==NULL){
|
||||||
ESP_LOGE(TAG,"No memory for http context");
|
ESP_LOGE(TAG,"No memory for http context");
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
strlcpy(rest_context->base_path, "/res/", sizeof(rest_context->base_path));
|
strlcpy(rest_context->base_path, "/res/", sizeof(rest_context->base_path));
|
||||||
|
|
||||||
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
||||||
@@ -141,15 +146,17 @@ esp_err_t http_server_start()
|
|||||||
//todo: use the endpoint below to configure session token?
|
//todo: use the endpoint below to configure session token?
|
||||||
// config.open_fn
|
// config.open_fn
|
||||||
|
|
||||||
ESP_LOGD(TAG, "Starting HTTP Server");
|
MEMTRACE_PRINT_DELTA_MESSAGE( "Starting HTTP Server");
|
||||||
esp_err_t err= __httpd_start(&_server, &config);
|
esp_err_t err= __httpd_start(&_server, &config);
|
||||||
if(err != ESP_OK){
|
if(err != ESP_OK){
|
||||||
ESP_LOGE_LOC(TAG,"Start server failed");
|
ESP_LOGE_LOC(TAG,"Start server failed");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE( "HTTP Server started. Registering common handlers");
|
||||||
register_common_handlers(_server);
|
register_common_handlers(_server);
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("Registering regular handlers");
|
||||||
register_regular_handlers(_server);
|
register_regular_handlers(_server);
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("HTTP Server regular handlers registered");
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
menu "Squeezelite-ESP32"
|
menu "Squeezelite-ESP32"
|
||||||
menu "Logging"
|
menu "Logging"
|
||||||
config LOGGING_SLIMPROTO
|
config LOGGING_SLIMPROTO
|
||||||
string "logging level for slimproto"
|
string "logging level for slimproto"
|
||||||
default "info"
|
default "info"
|
||||||
help
|
help
|
||||||
Set logging level info|debug|sdebug
|
Set logging level info|debug|sdebug
|
||||||
config LOGGING_STREAM
|
config LOGGING_STREAM
|
||||||
string "logging level for stream"
|
string "logging level for stream"
|
||||||
default "info"
|
default "info"
|
||||||
help
|
help
|
||||||
Set logging level info|debug|sdebug
|
Set logging level info|debug|sdebug
|
||||||
config LOGGING_DECODE
|
config LOGGING_DECODE
|
||||||
string "logging level for decode"
|
string "logging level for decode"
|
||||||
default "info"
|
default "info"
|
||||||
help
|
help
|
||||||
Set logging level info|debug|sdebug
|
Set logging level info|debug|sdebug
|
||||||
config LOGGING_OUTPUT
|
config LOGGING_OUTPUT
|
||||||
string "logging level for output"
|
string "logging level for output"
|
||||||
default "info"
|
default "info"
|
||||||
@@ -102,11 +102,22 @@ menu "Squeezelite-ESP32"
|
|||||||
config DAC_CONTROLSET
|
config DAC_CONTROLSET
|
||||||
string
|
string
|
||||||
default '{ "init": [ {"reg":41, "val":128}, {"reg":18, "val":255} ], "poweron": [ {"reg":18, "val":64, "mode":"or"} ], "poweroff": [ {"reg":18, "val":191, "mode":"and" } ] }' if TWATCH2020
|
default '{ "init": [ {"reg":41, "val":128}, {"reg":18, "val":255} ], "poweron": [ {"reg":18, "val":64, "mode":"or"} ], "poweroff": [ {"reg":18, "val":191, "mode":"and" } ] }' if TWATCH2020
|
||||||
default ""
|
default ""
|
||||||
# AGGREGATES - end
|
# AGGREGATES - end
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
menu "Audio settings"
|
menu "Audio settings"
|
||||||
|
menu "Known Configurations"
|
||||||
|
visible if BASIC_I2C_BT
|
||||||
|
config DAC_KNOWN_CONFIGURATIONS
|
||||||
|
string "Known DAC configurations"
|
||||||
|
default "ESP32A1S Old (AC101)|ESP32A1S V2.2+ (ES8388)|Xiaomi Gateway" if BASIC_I2C_BT
|
||||||
|
default ""
|
||||||
|
config DAC_KNOWN_CONFIGURATIONS_GPIOS
|
||||||
|
string "GPIOs for known DAC configurations"
|
||||||
|
default "model=AC101,sda=33,scl=32,bck=27,ws=26,di=35,do=25|model=ES8388,bck=5,ws=25,do=26,sda=18,scl=23,i2c=16|model=I2S,bck=12,ws=26,do=25,i2c=106,sda=18,scl=23" if BASIC_I2C_BT
|
||||||
|
default ""
|
||||||
|
endmenu
|
||||||
menu "DAC settings"
|
menu "DAC settings"
|
||||||
visible if BASIC_I2C_BT
|
visible if BASIC_I2C_BT
|
||||||
menu "I2S settings"
|
menu "I2S settings"
|
||||||
@@ -198,7 +209,8 @@ menu "Squeezelite-ESP32"
|
|||||||
int "Control loop delay."
|
int "Control loop delay."
|
||||||
default 500
|
default 500
|
||||||
help
|
help
|
||||||
Decreasing this will lead to a more responsive BT control, but might lead to noisy log files if debug is enabled.
|
Decreasing this will lead to a more responsive BT control,
|
||||||
|
but might lead to noisy log files if debug is enabled.
|
||||||
config A2DP_CONNECT_TIMEOUT_MS
|
config A2DP_CONNECT_TIMEOUT_MS
|
||||||
int "Time out duration when trying to connect to an A2DP audio sink"
|
int "Time out duration when trying to connect to an A2DP audio sink"
|
||||||
default 1000
|
default 1000
|
||||||
@@ -351,5 +363,5 @@ menu "Squeezelite-ESP32"
|
|||||||
string "Default command line to execute"
|
string "Default command line to execute"
|
||||||
default "squeezelite -o I2S -b 500:2000 -d all=info -C 30"
|
default "squeezelite -o I2S -b 500:2000 -d all=info -C 30"
|
||||||
help
|
help
|
||||||
This is the command to run when starting the device
|
This is the command to run when starting the device
|
||||||
endmenu
|
endmenu
|
||||||
@@ -45,14 +45,16 @@
|
|||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "accessors.h"
|
#include "accessors.h"
|
||||||
#include "cmd_system.h"
|
#include "cmd_system.h"
|
||||||
|
#include "globdefs.h"
|
||||||
|
|
||||||
static const char certs_namespace[] = "certificates";
|
static const char certs_namespace[] = "certificates";
|
||||||
static const char certs_key[] = "blob";
|
static const char certs_key[] = "blob";
|
||||||
static const char certs_version[] = "version";
|
static const char certs_version[] = "version";
|
||||||
const char unknown_string_placeholder[] = "unknown";
|
const char unknown_string_placeholder[] = "unknown";
|
||||||
const char null_string_placeholder[] = "null";
|
const char null_string_placeholder[] = "null";
|
||||||
EventGroupHandle_t wifi_event_group;
|
EventGroupHandle_t network_event_group;
|
||||||
|
|
||||||
bool bypass_wifi_manager=false;
|
bool bypass_network_manager=false;
|
||||||
const int CONNECTED_BIT = BIT0;
|
const int CONNECTED_BIT = BIT0;
|
||||||
#define JOIN_TIMEOUT_MS (10000)
|
#define JOIN_TIMEOUT_MS (10000)
|
||||||
#define LOCAL_MAC_SIZE 20
|
#define LOCAL_MAC_SIZE 20
|
||||||
@@ -61,7 +63,7 @@ static const char TAG[] = "esp_app_main";
|
|||||||
char * fwurl = NULL;
|
char * fwurl = NULL;
|
||||||
RTC_NOINIT_ATTR uint32_t RebootCounter ;
|
RTC_NOINIT_ATTR uint32_t RebootCounter ;
|
||||||
|
|
||||||
static bool bWifiConnected=false;
|
static bool bNetworkConnected=false;
|
||||||
extern const uint8_t server_cert_pem_start[] asm("_binary_github_pem_start");
|
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");
|
extern const uint8_t server_cert_pem_end[] asm("_binary_github_pem_end");
|
||||||
|
|
||||||
@@ -71,12 +73,11 @@ extern void display_init(char *welcome);
|
|||||||
const char * str_or_unknown(const char * str) { return (str?str:unknown_string_placeholder); }
|
const char * str_or_unknown(const char * str) { return (str?str:unknown_string_placeholder); }
|
||||||
const char * str_or_null(const char * str) { return (str?str:null_string_placeholder); }
|
const char * str_or_null(const char * str) { return (str?str:null_string_placeholder); }
|
||||||
bool is_recovery_running;
|
bool is_recovery_running;
|
||||||
/* brief this is an exemple of a callback that you can setup in your own app to get notified of wifi manager event */
|
|
||||||
void cb_connection_got_ip(void *pvParameter){
|
void cb_connection_got_ip(nm_state_t new_state, int sub_state){
|
||||||
static ip4_addr_t ip;
|
static ip4_addr_t ip;
|
||||||
tcpip_adapter_ip_info_t ipInfo;
|
tcpip_adapter_ip_info_t ipInfo;
|
||||||
|
network_get_ip_info(&ipInfo);
|
||||||
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ipInfo);
|
|
||||||
if (ip.addr && ipInfo.ip.addr != ip.addr) {
|
if (ip.addr && ipInfo.ip.addr != ip.addr) {
|
||||||
ESP_LOGW(TAG, "IP change, need to reboot");
|
ESP_LOGW(TAG, "IP change, need to reboot");
|
||||||
if(!wait_for_commit()){
|
if(!wait_for_commit()){
|
||||||
@@ -85,10 +86,10 @@ void cb_connection_got_ip(void *pvParameter){
|
|||||||
esp_restart();
|
esp_restart();
|
||||||
}
|
}
|
||||||
ip.addr = ipInfo.ip.addr;
|
ip.addr = ipInfo.ip.addr;
|
||||||
ESP_LOGI(TAG, "Wifi connected!");
|
ESP_LOGI(TAG, "Network connected!");
|
||||||
messaging_post_message(MESSAGING_INFO,MESSAGING_CLASS_SYSTEM,"Wifi connected");
|
messaging_post_message(MESSAGING_INFO,MESSAGING_CLASS_SYSTEM,"Network connected");
|
||||||
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
|
xEventGroupSetBits(network_event_group, CONNECTED_BIT);
|
||||||
bWifiConnected=true;
|
bNetworkConnected=true;
|
||||||
led_unpush(LED_GREEN);
|
led_unpush(LED_GREEN);
|
||||||
if(is_recovery_running){
|
if(is_recovery_running){
|
||||||
// when running in recovery, send a LMS discovery message
|
// when running in recovery, send a LMS discovery message
|
||||||
@@ -98,24 +99,24 @@ void cb_connection_got_ip(void *pvParameter){
|
|||||||
discover_ota_server(5);
|
discover_ota_server(5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void cb_connection_sta_disconnected(void *pvParameter){
|
void cb_connection_sta_disconnected(nm_state_t new_state, int sub_state){
|
||||||
led_blink_pushed(LED_GREEN, 250, 250);
|
led_blink_pushed(LED_GREEN, 250, 250);
|
||||||
messaging_post_message(MESSAGING_WARNING,MESSAGING_CLASS_SYSTEM,"Wifi disconnected");
|
messaging_post_message(MESSAGING_WARNING,MESSAGING_CLASS_SYSTEM,"Wifi disconnected");
|
||||||
bWifiConnected=false;
|
bNetworkConnected=false;
|
||||||
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
|
xEventGroupClearBits(network_event_group, CONNECTED_BIT);
|
||||||
}
|
}
|
||||||
bool wait_for_wifi(){
|
bool wait_for_wifi(){
|
||||||
bool connected=(xEventGroupGetBits(wifi_event_group) & CONNECTED_BIT)!=0;
|
bool connected=(xEventGroupGetBits(network_event_group) & CONNECTED_BIT)!=0;
|
||||||
if(!connected){
|
if(!connected){
|
||||||
ESP_LOGD(TAG,"Waiting for WiFi...");
|
ESP_LOGD(TAG,"Waiting for Network...");
|
||||||
connected = (xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
|
connected = (xEventGroupWaitBits(network_event_group, CONNECTED_BIT,
|
||||||
pdFALSE, pdTRUE, JOIN_TIMEOUT_MS / portTICK_PERIOD_MS)& CONNECTED_BIT)!=0;
|
pdFALSE, pdTRUE, JOIN_TIMEOUT_MS / portTICK_PERIOD_MS)& CONNECTED_BIT)!=0;
|
||||||
if(!connected){
|
if(!connected){
|
||||||
ESP_LOGW(TAG,"wifi timeout.");
|
ESP_LOGW(TAG,"Network timeout.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG,"WiFi Connected!");
|
ESP_LOGI(TAG,"Network Connected!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return connected;
|
return connected;
|
||||||
@@ -170,9 +171,8 @@ esp_err_t update_certificates(bool force){
|
|||||||
char *str=NULL;
|
char *str=NULL;
|
||||||
bool changed=false;
|
bool changed=false;
|
||||||
if ( (esp_err= nvs_get_str(handle, certs_version, NULL, &len)) == ESP_OK) {
|
if ( (esp_err= nvs_get_str(handle, certs_version, NULL, &len)) == ESP_OK) {
|
||||||
str=(char *)malloc(len+1);
|
str=(char *)malloc_init_external(len+1);
|
||||||
if(str){
|
if(str){
|
||||||
memset(str,0x00,len+1);
|
|
||||||
if ( (esp_err = nvs_get_str(handle, certs_version, str, &len)) == ESP_OK) {
|
if ( (esp_err = nvs_get_str(handle, certs_version, str, &len)) == ESP_OK) {
|
||||||
ESP_LOGI(TAG,"Certificate version: %s", str);
|
ESP_LOGI(TAG,"Certificate version: %s", str);
|
||||||
}
|
}
|
||||||
@@ -230,7 +230,8 @@ const char * get_certificate(){
|
|||||||
size_t len;
|
size_t len;
|
||||||
esp_err = nvs_get_blob(handle, certs_key, NULL, &len);
|
esp_err = nvs_get_blob(handle, certs_key, NULL, &len);
|
||||||
if( esp_err == ESP_OK) {
|
if( esp_err == ESP_OK) {
|
||||||
blob = (char *) heap_caps_malloc(len+1, (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT));
|
//blob = (char *) heap_caps_malloc(len+1, (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT));
|
||||||
|
blob = (char *) malloc_init_external(len+1);
|
||||||
if(!blob){
|
if(!blob){
|
||||||
log_send_messaging(MESSAGING_ERROR,"Unable to retrieve HTTPS certificates. %s","Memory allocation failed");
|
log_send_messaging(MESSAGING_ERROR,"Unable to retrieve HTTPS certificates. %s","Memory allocation failed");
|
||||||
return "";
|
return "";
|
||||||
@@ -275,7 +276,7 @@ void register_default_with_mac(const char* key, char* defval) {
|
|||||||
char* fullvalue = NULL;
|
char* fullvalue = NULL;
|
||||||
esp_read_mac((uint8_t*)&mac, ESP_MAC_WIFI_STA);
|
esp_read_mac((uint8_t*)&mac, ESP_MAC_WIFI_STA);
|
||||||
snprintf(macStr, LOCAL_MAC_SIZE - 1, "-%x%x%x", mac[3], mac[4], mac[5]);
|
snprintf(macStr, LOCAL_MAC_SIZE - 1, "-%x%x%x", mac[3], mac[4], mac[5]);
|
||||||
fullvalue = malloc(strlen(defval)+sizeof(macStr)+1);
|
fullvalue = malloc_init_external(strlen(defval)+sizeof(macStr)+1);
|
||||||
if(fullvalue){
|
if(fullvalue){
|
||||||
strcpy(fullvalue, defval);
|
strcpy(fullvalue, defval);
|
||||||
strcat(fullvalue, macStr);
|
strcat(fullvalue, macStr);
|
||||||
@@ -287,6 +288,13 @@ void register_default_with_mac(const char* key, char* defval) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#ifndef CONFIG_DAC_KNOWN_CONFIGURATIONS
|
||||||
|
#define CONFIG_DAC_KNOWN_CONFIGURATIONS ""
|
||||||
|
#endif
|
||||||
|
#ifndef CONFIG_DAC_KNOWN_CONFIGURATIONS_GPIOS
|
||||||
|
#define CONFIG_DAC_KNOWN_CONFIGURATIONS_GPIOS ""
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void register_default_nvs(){
|
void register_default_nvs(){
|
||||||
|
|
||||||
@@ -341,24 +349,35 @@ void register_default_nvs(){
|
|||||||
register_default_string_val( "stats", "n");
|
register_default_string_val( "stats", "n");
|
||||||
register_default_string_val( "rel_api", CONFIG_RELEASE_API);
|
register_default_string_val( "rel_api", CONFIG_RELEASE_API);
|
||||||
register_default_string_val("wifi_smode", "A");
|
register_default_string_val("wifi_smode", "A");
|
||||||
|
register_default_string_val("kndac", CONFIG_DAC_KNOWN_CONFIGURATIONS);
|
||||||
|
register_default_string_val("kngpio", CONFIG_DAC_KNOWN_CONFIGURATIONS_GPIOS);
|
||||||
wait_for_commit();
|
wait_for_commit();
|
||||||
ESP_LOGD(TAG,"Done setting default values in nvs.");
|
ESP_LOGD(TAG,"Done setting default values in nvs.");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t halSTORAGE_RebootCounterRead(void) { return RebootCounter ; }
|
uint32_t halSTORAGE_RebootCounterRead(void) { return RebootCounter ; }
|
||||||
uint32_t halSTORAGE_RebootCounterUpdate(int32_t xValue) { return (RebootCounter = (xValue != 0) ? (RebootCounter + xValue) : 0) ; }
|
uint32_t halSTORAGE_RebootCounterUpdate(int32_t xValue) {
|
||||||
|
if(RebootCounter >100) {
|
||||||
|
RebootCounter = 0;
|
||||||
|
}
|
||||||
|
return (RebootCounter = (xValue != 0) ? (RebootCounter + xValue) : 0) ;
|
||||||
|
}
|
||||||
|
|
||||||
void handle_ap_connect(){
|
void handle_ap_connect(nm_state_t new_state, int sub_state){
|
||||||
start_telnet(NULL);
|
start_telnet(NULL);
|
||||||
|
}
|
||||||
|
void handle_network_up(nm_state_t new_state, int sub_state){
|
||||||
halSTORAGE_RebootCounterUpdate(0);
|
halSTORAGE_RebootCounterUpdate(0);
|
||||||
}
|
}
|
||||||
|
esp_reset_reason_t xReason=ESP_RST_UNKNOWN;
|
||||||
|
|
||||||
void app_main()
|
void app_main()
|
||||||
{
|
{
|
||||||
const esp_partition_t *running = esp_ota_get_running_partition();
|
const esp_partition_t *running = esp_ota_get_running_partition();
|
||||||
is_recovery_running = (running->subtype == ESP_PARTITION_SUBTYPE_APP_FACTORY);
|
is_recovery_running = (running->subtype == ESP_PARTITION_SUBTYPE_APP_FACTORY);
|
||||||
esp_reset_reason_t xReason = esp_reset_reason();
|
xReason = esp_reset_reason();
|
||||||
ESP_LOGI(TAG,"Reset reason is: %u", xReason);
|
ESP_LOGI(TAG,"Reset reason is: %u", xReason);
|
||||||
if(!is_recovery_running && xReason != ESP_RST_SW && xReason != ESP_RST_POWERON ) {
|
if(!is_recovery_running ) {
|
||||||
/* unscheduled restart (HW, Watchdog or similar) thus increment dynamic
|
/* unscheduled restart (HW, Watchdog or similar) thus increment dynamic
|
||||||
* counter then log current boot statistics as a warning */
|
* counter then log current boot statistics as a warning */
|
||||||
uint32_t Counter = halSTORAGE_RebootCounterUpdate(1) ; // increment counter
|
uint32_t Counter = halSTORAGE_RebootCounterUpdate(1) ; // increment counter
|
||||||
@@ -369,30 +388,44 @@ void app_main()
|
|||||||
guided_factory();
|
guided_factory();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
uint32_t Counter = halSTORAGE_RebootCounterUpdate(1) ; // increment counter
|
||||||
|
ESP_LOGI(TAG,"Recovery Reboot counter=%u\n", Counter) ;
|
||||||
|
if (Counter == 5) {
|
||||||
|
ESP_LOGW(TAG,"System rebooted too many times. This could be an indication that configuration is corrupted. Erasing config.");
|
||||||
|
halSTORAGE_RebootCounterUpdate(0);
|
||||||
|
erase_settings_partition();
|
||||||
|
// reboot one more time
|
||||||
|
guided_factory();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
char * fwurl = NULL;
|
char * fwurl = NULL;
|
||||||
|
MEMTRACE_PRINT_DELTA();
|
||||||
ESP_LOGI(TAG,"Starting app_main");
|
ESP_LOGI(TAG,"Starting app_main");
|
||||||
initialize_nvs();
|
initialize_nvs();
|
||||||
|
MEMTRACE_PRINT_DELTA();
|
||||||
ESP_LOGI(TAG,"Setting up telnet.");
|
ESP_LOGI(TAG,"Setting up telnet.");
|
||||||
init_telnet(); // align on 32 bits boundaries
|
init_telnet(); // align on 32 bits boundaries
|
||||||
|
MEMTRACE_PRINT_DELTA();
|
||||||
ESP_LOGI(TAG,"Setting up config subsystem.");
|
ESP_LOGI(TAG,"Setting up config subsystem.");
|
||||||
config_init();
|
config_init();
|
||||||
|
MEMTRACE_PRINT_DELTA();
|
||||||
ESP_LOGD(TAG,"Creating event group for wifi");
|
ESP_LOGD(TAG,"Creating event group for wifi");
|
||||||
wifi_event_group = xEventGroupCreate();
|
network_event_group = xEventGroupCreate();
|
||||||
ESP_LOGD(TAG,"Clearing CONNECTED_BIT from wifi group");
|
ESP_LOGD(TAG,"Clearing CONNECTED_BIT from wifi group");
|
||||||
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
|
xEventGroupClearBits(network_event_group, CONNECTED_BIT);
|
||||||
|
|
||||||
ESP_LOGI(TAG,"Registering default values");
|
ESP_LOGI(TAG,"Registering default values");
|
||||||
register_default_nvs();
|
register_default_nvs();
|
||||||
|
MEMTRACE_PRINT_DELTA();
|
||||||
ESP_LOGI(TAG,"Configuring services");
|
ESP_LOGI(TAG,"Configuring services");
|
||||||
services_init();
|
services_init();
|
||||||
|
MEMTRACE_PRINT_DELTA();
|
||||||
ESP_LOGI(TAG,"Initializing display");
|
ESP_LOGI(TAG,"Initializing display");
|
||||||
display_init("SqueezeESP32");
|
display_init("SqueezeESP32");
|
||||||
|
MEMTRACE_PRINT_DELTA();
|
||||||
if(is_recovery_running && display){
|
if(is_recovery_running && display){
|
||||||
GDS_ClearExt(display, true);
|
GDS_ClearExt(display, true);
|
||||||
GDS_SetFont(display, &Font_droid_sans_fallback_15x17 );
|
GDS_SetFont(display, &Font_droid_sans_fallback_15x17 );
|
||||||
@@ -402,7 +435,7 @@ void app_main()
|
|||||||
|
|
||||||
ESP_LOGI(TAG,"Checking if certificates need to be updated");
|
ESP_LOGI(TAG,"Checking if certificates need to be updated");
|
||||||
update_certificates(false);
|
update_certificates(false);
|
||||||
|
MEMTRACE_PRINT_DELTA();
|
||||||
|
|
||||||
ESP_LOGD(TAG,"Getting firmware OTA URL (if any)");
|
ESP_LOGD(TAG,"Getting firmware OTA URL (if any)");
|
||||||
fwurl = process_ota_url();
|
fwurl = process_ota_url();
|
||||||
@@ -412,10 +445,10 @@ void app_main()
|
|||||||
if(bypass_wm==NULL)
|
if(bypass_wm==NULL)
|
||||||
{
|
{
|
||||||
ESP_LOGE(TAG, "Unable to retrieve the Wifi Manager bypass flag");
|
ESP_LOGE(TAG, "Unable to retrieve the Wifi Manager bypass flag");
|
||||||
bypass_wifi_manager = false;
|
bypass_network_manager = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
bypass_wifi_manager=(strcmp(bypass_wm,"1")==0 ||strcasecmp(bypass_wm,"y")==0);
|
bypass_network_manager=(strcmp(bypass_wm,"1")==0 ||strcasecmp(bypass_wm,"y")==0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!is_recovery_running){
|
if(!is_recovery_running){
|
||||||
@@ -432,25 +465,32 @@ void app_main()
|
|||||||
/* start the wifi manager */
|
/* start the wifi manager */
|
||||||
ESP_LOGD(TAG,"Blinking led");
|
ESP_LOGD(TAG,"Blinking led");
|
||||||
led_blink_pushed(LED_GREEN, 250, 250);
|
led_blink_pushed(LED_GREEN, 250, 250);
|
||||||
|
MEMTRACE_PRINT_DELTA();
|
||||||
if(bypass_wifi_manager){
|
if(bypass_network_manager){
|
||||||
ESP_LOGW(TAG,"wifi manager is disabled. Use command line for wifi control.");
|
ESP_LOGW(TAG,"Network manager is disabled. Use command line for wifi control.");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ESP_LOGI(TAG,"Starting Wifi Manager");
|
ESP_LOGI(TAG,"Starting Network Manager");
|
||||||
network_manager_start();
|
network_start();
|
||||||
//wifi_manager_set_callback(EVENT_STA_GOT_IP, &cb_connection_got_ip);
|
MEMTRACE_PRINT_DELTA();
|
||||||
wifi_manager_set_callback(EVENT_ETH_GOT_IP, &cb_connection_got_ip);
|
network_register_state_callback(NETWORK_WIFI_ACTIVE_STATE,WIFI_CONNECTED_STATE, "cb_connection_got_ip", &cb_connection_got_ip);
|
||||||
wifi_manager_set_callback(EVENT_STA_DISCONNECTED, &cb_connection_sta_disconnected);
|
network_register_state_callback(NETWORK_ETH_ACTIVE_STATE,ETH_ACTIVE_CONNECTED_STATE, "cb_connection_got_ip",&cb_connection_got_ip);
|
||||||
|
network_register_state_callback(NETWORK_WIFI_ACTIVE_STATE,WIFI_LOST_CONNECTION_STATE, "cb_connection_sta_disconnected",&cb_connection_sta_disconnected);
|
||||||
|
|
||||||
/* Start the telnet service after we are certain that the network stack has been properly initialized.
|
/* Start the telnet service after we are certain that the network stack has been properly initialized.
|
||||||
* This can be either after we're started the AP mode, or after we've started the STA mode */
|
* This can be either after we're started the AP mode, or after we've started the STA mode */
|
||||||
wifi_manager_set_callback(ORDER_START_AP, &handle_ap_connect);
|
network_register_state_callback(NETWORK_INITIALIZING_STATE,-1, "handle_ap_connect", &handle_ap_connect);
|
||||||
wifi_manager_set_callback(ORDER_CONNECT_STA, &handle_ap_connect);
|
network_register_state_callback(NETWORK_ETH_ACTIVE_STATE,ETH_ACTIVE_LINKDOWN_STATE, "handle_network_up", &handle_network_up);
|
||||||
|
network_register_state_callback(NETWORK_WIFI_ACTIVE_STATE,WIFI_INITIALIZING_STATE, "handle_network_up", &handle_network_up);
|
||||||
|
MEMTRACE_PRINT_DELTA();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("Starting Console");
|
||||||
console_start();
|
console_start();
|
||||||
|
MEMTRACE_PRINT_DELTA_MESSAGE("Console started");
|
||||||
if(fwurl && strlen(fwurl)>0){
|
if(fwurl && strlen(fwurl)>0){
|
||||||
if(is_recovery_running){
|
if(is_recovery_running){
|
||||||
while(!bWifiConnected){
|
while(!bNetworkConnected){
|
||||||
wait_for_wifi();
|
wait_for_wifi();
|
||||||
taskYIELD();
|
taskYIELD();
|
||||||
}
|
}
|
||||||
|
|||||||
19
sdkconfig
19
sdkconfig
@@ -202,6 +202,13 @@ CONFIG_DAC_CONTROLSET=""
|
|||||||
# Audio settings
|
# Audio settings
|
||||||
#
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Known Configurations
|
||||||
|
#
|
||||||
|
CONFIG_DAC_KNOWN_CONFIGURATIONS="ESP-A1S-AC101(audio kit 2.2)-Fixed GPIOs|ESP-A1S-ES8388(audio kit 2.2+)-Fixed GPIOs"
|
||||||
|
CONFIG_DAC_KNOWN_CONFIGURATIONS_GPIOS="model=AC101,bck=27,ws=26,do=25,di=35,sda=33,scl=32|model=ES8388,bck=5,ws=25,do=26,sda=18,scl=23,i2c=16"
|
||||||
|
# end of Known Configurations
|
||||||
|
|
||||||
#
|
#
|
||||||
# DAC settings
|
# DAC settings
|
||||||
#
|
#
|
||||||
@@ -313,7 +320,7 @@ CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
|||||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
|
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
|
||||||
# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set
|
# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set
|
||||||
# CONFIG_COMPILER_CXX_EXCEPTIONS is not set
|
# CONFIG_COMPILER_CXX_EXCEPTIONS is not set
|
||||||
CONFIG_COMPILER_CXX_RTTI=y
|
# CONFIG_COMPILER_CXX_RTTI is not set
|
||||||
CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y
|
CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y
|
||||||
# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set
|
# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set
|
||||||
# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set
|
# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set
|
||||||
@@ -930,9 +937,9 @@ CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y
|
|||||||
# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set
|
# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set
|
||||||
CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y
|
CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y
|
||||||
CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1
|
CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1
|
||||||
CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y
|
# CONFIG_FREERTOS_ASSERT_FAIL_ABORT is not set
|
||||||
# CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set
|
# CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set
|
||||||
# CONFIG_FREERTOS_ASSERT_DISABLE is not set
|
CONFIG_FREERTOS_ASSERT_DISABLE=y
|
||||||
CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536
|
CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536
|
||||||
CONFIG_FREERTOS_ISR_STACKSIZE=2096
|
CONFIG_FREERTOS_ISR_STACKSIZE=2096
|
||||||
# CONFIG_FREERTOS_LEGACY_HOOKS is not set
|
# CONFIG_FREERTOS_LEGACY_HOOKS is not set
|
||||||
@@ -980,12 +987,12 @@ CONFIG_HEAP_TRACING_OFF=y
|
|||||||
# Log output
|
# Log output
|
||||||
#
|
#
|
||||||
# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set
|
# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set
|
||||||
CONFIG_LOG_DEFAULT_LEVEL_ERROR=y
|
# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set
|
||||||
# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set
|
# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set
|
||||||
# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set
|
CONFIG_LOG_DEFAULT_LEVEL_INFO=y
|
||||||
# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set
|
# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set
|
||||||
# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set
|
# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set
|
||||||
CONFIG_LOG_DEFAULT_LEVEL=1
|
CONFIG_LOG_DEFAULT_LEVEL=3
|
||||||
CONFIG_LOG_COLORS=y
|
CONFIG_LOG_COLORS=y
|
||||||
CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y
|
CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y
|
||||||
# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set
|
# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set
|
||||||
|
|||||||
Reference in New Issue
Block a user