mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-08 12:37:01 +03:00
Network manager implemented and relatively stable
This commit is contained in:
@@ -8,6 +8,6 @@ idf_component_register( SRCS
|
||||
cmd_config.c
|
||||
INCLUDE_DIRS .
|
||||
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} ${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_component_register( SRCS cmd_squeezelite.c
|
||||
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")
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include "platform_esp32.h"
|
||||
#include "platform_config.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);
|
||||
static const char * TAG = "squeezelite_cmd";
|
||||
#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");
|
||||
|
||||
thread_parms.argc=0;
|
||||
thread_parms.argv = malloc(sizeof(char**)*(argc+ADDITIONAL_SQUEEZELITE_ARGS));
|
||||
memset(thread_parms.argv,'\0',sizeof(char**)*(argc+ADDITIONAL_SQUEEZELITE_ARGS));
|
||||
thread_parms.argv = malloc_init_external(sizeof(char**)*(argc+ADDITIONAL_SQUEEZELITE_ARGS));
|
||||
|
||||
for(int i=0;i<argc;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
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
//#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
|
||||
#include <stdio.h>
|
||||
#include "cmd_config.h"
|
||||
#include "argtable3/argtable3.h"
|
||||
@@ -18,14 +17,19 @@
|
||||
#include "trace.h"
|
||||
#include "messaging.h"
|
||||
#include "accessors.h"
|
||||
#include "adac.h"
|
||||
#include "globdefs.h"
|
||||
#include "cJSON.h"
|
||||
|
||||
const char * desc_squeezelite ="Squeezelite Options";
|
||||
const char * desc_dac= "DAC Options";
|
||||
const char * desc_preset= "Preset Options";
|
||||
const char * desc_spdif= "SPDIF Options";
|
||||
const char * desc_audio= "General Audio Options";
|
||||
const char * desc_bt_source= "Bluetooth Audio Output Options";
|
||||
const char * desc_rotary= "Rotary Control";
|
||||
|
||||
extern const struct adac_s *dac_set[];
|
||||
|
||||
#define CODECS_BASE "flac|pcm|mp3|ogg"
|
||||
#if NO_FAAD
|
||||
@@ -44,6 +48,11 @@ const char * desc_rotary= "Rotary Control";
|
||||
#define CODECS_DSD ""
|
||||
#endif
|
||||
#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)
|
||||
@@ -58,6 +67,7 @@ const char * desc_rotary= "Rotary Control";
|
||||
#define MODEL_NAME_STRING STR(MODEL_NAME)
|
||||
#endif
|
||||
|
||||
|
||||
#define CODECS CODECS_BASE CODECS_AAC CODECS_FF CODECS_DSD CODECS_MP3
|
||||
#define NOT_OUTPUT "has input capabilities only"
|
||||
#define NOT_GPIO "is not a GPIO"
|
||||
@@ -85,7 +95,10 @@ static struct {
|
||||
struct arg_lit *clear;
|
||||
struct arg_end *end;
|
||||
} i2s_args;
|
||||
|
||||
static struct {
|
||||
struct arg_str *model_name;
|
||||
struct arg_end *end;
|
||||
} known_model_args;
|
||||
static struct {
|
||||
struct arg_rem * rem;
|
||||
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 *result = malloc(strlen(opt_str)+1);
|
||||
memset(result, 0x00, strlen(opt_str)+1);
|
||||
char *str = strdup(opt_str);
|
||||
char *result = malloc_init_external(strlen(opt_str)+1);
|
||||
char *str = strdup_psram(opt_str);
|
||||
const char * output_marker=" -o";
|
||||
|
||||
if(!result ){
|
||||
@@ -555,7 +567,18 @@ static int do_rotary_cmd(int argc, char **argv){
|
||||
FREE_AND_NULL(buf);
|
||||
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)
|
||||
{
|
||||
i2s_platform_config_t i2s_dac_pin = {
|
||||
@@ -570,6 +593,7 @@ static int do_i2s_cmd(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
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;
|
||||
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;
|
||||
FILE *f = open_memstream(&buf, &buf_size);
|
||||
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");
|
||||
return 1;
|
||||
}
|
||||
if(nerrors >0){
|
||||
ESP_LOGE(TAG,"do_i2s_cmd: %d errors parsing arguments",nerrors);
|
||||
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);
|
||||
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){
|
||||
else {
|
||||
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';
|
||||
}
|
||||
if(!nerrors ){
|
||||
fprintf(f,"Storing i2s parameters.\n");
|
||||
nerrors+=(config_i2s_set(&i2s_dac_pin, "dac_config")!=ESP_OK);
|
||||
nerrors += is_output_gpio(i2s_args.clock, f, &i2s_dac_pin.pin.bck_io_num, true);
|
||||
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 (!nerrors) {
|
||||
fprintf(f, "Storing i2s parameters.\n");
|
||||
nerrors += (config_i2s_set(&i2s_dac_pin, "dac_config") != ESP_OK);
|
||||
}
|
||||
}
|
||||
if(!nerrors ){
|
||||
fprintf(f,"Done.\n");
|
||||
@@ -647,40 +671,58 @@ cJSON * example_cb(){
|
||||
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 * values = cJSON_CreateObject();
|
||||
|
||||
const i2s_platform_config_t * i2s_conf= config_dac_get( );
|
||||
|
||||
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 ) {
|
||||
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 ) {
|
||||
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 ) {
|
||||
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 ) {
|
||||
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 ) {
|
||||
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 ) {
|
||||
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 ) {
|
||||
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){
|
||||
cJSON_AddStringToObject(values,"model_name",i2s_conf->model);
|
||||
cJSON_AddStringToObject(values,i2s_args.model_name->hdr.longopts,i2s_conf->model);
|
||||
}
|
||||
else {
|
||||
cJSON_AddStringToObject(values,"model_name","I2S");
|
||||
cJSON_AddStringToObject(values,i2s_args.model_name->hdr.longopts,"I2S");
|
||||
}
|
||||
|
||||
return values;
|
||||
@@ -862,17 +904,288 @@ static char * get_log_level_options(const char * longname){
|
||||
char * options = NULL;
|
||||
int len = snprintf(NULL,0,template,longname,longname,longname);
|
||||
if(len>0){
|
||||
options = malloc(len+1);
|
||||
options = malloc_init_external(len+1);
|
||||
snprintf(options,len,template,longname,longname,longname);
|
||||
}
|
||||
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){
|
||||
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.clock = arg_int1(NULL,"clock","<n>","Clock GPIO. e.g. 33");
|
||||
i2s_args.wordselect = arg_int1(NULL,"wordselect","<n>","Word Select GPIO. e.g. 25");
|
||||
i2s_args.data = arg_int1(NULL,"data","<n>","Data GPIO. e.g. 32");
|
||||
i2s_args.clock = arg_int0(NULL,"clock","<n>","Clock GPIO. e.g. 33");
|
||||
i2s_args.wordselect = arg_int0(NULL,"wordselect","<n>","Word Select GPIO. e.g. 25");
|
||||
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_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");
|
||||
@@ -1005,6 +1318,9 @@ static void register_squeezelite_config(void){
|
||||
}
|
||||
|
||||
void register_config_cmd(void){
|
||||
if(!is_dac_config_locked()){
|
||||
register_known_templates_config();
|
||||
}
|
||||
register_audio_config();
|
||||
// register_squeezelite_config();
|
||||
register_bt_source_config();
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
//#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
|
||||
#include <stdio.h>
|
||||
#include "cmd_i2ctools.h"
|
||||
#include "argtable3/argtable3.h"
|
||||
@@ -21,6 +20,7 @@
|
||||
#include "messaging.h"
|
||||
#include "display.h"
|
||||
#include "config.h"
|
||||
#include "globdefs.h"
|
||||
|
||||
#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 */
|
||||
@@ -754,7 +754,7 @@ static int do_i2cget_cmd(int argc, char **argv)
|
||||
}
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
uint8_t *data = malloc(len);
|
||||
uint8_t *data = malloc_init_external(len);
|
||||
if (data_addr != -1) {
|
||||
i2c_master_write_byte(cmd, chip_addr << 1 | WRITE_BIT, 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
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
//#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -27,41 +26,50 @@ extern "C" {
|
||||
#include "nvs_utilities.h"
|
||||
#include "platform_console.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 * TAG = "cmd_nvs";
|
||||
|
||||
static struct {
|
||||
EXT_RAM_ATTR static struct {
|
||||
struct arg_str *key;
|
||||
struct arg_str *type;
|
||||
struct arg_str *value;
|
||||
struct arg_end *end;
|
||||
} set_args;
|
||||
|
||||
static struct {
|
||||
EXT_RAM_ATTR static struct {
|
||||
struct arg_str *key;
|
||||
struct arg_str *type;
|
||||
struct arg_end *end;
|
||||
} get_args;
|
||||
|
||||
static struct {
|
||||
EXT_RAM_ATTR static struct {
|
||||
struct arg_str *key;
|
||||
struct arg_end *end;
|
||||
} erase_args;
|
||||
|
||||
static struct {
|
||||
EXT_RAM_ATTR static struct {
|
||||
struct arg_str *namespace;
|
||||
struct arg_end *end;
|
||||
} erase_all_args;
|
||||
|
||||
static struct {
|
||||
EXT_RAM_ATTR static struct {
|
||||
struct arg_str *partition;
|
||||
struct arg_str *namespace;
|
||||
struct arg_str *type;
|
||||
struct arg_end *end;
|
||||
} 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)
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
char *blob = (char *)malloc(blob_len);
|
||||
char *blob = (char *)malloc_init_external(blob_len);
|
||||
if (blob == NULL) {
|
||||
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) {
|
||||
size_t len=0;
|
||||
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) {
|
||||
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) {
|
||||
size_t len;
|
||||
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) {
|
||||
log_send_messaging(MESSAGING_INFO,"Blob associated with key '%s' is %d bytes long: \n", key, len);
|
||||
print_blob(blob, len);
|
||||
@@ -399,7 +407,7 @@ static int erase_namespace(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int erase_wifi_manager(int argc, char **argv)
|
||||
static int erase_network_manager(int argc, char **argv)
|
||||
{
|
||||
nvs_handle 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);
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -476,6 +518,10 @@ void register_nvs()
|
||||
erase_all_args.namespace = arg_str1(NULL, NULL, "<namespace>", "namespace to be erased");
|
||||
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.namespace = arg_str0("n", "namespace", "<namespace>", "namespace name");
|
||||
list_args.type = arg_str0("t", "type", "<type>", ARG_TYPE_STR);
|
||||
@@ -516,11 +562,19 @@ void register_nvs()
|
||||
.func = &erase_namespace,
|
||||
.argtable = &erase_all_args
|
||||
};
|
||||
const esp_console_cmd_t erase_wifimanager_cmd = {
|
||||
.command = "nvs_erase_wifi_manager",
|
||||
.help = "Erases wifi_manager's config",
|
||||
const esp_console_cmd_t erase_config_cmd = {
|
||||
.command = "wifi_erase_config",
|
||||
.help = "Erases all stored access points from flash",
|
||||
.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
|
||||
};
|
||||
|
||||
@@ -535,12 +589,21 @@ void register_nvs()
|
||||
.func = &list_entries,
|
||||
.argtable = &list_args
|
||||
};
|
||||
MEMTRACE_PRINT_DELTA_MESSAGE("registering 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));
|
||||
MEMTRACE_PRINT_DELTA_MESSAGE("registering 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));
|
||||
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_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
|
||||
|
||||
@@ -32,21 +32,23 @@
|
||||
#include "messaging.h"
|
||||
#include "platform_console.h"
|
||||
#include "trace.h"
|
||||
#include "globdefs.h"
|
||||
|
||||
#ifdef CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS
|
||||
#pragma message("Runtime stats enabled")
|
||||
#define WITH_TASKS_INFO 1
|
||||
#else
|
||||
#pragma message("Runtime stats disabled")
|
||||
#endif
|
||||
static struct {
|
||||
EXT_RAM_ATTR static struct {
|
||||
struct arg_str *scanmode;
|
||||
struct arg_end *end;
|
||||
} wifi_parms_arg;
|
||||
static struct {
|
||||
EXT_RAM_ATTR static struct {
|
||||
struct arg_str *name;
|
||||
struct arg_end *end;
|
||||
} name_args;
|
||||
static struct {
|
||||
EXT_RAM_ATTR static struct {
|
||||
struct arg_lit *btspeaker;
|
||||
struct arg_lit *airplay;
|
||||
struct arg_str *telnet;
|
||||
@@ -61,6 +63,7 @@ static const char * TAG = "cmd_system";
|
||||
static void register_free();
|
||||
static void register_setdevicename();
|
||||
static void register_heap();
|
||||
static void register_dump_heap();
|
||||
static void register_version();
|
||||
static void register_restart();
|
||||
static void register_deep_sleep();
|
||||
@@ -73,7 +76,7 @@ static void register_set_wifi_parms();
|
||||
#if WITH_TASKS_INFO
|
||||
static void register_tasks();
|
||||
#endif
|
||||
extern BaseType_t wifi_manager_task;
|
||||
extern BaseType_t network_manager_task;
|
||||
void register_system()
|
||||
{
|
||||
register_set_wifi_parms();
|
||||
@@ -81,6 +84,7 @@ void register_system()
|
||||
register_free();
|
||||
register_set_services();
|
||||
register_heap();
|
||||
register_dump_heap();
|
||||
register_setdevicename();
|
||||
register_version();
|
||||
register_restart();
|
||||
@@ -297,12 +301,35 @@ static void register_free()
|
||||
cmd_to_json(&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 */
|
||||
static int heap_size(int argc, char **argv)
|
||||
{
|
||||
uint32_t heap_size = heap_caps_get_minimum_free_size(MALLOC_CAP_DEFAULT);
|
||||
cmd_send_messaging(argv[0],MESSAGING_INFO, "min heap size: %u", heap_size);
|
||||
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)",
|
||||
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;
|
||||
}
|
||||
cJSON * setdevicename_cb(){
|
||||
@@ -341,10 +368,9 @@ int set_squeezelite_player_name(FILE * f,const char * name){
|
||||
if(nvs_config && strlen(nvs_config)>0){
|
||||
// allocate enough memory to hold the new command line
|
||||
size_t cmdLength = strlen(nvs_config) + strlen(cleaned_name) + strlen(parm) +1 ;
|
||||
newCommandLine = malloc(cmdLength);
|
||||
memset(newCommandLine,0x00, cmdLength);
|
||||
ESP_LOGD(TAG,"Parsing command %s",nvs_config);
|
||||
argv = (char **) calloc(22, sizeof(char *));
|
||||
newCommandLine = malloc_init_external(cmdLength);
|
||||
ESP_LOGD(TAG,"Parsing command %s",nvs_config);
|
||||
argv = (char **) malloc_init_external(22* sizeof(char *));
|
||||
if (argv == NULL) {
|
||||
FREE_AND_NULL(nvs_config);
|
||||
return 1;
|
||||
@@ -400,7 +426,7 @@ static int setdevicename(int argc, char **argv)
|
||||
|
||||
/* Check "--name" option */
|
||||
if (name_args.name->count) {
|
||||
name=strdup(name_args.name->sval[0]);
|
||||
name=strdup_psram(name_args.name->sval[0]);
|
||||
}
|
||||
else {
|
||||
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()
|
||||
{
|
||||
@@ -470,7 +507,7 @@ static void register_setdevicename()
|
||||
static int tasks_info(int argc, char **argv)
|
||||
{
|
||||
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) {
|
||||
cmd_send_messaging(argv[0],MESSAGING_ERROR, "failed to allocate buffer for vTaskList output");
|
||||
return 1;
|
||||
|
||||
@@ -32,12 +32,12 @@
|
||||
#include "esp_netif.h"
|
||||
#include "esp_event.h"
|
||||
#include "led.h"
|
||||
extern bool bypass_wifi_manager;
|
||||
extern bool bypass_network_manager;
|
||||
#define JOIN_TIMEOUT_MS (10000)
|
||||
#include "platform_console.h"
|
||||
|
||||
|
||||
extern EventGroupHandle_t wifi_event_group;
|
||||
extern EventGroupHandle_t network_event_group;
|
||||
extern const int CONNECTED_BIT;
|
||||
//static const char * TAG = "cmd_wifi";
|
||||
/** 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) {
|
||||
led_blink_pushed(LED_GREEN, 250, 250);
|
||||
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) {
|
||||
led_unpush(LED_GREEN);
|
||||
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
|
||||
xEventGroupSetBits(network_event_group, CONNECTED_BIT);
|
||||
}
|
||||
}
|
||||
//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_connect() );
|
||||
|
||||
int bits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
|
||||
int bits = xEventGroupWaitBits(network_event_group, CONNECTED_BIT,
|
||||
pdFALSE, pdTRUE, timeout_ms / portTICK_PERIOD_MS);
|
||||
return (bits & CONNECTED_BIT) != 0;
|
||||
}
|
||||
@@ -202,7 +202,7 @@ void register_wifi_join()
|
||||
void register_wifi()
|
||||
{
|
||||
register_wifi_join();
|
||||
if(bypass_wifi_manager){
|
||||
if(bypass_network_manager){
|
||||
initialise_wifi();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ pthread_t thread_console;
|
||||
static void * console_thread();
|
||||
void console_start();
|
||||
static const char * TAG = "console";
|
||||
extern bool bypass_wifi_manager;
|
||||
extern bool bypass_network_manager;
|
||||
extern void register_squeezelite();
|
||||
|
||||
/* Prompt to be printed before each line.
|
||||
@@ -188,8 +188,8 @@ void process_autoexec(){
|
||||
uint8_t autoexec_flag=0;
|
||||
|
||||
char * str_flag = config_alloc_get(NVS_TYPE_STR, "autoexec");
|
||||
if(!bypass_wifi_manager){
|
||||
ESP_LOGW(TAG, "Processing autoexec commands while wifi_manager active. Wifi related commands will be ignored.");
|
||||
if(!bypass_network_manager){
|
||||
ESP_LOGW(TAG, "Processing autoexec commands while network manager active. Wifi related commands will be ignored.");
|
||||
}
|
||||
if(is_recovery_running){
|
||||
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);
|
||||
autoexec_value= config_alloc_get(NVS_TYPE_STR, autoexec_name);
|
||||
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.");
|
||||
}
|
||||
else if(is_recovery_running && !strstr(autoexec_value, "squeezelite " ) ){
|
||||
@@ -298,18 +298,26 @@ void console_start() {
|
||||
ESP_ERROR_CHECK(esp_console_init(&console_config));
|
||||
}
|
||||
/* Register commands */
|
||||
MEMTRACE_PRINT_DELTA_MESSAGE("Registering help command");
|
||||
esp_console_register_help_command();
|
||||
MEMTRACE_PRINT_DELTA_MESSAGE("Registering system commands");
|
||||
register_system();
|
||||
MEMTRACE_PRINT_DELTA_MESSAGE("Registering config commands");
|
||||
register_config_cmd();
|
||||
MEMTRACE_PRINT_DELTA_MESSAGE("Registering nvs commands");
|
||||
register_nvs();
|
||||
MEMTRACE_PRINT_DELTA_MESSAGE("Registering wifi commands");
|
||||
register_wifi();
|
||||
|
||||
if(!is_recovery_running){
|
||||
MEMTRACE_PRINT_DELTA_MESSAGE("Registering squeezelite commands");
|
||||
register_squeezelite();
|
||||
}
|
||||
else {
|
||||
MEMTRACE_PRINT_DELTA_MESSAGE("Registering recovery commands");
|
||||
register_ota_cmd();
|
||||
}
|
||||
MEMTRACE_PRINT_DELTA_MESSAGE("Registering i2c commands");
|
||||
register_i2ctools();
|
||||
|
||||
if(!is_serial_suppressed()){
|
||||
@@ -358,14 +366,16 @@ void console_start() {
|
||||
prompt = recovery_prompt;
|
||||
cfg.stack_size = 4096 ;
|
||||
}
|
||||
MEMTRACE_PRINT_DELTA_MESSAGE("Creating console thread with stack size of 4096 bytes");
|
||||
esp_pthread_set_cfg(&cfg);
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
|
||||
pthread_create(&thread_console, &attr, console_thread, NULL);
|
||||
pthread_attr_destroy(&attr);
|
||||
MEMTRACE_PRINT_DELTA_MESSAGE("Console thread created");
|
||||
}
|
||||
else if(!is_recovery_running){
|
||||
MEMTRACE_PRINT_DELTA_MESSAGE("Running autoexec");
|
||||
process_autoexec();
|
||||
}
|
||||
|
||||
@@ -392,7 +402,9 @@ esp_err_t run_command(char * line){
|
||||
}
|
||||
static void * console_thread() {
|
||||
if(!is_recovery_running){
|
||||
MEMTRACE_PRINT_DELTA_MESSAGE("Running autoexec");
|
||||
process_autoexec();
|
||||
MEMTRACE_PRINT_DELTA_MESSAGE("Autoexec done");
|
||||
}
|
||||
/* Main loop */
|
||||
while (1) {
|
||||
|
||||
Reference in New Issue
Block a user