initial refactoring

This commit is contained in:
Sebastien L
2023-12-04 23:25:57 -05:00
parent d03678ea81
commit c0ddf0a997
331 changed files with 29663 additions and 16553 deletions

View File

@@ -1,6 +1,5 @@
idf_component_register( SRCS
cmd_i2ctools.c
cmd_nvs.c
cmd_ota.c
cmd_system.c
cmd_wifi.c

View File

@@ -40,7 +40,10 @@ int main(int argc, char **argv){
return 1;
}
void register_squeezelite(){
// void register_squeezelite(){
// }
void start_squeezelite(){
}
void register_external(void) {

View File

@@ -9,14 +9,16 @@
#include "freertos/event_groups.h"
#include "pthread.h"
#include "platform_esp32.h"
#include "platform_config.h"
#include "Configurator.h"
#include "esp_app_format.h"
#include "tools.h"
#include "messaging.h"
extern esp_err_t process_recovery_ota(const char * bin_url, char * bin_buffer, uint32_t length);
extern int squeezelite_main_start();
static const char * TAG = "squeezelite_cmd";
#define SQUEEZELITE_THREAD_STACK_SIZE (8*1024)
#define ADDITIONAL_SQUEEZELITE_ARGS 5
const __attribute__((section(".rodata_desc"))) esp_app_desc_t esp_app_desc = {
@@ -41,19 +43,9 @@ const __attribute__((section(".rodata_desc"))) esp_app_desc_t esp_app_desc = {
};
extern void register_audio_config(void);
extern void register_rotary_config(void);
extern void register_ledvu_config(void);
// extern void register_rotary_config(void);
extern void register_nvs();
extern cJSON * get_gpio_list_handler(bool refresh);
void register_optional_cmd(void) {
#if CONFIG_WITH_CONFIG_UI
register_rotary_config();
#endif
register_audio_config();
register_ledvu_config();
register_nvs();
}
cJSON * get_gpio_list(bool refresh){
#if CONFIG_WITH_CONFIG_UI
return get_gpio_list_handler(refresh);
@@ -61,11 +53,14 @@ cJSON * get_gpio_list(bool refresh){
return cJSON_CreateArray();
#endif
}
void register_optional_cmd(void) {
// #if CONFIG_WITH_CONFIG_UI
// register_rotary_config();
// #endif
register_audio_config();
// register_ledvu_config();
extern int squeezelite_main(int argc, char **argv);
static int launchsqueezelite(int argc, char **argv);
}
/** Arguments used by 'squeezelite' function */
static struct {
@@ -77,7 +72,6 @@ static struct {
char ** argv;
} thread_parms ;
#define ADDITIONAL_SQUEEZELITE_ARGS 5
static void squeezelite_thread(void *arg){
ESP_LOGV(TAG ,"Number of args received: %u",thread_parms.argc );
ESP_LOGV(TAG ,"Values:");
@@ -85,13 +79,14 @@ static void squeezelite_thread(void *arg){
ESP_LOGV(TAG ," %s",thread_parms.argv[i]);
}
ESP_LOGI(TAG ,"Calling squeezelite");
int ret = squeezelite_main(thread_parms.argc, thread_parms.argv);
int ret = squeezelite_main_start(thread_parms.argc, thread_parms.argv);
cmd_send_messaging("cfg-audio-tmpl",ret > 1 ? MESSAGING_ERROR : MESSAGING_WARNING,"squeezelite exited with error code %d\n", ret);
if (ret <= 1) {
int wait = 60;
wait_for_commit();
// wait_for_commit();
// TODO: Add support for the commented code
cmd_send_messaging("cfg-audio-tmpl",MESSAGING_ERROR,"Rebooting in %d sec\n", wait);
vTaskDelay( pdMS_TO_TICKS(wait * 1000));
esp_restart();
@@ -119,26 +114,26 @@ static int launchsqueezelite(int argc, char **argv) {
ESP_LOGV(TAG ,"Begin");
isRunning = true;
ESP_LOGV(TAG, "Parameters:");
for(int i = 0;i<argc; i++){
ESP_LOGV(TAG, " %s",argv[i]);
}
ESP_LOGV(TAG,"Saving args in thread structure");
// ESP_LOGV(TAG, "Parameters:");
// for(int i = 0;i<argc; i++){
// ESP_LOGV(TAG, " %s",argv[i]);
// }
// ESP_LOGV(TAG,"Saving args in thread structure");
thread_parms.argc=0;
thread_parms.argv = malloc_init_external(sizeof(char**)*(argc+ADDITIONAL_SQUEEZELITE_ARGS));
// thread_parms.argc=0;
// 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]);
thread_parms.argv[thread_parms.argc++]=strdup(argv[i]);
}
// for(int i=0;i<argc;i++){
// ESP_LOGD(TAG ,"assigning parm %u : %s",i,argv[i]);
// thread_parms.argv[thread_parms.argc++]=strdup(argv[i]);
// }
if(argc==1){
// There isn't a default configuration that would actually work
// if no parameter is passed.
ESP_LOGV(TAG ,"Adding argv value at %u. Prev value: %s",thread_parms.argc,thread_parms.argv[thread_parms.argc-1]);
thread_parms.argv[thread_parms.argc++]=strdup("-?");
}
// if(argc==1){
// // There isn't a default configuration that would actually work
// // if no parameter is passed.
// ESP_LOGV(TAG ,"Adding argv value at %u. Prev value: %s",thread_parms.argc,thread_parms.argv[thread_parms.argc-1]);
// thread_parms.argv[thread_parms.argc++]=strdup("-?");
// }
ESP_LOGD(TAG,"Starting Squeezelite Thread");
xTaskCreateStaticPinnedToCore(squeezelite_thread, "squeezelite", SQUEEZELITE_THREAD_STACK_SIZE,
@@ -147,35 +142,34 @@ static int launchsqueezelite(int argc, char **argv) {
return 0;
}
void register_squeezelite() {
squeezelite_args.parameters = arg_str0(NULL, NULL, "<parms>", "command line for squeezelite. -h for help, --defaults to launch with default values.");
squeezelite_args.end = arg_end(1);
const esp_console_cmd_t launch_squeezelite = {
.command = "squeezelite",
.help = "Starts squeezelite",
.hint = NULL,
.func = &launchsqueezelite,
.argtable = &squeezelite_args
};
ESP_ERROR_CHECK( esp_console_cmd_register(&launch_squeezelite) );
void start_squeezelite(){
launchsqueezelite(0,NULL);
}
// void register_squeezelite() {
// squeezelite_args.parameters = arg_str0(NULL, NULL, "<parms>", "command line for squeezelite. -h for help, --defaults to launch with default values.");
// squeezelite_args.end = arg_end(1);
// const esp_console_cmd_t launch_squeezelite = {
// .command = "squeezelite",
// .help = "Starts squeezelite",
// .hint = NULL,
// .func = &launchsqueezelite,
// .argtable = &squeezelite_args
// };
// ESP_ERROR_CHECK( esp_console_cmd_register(&launch_squeezelite) );
// }
esp_err_t start_ota(const char * bin_url, char * bin_buffer, uint32_t length) {
if(!bin_url){
if(!bin_url || strlen(bin_url)==0){
ESP_LOGE(TAG,"missing URL parameter. Unable to start OTA");
return ESP_ERR_INVALID_ARG;
}
ESP_LOGW(TAG, "Called to update the firmware from url: %s",bin_url);
if(config_set_value(NVS_TYPE_STR, "fwurl", bin_url) != ESP_OK){
ESP_LOGE(TAG,"Failed to save the OTA url into nvs cache");
return ESP_FAIL;
}
configurator_set_string(&sys_State_msg,sys_State_ota_url_tag,sys_state,bin_url);
configurator_raise_state_changed();
if(!wait_for_commit()){
if(!configurator_waitcommit()){
ESP_LOGW(TAG,"Unable to commit configuration. ");
}
ESP_LOGW(TAG, "Rebooting to recovery to complete the installation");
return guided_factory();
return ESP_OK;

File diff suppressed because it is too large Load Diff

View File

@@ -14,7 +14,6 @@ extern "C" {
#include "cmd_system.h"
#include "cmd_wifi.h"
#include "cmd_nvs.h"
#include "cmd_i2ctools.h"
#include "cmd_ota.h"
#include "cmd_config.h"

View File

@@ -16,7 +16,8 @@
#include "driver/i2c.h"
#include "esp_log.h"
#include "messaging.h"
#include "platform_config.h"
// #include "Configurator.h"
#pragma message("fixme: look for TODO below")
#include "platform_console.h"
#include "stdio.h"
#include "string.h"
@@ -520,86 +521,87 @@ static int do_spiconfig_cmd(int argc, char** argv) {
static int do_i2cconfig_cmd(int argc, char** argv) {
esp_err_t err = ESP_OK;
i2c_config_t conf = {.mode = I2C_MODE_MASTER,
.sda_io_num = 19,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_io_num = 18,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = 100000};
// i2c_config_t conf = {.mode = I2C_MODE_MASTER,
// .sda_io_num = 19,
// .sda_pullup_en = GPIO_PULLUP_ENABLE,
// .scl_io_num = 18,
// .scl_pullup_en = GPIO_PULLUP_ENABLE,
// .master.clk_speed = 100000};
int nerrors = arg_parse_msg(argc, argv, (struct arg_hdr**)&i2cconfig_args);
/* Check "--clear" option */
if (i2cconfig_args.clear->count) {
cmd_send_messaging(argv[0], MESSAGING_WARNING, "i2c config cleared\n");
config_set_value(NVS_TYPE_STR, "i2c_config", "");
return 0;
}
// if (i2cconfig_args.clear->count) {
// cmd_send_messaging(argv[0], MESSAGING_WARNING, "i2c config cleared\n");
// config_set_value(NVS_TYPE_STR, "i2c_config", "");
// return 0;
// }
// TODO: Add support for the commented code
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, i2cconfig_args.end, desc_i2c);
fclose(f);
return 1;
}
/* Check "--port" option */
if (i2cconfig_args.port->count) {
if (i2c_get_port(i2cconfig_args.port->ival[0], &i2c_port) != ESP_OK) {
fprintf(f, "Invalid port %u \n", i2cconfig_args.port->ival[0]);
nerrors++;
}
}
/* Check "--freq" option */
if (i2cconfig_args.freq->count) {
conf.master.clk_speed = i2cconfig_args.freq->ival[0];
}
// 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, i2cconfig_args.end, desc_i2c);
// fclose(f);
// return 1;
// }
// /* Check "--port" option */
// if (i2cconfig_args.port->count) {
// if (i2c_get_port(i2cconfig_args.port->ival[0], &i2c_port) != ESP_OK) {
// fprintf(f, "Invalid port %u \n", i2cconfig_args.port->ival[0]);
// nerrors++;
// }
// }
// /* Check "--freq" option */
// if (i2cconfig_args.freq->count) {
// conf.master.clk_speed = i2cconfig_args.freq->ival[0];
// }
nerrors += is_output_gpio(i2cconfig_args.sda, f, &conf.sda_io_num, true);
nerrors += is_output_gpio(i2cconfig_args.scl, f, &conf.scl_io_num, true);
// nerrors += is_output_gpio(i2cconfig_args.sda, f, &conf.sda_io_num, true);
// nerrors += is_output_gpio(i2cconfig_args.scl, f, &conf.scl_io_num, true);
#ifdef CONFIG_I2C_LOCKED
if (i2c_port == I2C_NUM_0) {
i2c_port = I2C_NUM_1;
fprintf(f, "can't use i2c port 0 when locked by config. Changing to port 1.\n");
}
#endif
// #ifdef CONFIG_I2C_LOCKED
// if (i2c_port == I2C_NUM_0) {
// i2c_port = I2C_NUM_1;
// fprintf(f, "can't use i2c port 0 when locked by config. Changing to port 1.\n");
// }
// #endif
if (!nerrors) {
fprintf(f, "Uninstalling i2c driver from port %u if needed\n", i2c_port);
if (is_i2c_started(i2c_port)) {
if ((err = i2c_driver_delete(i2c_port)) != ESP_OK) {
fprintf(f, "i2c driver delete failed. %s\n", esp_err_to_name(err));
nerrors++;
}
}
}
if (!nerrors) {
if ((err = i2c_master_driver_initialize(argv[0], &conf)) == ESP_OK) {
if ((err = i2c_master_driver_install(argv[0])) != ESP_OK) {
nerrors++;
} else {
fprintf(f, "i2c driver successfully started.\n");
}
} else {
nerrors++;
}
}
if (!nerrors) {
fprintf(f, "Storing i2c parameters.\n");
config_i2c_set(&conf, i2c_port);
}
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);
// if (!nerrors) {
// fprintf(f, "Uninstalling i2c driver from port %u if needed\n", i2c_port);
// if (is_i2c_started(i2c_port)) {
// if ((err = i2c_driver_delete(i2c_port)) != ESP_OK) {
// fprintf(f, "i2c driver delete failed. %s\n", esp_err_to_name(err));
// nerrors++;
// }
// }
// }
// if (!nerrors) {
// if ((err = i2c_master_driver_initialize(argv[0], &conf)) == ESP_OK) {
// if ((err = i2c_master_driver_install(argv[0])) != ESP_OK) {
// nerrors++;
// } else {
// fprintf(f, "i2c driver successfully started.\n");
// }
// } else {
// nerrors++;
// }
// }
// if (!nerrors) {
// fprintf(f, "Storing i2c parameters.\n");
// config_i2c_set(&conf, i2c_port);
// }
// 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;
}
@@ -971,50 +973,7 @@ static int do_i2cdetect_cmd(int argc, char** argv) {
return 0;
}
cJSON* i2c_set_display_cb() {
cJSON* values = cJSON_CreateObject();
const display_config_t* conf = config_display_get();
if (conf) {
if (conf->width > 0) {
cJSON_AddNumberToObject(values, "width", conf->width);
}
if (conf->height > 0) {
cJSON_AddNumberToObject(values, "height", conf->height);
}
if (conf->address > 0) {
cJSON_AddNumberToObject(values, "address", conf->address);
}
if (conf->RST_pin >= 0) {
cJSON_AddNumberToObject(values, "reset", conf->RST_pin);
}
if (conf->drivername && strlen(conf->drivername) > 0) {
cJSON_AddStringToObject(values, "driver", conf->drivername);
}
if (conf->CS_pin >= 0) {
cJSON_AddNumberToObject(values, "cs", conf->CS_pin);
}
if (conf->speed > 0) {
cJSON_AddNumberToObject(values, "speed", conf->speed);
}
if (conf->back >= 0) {
cJSON_AddNumberToObject(values, "back", conf->back);
}
if (conf->depth > 0) {
cJSON_AddNumberToObject(values, "depth", conf->depth);
}
if (conf->type && strlen(conf->type)) {
cJSON_AddStringToObject(values, "type", conf->type);
}
cJSON_AddBoolToObject(values, "rotate", conf->rotate);
cJSON_AddBoolToObject(values, "hf", conf->hflip);
cJSON_AddBoolToObject(values, "vf", conf->vflip);
cJSON_AddBoolToObject(values, "invert", conf->invert);
if (conf->mode >= 0) {
cJSON_AddNumberToObject(values, "mode", conf->mode);
}
}
return values;
}
#if CONFIG_WITH_CONFIG_UI
static void register_i2c_set_display() {
@@ -1044,7 +1003,6 @@ static void register_i2c_set_display() {
.hint = NULL,
.func = &do_i2c_set_display,
.argtable = &i2cdisp_args};
cmd_to_json_with_cb(&i2c_set_display, &i2c_set_display_cb);
ESP_ERROR_CHECK(esp_console_cmd_register(&i2c_set_display));
}
#endif

View File

@@ -1,612 +0,0 @@
/* Console example — NVS commands
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "nvs_flash.h"
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include "esp_log.h"
#include "esp_console.h"
#include "argtable3/argtable3.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "esp_err.h"
#include "cmd_nvs.h"
#include "nvs.h"
#include "nvs_utilities.h"
#include "platform_console.h"
#include "messaging.h"
#include "tools.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";
EXT_RAM_ATTR static struct {
struct arg_str *key;
struct arg_str *type;
struct arg_str *value;
struct arg_end *end;
} set_args;
EXT_RAM_ATTR static struct {
struct arg_str *key;
struct arg_str *type;
struct arg_end *end;
} get_args;
EXT_RAM_ATTR static struct {
struct arg_str *key;
struct arg_end *end;
} erase_args;
EXT_RAM_ATTR static struct {
struct arg_str *namespace;
struct arg_end *end;
} erase_all_args;
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)
{
uint8_t value;
size_t str_len = strlen(str_values);
size_t blob_len = str_len / 2;
if (str_len % 2) {
log_send_messaging(MESSAGING_ERROR, "Blob data must contain even number of characters");
return ESP_ERR_NVS_TYPE_MISMATCH;
}
char *blob = (char *)malloc_init_external(blob_len);
if (blob == NULL) {
return ESP_ERR_NO_MEM;
}
for (int i = 0, j = 0; i < str_len; i++) {
char ch = str_values[i];
if (ch >= '0' && ch <= '9') {
value = ch - '0';
} else if (ch >= 'A' && ch <= 'F') {
value = ch - 'A' + 10;
} else if (ch >= 'a' && ch <= 'f') {
value = ch - 'a' + 10;
} else {
log_send_messaging(MESSAGING_ERROR, "Blob data contain invalid character");
free(blob);
return ESP_ERR_NVS_TYPE_MISMATCH;
}
if (i & 1) {
blob[j++] += value;
} else {
blob[j] = value << 4;
}
}
esp_err_t err = nvs_set_blob(nvs, key, blob, blob_len);
free(blob);
if (err == ESP_OK) {
err = nvs_commit(nvs);
}
return err;
}
static esp_err_t set_value_in_nvs(const char *key, const char *str_type, const char *str_value)
{
esp_err_t err;
nvs_handle nvs;
bool range_error = false;
nvs_type_t type = str_to_type(str_type);
if (type == NVS_TYPE_ANY) {
return ESP_ERR_NVS_TYPE_MISMATCH;
}
err = nvs_open_from_partition(settings_partition, current_namespace, NVS_READWRITE, &nvs);
if (err != ESP_OK) {
return err;
}
if (type == NVS_TYPE_I8) {
int32_t value = strtol(str_value, NULL, 0);
if (value < INT8_MIN || value > INT8_MAX || errno == ERANGE) {
range_error = true;
} else {
err = nvs_set_i8(nvs, key, (int8_t)value);
}
} else if (type == NVS_TYPE_U8) {
uint32_t value = strtoul(str_value, NULL, 0);
if (value > UINT8_MAX || errno == ERANGE) {
range_error = true;
} else {
err = nvs_set_u8(nvs, key, (uint8_t)value);
}
} else if (type == NVS_TYPE_I16) {
int32_t value = strtol(str_value, NULL, 0);
if (value < INT16_MIN || value > INT16_MAX || errno == ERANGE) {
range_error = true;
} else {
err = nvs_set_i16(nvs, key, (int16_t)value);
}
} else if (type == NVS_TYPE_U16) {
uint32_t value = strtoul(str_value, NULL, 0);
if (value > UINT16_MAX || errno == ERANGE) {
range_error = true;
} else {
err = nvs_set_u16(nvs, key, (uint16_t)value);
}
} else if (type == NVS_TYPE_I32) {
int32_t value = strtol(str_value, NULL, 0);
if (errno != ERANGE) {
err = nvs_set_i32(nvs, key, value);
}
} else if (type == NVS_TYPE_U32) {
uint32_t value = strtoul(str_value, NULL, 0);
if (errno != ERANGE) {
err = nvs_set_u32(nvs, key, value);
}
} else if (type == NVS_TYPE_I64) {
int64_t value = strtoll(str_value, NULL, 0);
if (errno != ERANGE) {
err = nvs_set_i64(nvs, key, value);
}
} else if (type == NVS_TYPE_U64) {
uint64_t value = strtoull(str_value, NULL, 0);
if (errno != ERANGE) {
err = nvs_set_u64(nvs, key, value);
}
} else if (type == NVS_TYPE_STR) {
err = nvs_set_str(nvs, key, str_value);
} else if (type == NVS_TYPE_BLOB) {
err = store_blob(nvs, key, str_value);
}
if (range_error || errno == ERANGE) {
nvs_close(nvs);
return ESP_ERR_NVS_VALUE_TOO_LONG;
}
if (err == ESP_OK) {
log_send_messaging(MESSAGING_INFO, "Set value ok. Committing '%s'", key);
err = nvs_commit(nvs);
if (err == ESP_OK) {
log_send_messaging(MESSAGING_INFO, "Value stored under key '%s'", key);
}
}
nvs_close(nvs);
return err;
}
static esp_err_t get_value_from_nvs(const char *key, const char *str_type)
{
nvs_handle nvs;
esp_err_t err;
nvs_type_t type = str_to_type(str_type);
if (type == NVS_TYPE_ANY) {
return ESP_ERR_NVS_TYPE_MISMATCH;
}
err = nvs_open_from_partition(settings_partition, current_namespace, NVS_READWRITE, &nvs);
if (err != ESP_OK) {
return err;
}
if (type == NVS_TYPE_I8) {
int8_t value;
err = nvs_get_i8(nvs, key, &value);
if (err == ESP_OK) {
log_send_messaging(MESSAGING_INFO,"Value associated with key '%s' is %d \n", key, value);
}
} else if (type == NVS_TYPE_U8) {
uint8_t value;
err = nvs_get_u8(nvs, key, &value);
if (err == ESP_OK) {
log_send_messaging(MESSAGING_INFO,"Value associated with key '%s' is %u \n", key, value);
}
} else if (type == NVS_TYPE_I16) {
int16_t value;
err = nvs_get_i16(nvs, key, &value);
if (err == ESP_OK) {
log_send_messaging(MESSAGING_INFO,"Value associated with key '%s' is %d \n", key, value);
}
} else if (type == NVS_TYPE_U16) {
uint16_t value;
if ((err = nvs_get_u16(nvs, key, &value)) == ESP_OK) {
log_send_messaging(MESSAGING_INFO,"Value associated with key '%s' is %u", key, value);
}
} else if (type == NVS_TYPE_I32) {
int32_t value;
if ((err = nvs_get_i32(nvs, key, &value)) == ESP_OK) {
log_send_messaging(MESSAGING_INFO,"Value associated with key '%s' is %d \n", key, value);
}
} else if (type == NVS_TYPE_U32) {
uint32_t value;
if ((err = nvs_get_u32(nvs, key, &value)) == ESP_OK) {
log_send_messaging(MESSAGING_INFO,"Value associated with key '%s' is %u \n", key, value);
}
} else if (type == NVS_TYPE_I64) {
int64_t value;
if ((err = nvs_get_i64(nvs, key, &value)) == ESP_OK) {
log_send_messaging(MESSAGING_INFO,"Value associated with key '%s' is %lld \n", key, value);
}
} else if (type == NVS_TYPE_U64) {
uint64_t value;
if ( (err = nvs_get_u64(nvs, key, &value)) == ESP_OK) {
log_send_messaging(MESSAGING_INFO,"Value associated with key '%s' is %llu \n", key, value);
}
} 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_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);
}
free(str);
}
} else if (type == NVS_TYPE_BLOB) {
size_t len;
if ( (err = nvs_get_blob(nvs, key, NULL, &len)) == ESP_OK) {
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);
}
free(blob);
}
}
nvs_close(nvs);
return err;
}
static esp_err_t erase(const char *key)
{
nvs_handle nvs;
esp_err_t err = nvs_open_from_partition(settings_partition, current_namespace, NVS_READWRITE, &nvs);
if (err == ESP_OK) {
err = nvs_erase_key(nvs, key);
if (err == ESP_OK) {
err = nvs_commit(nvs);
if (err == ESP_OK) {
log_send_messaging(MESSAGING_INFO, "Value with key '%s' erased", key);
}
}
nvs_close(nvs);
}
return err;
}
static esp_err_t erase_all(const char *name)
{
nvs_handle nvs;
esp_err_t err = nvs_open_from_partition(settings_partition, current_namespace, NVS_READWRITE, &nvs);
if (err == ESP_OK) {
err = nvs_erase_all(nvs);
if (err == ESP_OK) {
err = nvs_commit(nvs);
}
}
log_send_messaging(MESSAGING_INFO, "Namespace '%s' was %s erased", name, (err == ESP_OK) ? "" : "not");
nvs_close(nvs);
return ESP_OK;
}
static int set_value(int argc, char **argv)
{
ESP_LOGD(TAG, "%s %u - Parsing keys ",__func__,__LINE__);
int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&set_args);
if (nerrors != 0) {
return 1;
}
const char *key = set_args.key->sval[0];
const char *type = set_args.type->sval[0];
const char *values = set_args.value->sval[0];
cmd_send_messaging(argv[0],MESSAGING_INFO, "Setting '%s' (type %s)", key,type);
esp_err_t err = set_value_in_nvs(key, type, values);
if (err != ESP_OK) {
cmd_send_messaging(argv[0],MESSAGING_ERROR, "%s", esp_err_to_name(err));
return 1;
}
return 0;
}
static int get_value(int argc, char **argv)
{
int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&get_args);
if (nerrors != 0) {
return 1;
}
const char *key = get_args.key->sval[0];
const char *type = get_args.type->sval[0];
esp_err_t err = get_value_from_nvs(key, type);
if (err != ESP_OK) {
cmd_send_messaging(argv[0],MESSAGING_ERROR, "%s", esp_err_to_name(err));
return 1;
}
return 0;
}
static int erase_value(int argc, char **argv)
{
int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&erase_args);
if (nerrors != 0) {
return 1;
}
const char *key = erase_args.key->sval[0];
esp_err_t err = erase(key);
if (err != ESP_OK) {
cmd_send_messaging(argv[0],MESSAGING_ERROR, "%s", esp_err_to_name(err));
return 1;
}
return 0;
}
static int erase_namespace(int argc, char **argv)
{
int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&erase_all_args);
if (nerrors != 0) {
return 1;
}
const char *name = erase_all_args.namespace->sval[0];
esp_err_t err = erase_all(name);
if (err != ESP_OK) {
cmd_send_messaging(argv[0],MESSAGING_ERROR, "%s", esp_err_to_name(err));
return 1;
}
return 0;
}
static int erase_network_manager(int argc, char **argv)
{
nvs_handle nvs;
esp_err_t err = nvs_open("config", NVS_READWRITE, &nvs);
if (err == ESP_OK) {
err = nvs_erase_all(nvs);
if (err == ESP_OK) {
err = nvs_commit(nvs);
}
}
nvs_close(nvs);
if (err != ESP_OK) {
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, "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)
{
nvs_type_t type = str_to_type(str_type);
nvs_iterator_t it = nvs_entry_find(part, NULL, type);
if (it == NULL) {
log_send_messaging(MESSAGING_ERROR, "No such enty was found");
return 1;
}
do {
nvs_entry_info_t info;
nvs_entry_info(it, &info);
it = nvs_entry_next(it);
log_send_messaging(MESSAGING_INFO, "namespace '%s', key '%s', type '%s' \n",
info.namespace_name, info.key, type_to_str(info.type));
} while (it != NULL);
return 0;
}
static int list_entries(int argc, char **argv)
{
list_args.partition->sval[0] = "";
list_args.namespace->sval[0] = "";
list_args.type->sval[0] = "";
int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&list_args);
if (nerrors != 0) {
return 1;
}
const char *part = list_args.partition->sval[0];
const char *name = list_args.namespace->sval[0];
const char *type = list_args.type->sval[0];
return list(part, name, type);
}
void register_nvs()
{
set_args.key = arg_str1(NULL, NULL, "<key>", "key of the value to be set");
set_args.type = arg_str1(NULL, NULL, "<type>", ARG_TYPE_STR);
set_args.value = arg_str1("v", "value", "<value>", "value to be stored");
set_args.end = arg_end(2);
get_args.key = arg_str1(NULL, NULL, "<key>", "key of the value to be read");
get_args.type = arg_str1(NULL, NULL, "<type>", ARG_TYPE_STR);
get_args.end = arg_end(2);
erase_args.key = arg_str1(NULL, NULL, "<key>", "key of the value to be erased");
erase_args.end = arg_end(2);
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);
list_args.end = arg_end(2);
const esp_console_cmd_t set_cmd = {
.command = "nvs_set",
.help = "Set variable in selected namespace. Blob type must be comma separated list of hex values. \n"
"Examples:\n"
" nvs_set VarName i32 -v 123 \n"
" nvs_set VarName srt -v YourString \n"
" nvs_set VarName blob -v 0123456789abcdef \n",
.hint = NULL,
.func = &set_value,
.argtable = &set_args
};
const esp_console_cmd_t get_cmd = {
.command = "nvs_get",
.help = "Get variable from selected namespace. \n"
"Example: nvs_get VarName i32",
.hint = NULL,
.func = &get_value,
.argtable = &get_args
};
const esp_console_cmd_t erase_cmd = {
.command = "nvs_erase",
.help = "Erase variable from current namespace",
.hint = NULL,
.func = &erase_value,
.argtable = &erase_args
};
const esp_console_cmd_t erase_namespace_cmd = {
.command = "nvs_erase_namespace",
.help = "Erases specified namespace",
.hint = NULL,
.func = &erase_namespace,
.argtable = &erase_all_args
};
const esp_console_cmd_t erase_config_cmd = {
.command = "wifi_erase_config",
.help = "Erases all stored access points from flash",
.hint = NULL,
.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
};
const esp_console_cmd_t list_entries_cmd = {
.command = "nvs_list",
.help = "List stored key-value pairs stored in NVS."
"Namespace and type can be specified to print only those key-value pairs.\n"
"Following command list variables stored inside 'nvs' partition, under namespace 'storage' with type uint32_t"
"Example: nvs_list nvs -n storage -t u32 \n",
.hint = NULL,
.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));
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
extern }
#endif

View File

@@ -1,22 +0,0 @@
/* Console example — declarations of command registration functions.
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#pragma once
#include "nvs_flash.h"
#ifdef __cplusplus
extern "C" {
#endif
// Register NVS functions
void register_nvs();
#ifdef __cplusplus
}
#endif

View File

@@ -26,7 +26,7 @@
#include "esp_partition.h"
#include "esp_ota_ops.h"
#include "platform_esp32.h"
#include "platform_config.h"
#include "Configurator.h"
#include "esp_sleep.h"
#include "messaging.h"
#include "platform_console.h"
@@ -42,25 +42,24 @@
#pragma message("Runtime stats disabled")
#endif
EXT_RAM_ATTR static struct {
struct arg_str *name;
struct arg_end *end;
} name_args;
EXT_RAM_ATTR static struct {
#if CONFIG_CSPOT_SINK
struct arg_lit *cspot;
#endif
struct arg_lit *btspeaker;
struct arg_lit *airplay;
struct arg_str *telnet;
#if WITH_TASKS_INFO
struct arg_lit *stats;
#endif
struct arg_end *end;
} set_services_args;
struct arg_str * device;
// AirPlay device name
struct arg_str * airplay;
// Spotify device name
struct arg_str * spotify;
// Bluetooth player name advertized
struct arg_str * bluetooth;
// Player name reported to the Logitech Media Server
struct arg_str * squeezelite;
// Wifi Access Point name
struct arg_str * wifi_ap_name;
struct arg_lit * all;
struct arg_end *end;
} names_args;
static const char * TAG = "cmd_system";
//static void register_setbtsource();
static void register_free();
static void register_setdevicename();
static void register_heap();
@@ -73,7 +72,7 @@ static void register_light_sleep();
#endif
static void register_factory_boot();
static void register_restart_ota();
static void register_set_services();
// static void register_set_services();
#if WITH_TASKS_INFO
static void register_tasks();
#endif
@@ -88,7 +87,7 @@ FILE * system_open_memstream(const char * cmdname,char **buf,size_t *buf_size){
void register_system()
{
register_set_services();
// register_set_services();
register_setdevicename();
register_free();
register_heap();
@@ -108,7 +107,7 @@ void register_system()
void simple_restart()
{
log_send_messaging(MESSAGING_WARNING,"Rebooting.");
if(!wait_for_commit()){
if(!configurator_waitcommit()){
log_send_messaging(MESSAGING_WARNING,"Unable to commit configuration. ");
}
vTaskDelay(750/ portTICK_PERIOD_MS);
@@ -320,17 +319,19 @@ static int heap_size(int argc, char **argv)
return 0;
}
cJSON * setdevicename_cb(){
char * default_host_name = config_alloc_get_str("host_name",NULL,"Squeezelite");
// char * default_host_name = config_alloc_get_str("host_name",NULL,"Squeezelite");
cJSON * values = cJSON_CreateObject();
cJSON_AddStringToObject(values,"name",default_host_name);
free(default_host_name);
// cJSON_AddStringToObject(values,"name",default_host_name);
// free(default_host_name);
// TODO: Add support for the commented code")
return values;
}
static int setnamevar(char * nvsname, FILE *f, char * value){
esp_err_t err=ESP_OK;
if((err=config_set_value(NVS_TYPE_STR, nvsname, value))!=ESP_OK){
fprintf(f,"Unable to set %s=%s. %s\n",nvsname,value,esp_err_to_name(err));
}
// if((err=config_set_value(NVS_TYPE_STR, nvsname, value))!=ESP_OK){
// fprintf(f,"Unable to set %s=%s. %s\n",nvsname,value,esp_err_to_name(err));
// }
// TODO: Add support for the commented code")
return err==ESP_OK?0:1;
}
typedef enum {
@@ -339,140 +340,147 @@ typedef enum {
} scanstate_t;
int set_cspot_player_name(FILE * f,const char * name){
int ret=0;
cJSON * cspot_config = config_alloc_get_cjson("cspot_config");
if(cspot_config==NULL){
fprintf(f,"Unable to get cspot_config\n");
return 1;
}
cJSON * player_name = cJSON_GetObjectItemCaseSensitive(cspot_config,"deviceName");
if(player_name==NULL){
fprintf(f,"Unable to get deviceName\n");
ret=1;
}
if(strcmp(player_name->valuestring,name)==0){
fprintf(f,"CSpot device name not changed.\n");
ret=0;
}
else{
cJSON_SetValuestring(player_name,name);
if(setnamevar("cspot_config",f,cJSON_Print(cspot_config))!=0){
fprintf(f,"Unable to set cspot_config\n");
ret=1;
}
else{
fprintf(f,"CSpot device name set to %s\n",name);
}
}
cJSON_Delete(cspot_config);
// cJSON * cspot_config = config_alloc_get_cjson("cspot_config");
// if(cspot_config==NULL){
// fprintf(f,"Unable to get cspot_config\n");
// return 1;
// }
// cJSON * player_name = cJSON_GetObjectItemCaseSensitive(cspot_config,"deviceName");
// if(player_name==NULL){
// fprintf(f,"Unable to get deviceName\n");
// ret=1;
// }
// if(strcmp(player_name->valuestring,name)==0){
// fprintf(f,"CSpot device name not changed.\n");
// ret=0;
// }
// else{
// cJSON_SetValuestring(player_name,name);
// if(setnamevar("cspot_config",f,cJSON_Print(cspot_config))!=0){
// fprintf(f,"Unable to set cspot_config\n");
// ret=1;
// }
// else{
// fprintf(f,"CSpot device name set to %s\n",name);
// }
// }
// cJSON_Delete(cspot_config);
// TODO: Add support for the commented code")
return ret;
}
int set_squeezelite_player_name(FILE * f,const char * name){
char * nvs_config= config_alloc_get(NVS_TYPE_STR, "autoexec1");
char **argv = NULL;
esp_err_t err=ESP_OK;
int nerrors=0;
bool bFoundParm=false;
scanstate_t state=SCANNING;
char * newCommandLine = NULL;
char * parm = " -n ";
char * cleaned_name = strdup(name);
for(char * p=cleaned_name;*p!='\0';p++){
if(*p == ' '){
*p='_'; // no spaces allowed
}
}
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_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;
}
size_t argc = esp_console_split_argv(nvs_config, argv,22);
for(int i=0;i<argc;i++) {
if(i>0){
strcat(newCommandLine," ");
}
switch (state)
{
case SCANNING:
strcat(newCommandLine,argv[i]);
if(strcasecmp(argv[i],"--name")==0 || strcasecmp(argv[i],"-n")==0 ){
state = PROCESSING_NAME;
}
break;
case PROCESSING_NAME:
bFoundParm=true;
strcat(newCommandLine,cleaned_name);
state = SCANNING;
break;
int nerrors=0;
// TODO: Add support for the commented code")
// char * nvs_config= config_alloc_get(NVS_TYPE_STR, "autoexec1");
// char **argv = NULL;
// esp_err_t err=ESP_OK;
// bool bFoundParm=false;
// scanstate_t state=SCANNING;
// char * newCommandLine = NULL;
// char * parm = " -n ";
// char * cleaned_name = strdup(name);
// for(char * p=cleaned_name;*p!='\0';p++){
// if(*p == ' '){
// *p='_'; // no spaces allowed
// }
// }
// 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_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;
// }
// size_t argc = esp_console_split_argv(nvs_config, argv,22);
// for(int i=0;i<argc;i++) {
// if(i>0){
// strcat(newCommandLine," ");
// }
// switch (state)
// {
// case SCANNING:
// strcat(newCommandLine,argv[i]);
// if(strcasecmp(argv[i],"--name")==0 || strcasecmp(argv[i],"-n")==0 ){
// state = PROCESSING_NAME;
// }
// break;
// case PROCESSING_NAME:
// bFoundParm=true;
// strcat(newCommandLine,cleaned_name);
// state = SCANNING;
// break;
default:
break;
}
}
if(!bFoundParm){
strcat(newCommandLine,parm);
strcat(newCommandLine,name);
}
fprintf(f,"Squeezelite player name changed to %s\n",newCommandLine);
if((err=config_set_value(NVS_TYPE_STR, "autoexec1",newCommandLine))!=ESP_OK){
nerrors++;
fprintf(f,"Failed updating squeezelite command. %s", esp_err_to_name(err));
}
// default:
// break;
// }
// }
// if(!bFoundParm){
// strcat(newCommandLine,parm);
// strcat(newCommandLine,name);
// }
// fprintf(f,"Squeezelite player name changed to %s\n",newCommandLine);
// if((err=config_set_value(NVS_TYPE_STR, "autoexec1",newCommandLine))!=ESP_OK){
// nerrors++;
// fprintf(f,"Failed updating squeezelite command. %s", esp_err_to_name(err));
// }
}
// }
FREE_AND_NULL(nvs_config);
FREE_AND_NULL(argv);
free(cleaned_name);
// FREE_AND_NULL(nvs_config);
// FREE_AND_NULL(argv);
// free(cleaned_name);
return nerrors;
}
static int setdevicename(int argc, char **argv)
{
char * name = NULL;
int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&name_args);
bool changed = false;
int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&names_args);
if (nerrors != 0) {
return 1;
}
/* Check "--name" option */
if (name_args.name->count) {
name=strdup_psram(name_args.name->sval[0]);
}
if (names_args.device->count >0){
changed = changed | configurator_set_string(&sys_Names_msg,sys_Names_device_tag, &platform->names,names_args.device->sval[0]);
}
else {
cmd_send_messaging(argv[0],MESSAGING_ERROR,"Name must be specified.");
ESP_LOGE(TAG,"Device name must be specified");
return 1;
}
if (names_args.airplay->count >0){
changed = changed | configurator_set_string(&sys_Names_msg,sys_Names_airplay_tag, &platform->names,names_args.airplay->sval[0]);
}
if (names_args.bluetooth->count >0){
changed = changed | configurator_set_string(&sys_Names_msg,sys_Names_bluetooth_tag, &platform->names,names_args.bluetooth->sval[0]);
}
if (names_args.spotify->count >0){
changed = changed | configurator_set_string(&sys_Names_msg,sys_Names_spotify_tag, &platform->names,names_args.spotify->sval[0]);
}
if (names_args.squeezelite->count >0){
changed = changed | configurator_set_string(&sys_Names_msg,sys_Names_squeezelite_tag, &platform->names,names_args.squeezelite->sval[0]);
}
if (names_args.wifi_ap_name->count >0){
changed = changed | configurator_set_string(&sys_Names_msg,sys_Names_wifi_ap_name_tag, &platform->names,names_args.wifi_ap_name->sval[0]);
}
if (names_args.all->count >0){
ESP_LOGI(TAG,"Setting all names to %s", platform->names.device);
changed = changed | configurator_set_string(&sys_Names_msg,sys_Names_airplay_tag, &platform->names,platform->names.device);
changed = changed | configurator_set_string(&sys_Names_msg,sys_Names_bluetooth_tag, &platform->names,platform->names.device);
changed = changed | configurator_set_string(&sys_Names_msg,sys_Names_spotify_tag, &platform->names,platform->names.device);
changed = changed | configurator_set_string(&sys_Names_msg,sys_Names_squeezelite_tag, &platform->names,platform->names.device);
changed = changed | configurator_set_string(&sys_Names_msg,sys_Names_wifi_ap_name_tag, &platform->names,platform->names.device);
}
if(changed){
ESP_LOGI(TAG,"Found change(s). Saving");
configurator_raise_changed();
}
else {
ESP_LOGW(TAG,"No change detected.");
}
char *buf = NULL;
size_t buf_size = 0;
FILE *f = system_open_memstream(argv[0],&buf, &buf_size);
if (f == NULL) {
return 1;
}
nerrors+=setnamevar("a2dp_dev_name", f, name);
nerrors+=setnamevar("airplay_name", f, name);
nerrors+=setnamevar("ap_ssid", f, name);
nerrors+=setnamevar("bt_name", f, name);
nerrors+=setnamevar("host_name", f, name);
nerrors+=set_squeezelite_player_name(f, name);
nerrors+=set_cspot_player_name(f, name);
if(nerrors==0){
fprintf(f,"Device name changed to %s\n",name);
}
if(!nerrors ){
fprintf(f,"Done.\n");
}
FREE_AND_NULL(name);
fflush (f);
cmd_send_messaging(argv[0],nerrors>0?MESSAGING_ERROR:MESSAGING_INFO,"%s", buf);
fclose(f);
FREE_AND_NULL(buf);
return nerrors;
}
@@ -506,18 +514,23 @@ static void register_dump_heap()
static void register_setdevicename()
{
char * default_host_name = config_alloc_get_str("host_name",NULL,"Squeezelite");
name_args.name = arg_str0("n", "name", default_host_name, "New Name");
name_args.end = arg_end(8);
char * default_host_name = platform->names.device;
names_args.device = arg_str0("n", "device", default_host_name, "New Name");
names_args.airplay = arg_str0("a", "airplay", default_host_name, "New Airplay Device Name");
names_args.bluetooth = arg_str0("b", "bt", default_host_name, "New Bluetooth Device Name");
names_args.spotify = arg_str0("s", "spotify", default_host_name, "New Spotify Device Name");
names_args.squeezelite = arg_str0("l", "squeezelite", default_host_name, "New Squeezelite Player Name");
names_args.wifi_ap_name = arg_str0("w", "wifiap", default_host_name, "New Wifi AP Name");
names_args.all = arg_lit0(NULL, "all", "Set all names to device name");
names_args.end = arg_end(2);
const esp_console_cmd_t set_name= {
.command = CFG_TYPE_SYST("name"),
.help="Device Name",
.hint = NULL,
.func = &setdevicename,
.argtable = &name_args
.argtable = &names_args
};
cmd_to_json_with_cb(&set_name,&setdevicename_cb);
ESP_ERROR_CHECK(esp_console_cmd_register(&set_name));
}
/** 'tasks' command prints the list of tasks and related information */
@@ -625,123 +638,124 @@ static void register_deep_sleep()
#endif
static int enable_disable(FILE * f,char * nvs_name, struct arg_lit *arg){
esp_err_t err = config_set_value(NVS_TYPE_STR, nvs_name, arg->count>0?"Y":"N");
const char * name = arg->hdr.longopts?arg->hdr.longopts:arg->hdr.glossary;
esp_err_t err = ESP_OK;
// err= config_set_value(NVS_TYPE_STR, nvs_name, arg->count>0?"Y":"N");
// const char * name = arg->hdr.longopts?arg->hdr.longopts:arg->hdr.glossary;
if(err!=ESP_OK){
fprintf(f,"Error %s %s. %s\n",arg->count>0?"Enabling":"Disabling", name, esp_err_to_name(err));
}
else {
fprintf(f,"%s %s\n",arg->count>0?"Enabled":"Disabled",name);
}
// if(err!=ESP_OK){
// fprintf(f,"Error %s %s. %s\n",arg->count>0?"Enabling":"Disabling", name, esp_err_to_name(err));
// }
// else {
// fprintf(f,"%s %s\n",arg->count>0?"Enabled":"Disabled",name);
// }
return err;
}
static int do_set_services(int argc, char **argv)
{
esp_err_t err = ESP_OK;
int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&set_services_args);
if (nerrors != 0) {
return 1;
}
char *buf = NULL;
size_t buf_size = 0;
FILE *f = system_open_memstream(argv[0],&buf, &buf_size);
if (f == NULL) {
return 1;
}
// static int do_set_services(int argc, char **argv)
// {
// esp_err_t err = ESP_OK;
// int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&set_services_args);
// if (nerrors != 0) {
// return 1;
// }
// char *buf = NULL;
// size_t buf_size = 0;
// FILE *f = system_open_memstream(argv[0],&buf, &buf_size);
// if (f == NULL) {
// return 1;
// }
nerrors += enable_disable(f,"enable_airplay",set_services_args.airplay);
nerrors += enable_disable(f,"enable_bt_sink",set_services_args.btspeaker);
#if CONFIG_CSPOT_SINK
nerrors += enable_disable(f,"enable_cspot",set_services_args.cspot);
#endif
// nerrors += enable_disable(f,"enable_airplay",set_services_args.airplay);
// nerrors += enable_disable(f,"enable_bt_sink",set_services_args.btspeaker);
// #if CONFIG_CSPOT_SINK
// nerrors += enable_disable(f,"enable_cspot",set_services_args.cspot);
// #endif
if(set_services_args.telnet->count>0){
if(strcasecmp(set_services_args.telnet->sval[0],"Disabled") == 0){
err = config_set_value(NVS_TYPE_STR, "telnet_enable", "N");
}
else if(strcasecmp(set_services_args.telnet->sval[0],"Telnet Only") == 0){
err = config_set_value(NVS_TYPE_STR, "telnet_enable", "Y");
}
else if(strcasecmp(set_services_args.telnet->sval[0],"Telnet and Serial") == 0){
err = config_set_value(NVS_TYPE_STR, "telnet_enable", "D");
}
if(err!=ESP_OK){
nerrors++;
fprintf(f,"Error setting telnet to %s. %s\n",set_services_args.telnet->sval[0], esp_err_to_name(err));
}
else {
fprintf(f,"Telnet service changed to %s\n",set_services_args.telnet->sval[0]);
}
}
// if(set_services_args.telnet->count>0){
// // if(strcasecmp(set_services_args.telnet->sval[0],"Disabled") == 0){
// // err = config_set_value(NVS_TYPE_STR, "telnet_enable", "N");
// // }
// // else if(strcasecmp(set_services_args.telnet->sval[0],"Telnet Only") == 0){
// // err = config_set_value(NVS_TYPE_STR, "telnet_enable", "Y");
// // }
// // else if(strcasecmp(set_services_args.telnet->sval[0],"Telnet and Serial") == 0){
// // err = config_set_value(NVS_TYPE_STR, "telnet_enable", "D");
// // }
// // TODO: Add support for the commented code")
// if(err!=ESP_OK){
// nerrors++;
// fprintf(f,"Error setting telnet to %s. %s\n",set_services_args.telnet->sval[0], esp_err_to_name(err));
// }
// else {
// fprintf(f,"Telnet service changed to %s\n",set_services_args.telnet->sval[0]);
// }
// }
#if WITH_TASKS_INFO
nerrors += enable_disable(f,"stats",set_services_args.stats);
#endif
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;
}
// #if WITH_TASKS_INFO
// nerrors += enable_disable(f,"stats",set_services_args.stats);
// #endif
// 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;
// }
cJSON * set_services_cb(){
cJSON * values = cJSON_CreateObject();
char * p=NULL;
console_set_bool_parameter(values,"enable_bt_sink",set_services_args.btspeaker);
console_set_bool_parameter(values,"enable_airplay",set_services_args.airplay);
#if CONFIG_CSPOT_SINK
console_set_bool_parameter(values,"enable_cspot",set_services_args.cspot);
#endif
#if WITH_TASKS_INFO
console_set_bool_parameter(values,"stats",set_services_args.stats);
#endif
if ((p = config_alloc_get(NVS_TYPE_STR, "telnet_enable")) != NULL) {
if(strcasestr("YX",p)!=NULL){
cJSON_AddStringToObject(values,set_services_args.telnet->hdr.longopts,"Telnet Only");
}
else if(strcasestr("D",p)!=NULL){
cJSON_AddStringToObject(values,set_services_args.telnet->hdr.longopts,"Telnet and Serial");
}
else {
cJSON_AddStringToObject(values,set_services_args.telnet->hdr.longopts,"Disabled");
}
#if defined(CONFIG_WITH_METRICS)
metrics_add_feature_variant("telnet",p);
#endif
FREE_AND_NULL(p);
}
// cJSON * set_services_cb(){
// cJSON * values = cJSON_CreateObject();
// char * p=NULL;
// console_set_bool_parameter(values,"enable_bt_sink",set_services_args.btspeaker);
// console_set_bool_parameter(values,"enable_airplay",set_services_args.airplay);
// #if CONFIG_CSPOT_SINK
// console_set_bool_parameter(values,"enable_cspot",set_services_args.cspot);
// #endif
// #if WITH_TASKS_INFO
// console_set_bool_parameter(values,"stats",set_services_args.stats);
// #endif
// // if ((p = config_alloc_get(NVS_TYPE_STR, "telnet_enable")) != NULL) {
// // if(strcasestr("YX",p)!=NULL){
// // cJSON_AddStringToObject(values,set_services_args.telnet->hdr.longopts,"Telnet Only");
// // }
// // else if(strcasestr("D",p)!=NULL){
// // cJSON_AddStringToObject(values,set_services_args.telnet->hdr.longopts,"Telnet and Serial");
// // }
// // else {
// // cJSON_AddStringToObject(values,set_services_args.telnet->hdr.longopts,"Disabled");
// // }
// // #if defined(CONFIG_WITH_METRICS)
// // metrics_add_feature_variant("telnet",p);
// // #endif
// // FREE_AND_NULL(p);
// // }
// // TODO: Add support for the commented code")
// return values;
// }
return values;
}
static void register_set_services(){
set_services_args.airplay = arg_lit0(NULL, "AirPlay", "AirPlay");
#if CONFIG_CSPOT_SINK
set_services_args.cspot = arg_lit0(NULL, "cspot", "Spotify (cspot)");
#endif
set_services_args.btspeaker = arg_lit0(NULL, "BT_Speaker", "Bluetooth Speaker");
set_services_args.telnet= arg_str0("t", "telnet","Disabled|Telnet Only|Telnet and Serial","Telnet server. Use only for troubleshooting");
#if WITH_TASKS_INFO
set_services_args.stats= arg_lit0(NULL, "stats", "System Statistics. Use only for troubleshooting");
#endif
set_services_args.end=arg_end(2);
const esp_console_cmd_t cmd = {
.command = CFG_TYPE_SYST("services"),
.help = "Services",
.argtable = &set_services_args,
.hint = NULL,
.func = &do_set_services,
};
cmd_to_json_with_cb(&cmd,&set_services_cb);
ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
}
// static void register_set_services(){
// set_services_args.airplay = arg_lit0(NULL, "AirPlay", "AirPlay");
// #if CONFIG_CSPOT_SINK
// set_services_args.cspot = arg_lit0(NULL, "cspot", "Spotify (cspot)");
// #endif
// set_services_args.btspeaker = arg_lit0(NULL, "BT_Speaker", "Bluetooth Speaker");
// set_services_args.telnet= arg_str0("t", "telnet","Disabled|Telnet Only|Telnet and Serial","Telnet server. Use only for troubleshooting");
// #if WITH_TASKS_INFO
// set_services_args.stats= arg_lit0(NULL, "stats", "System Statistics. Use only for troubleshooting");
// #endif
// set_services_args.end=arg_end(2);
// const esp_console_cmd_t cmd = {
// .command = CFG_TYPE_SYST("services"),
// .help = "Services",
// .argtable = &set_services_args,
// .hint = NULL,
// .func = &do_set_services,
// };
// cmd_to_json_with_cb(&cmd,&set_services_cb);
// ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
// }
#if CONFIG_WITH_CONFIG_UI
static struct {

View File

@@ -24,7 +24,8 @@
#include "platform_esp32.h"
#include "cmd_decl.h"
#include "trace.h"
#include "platform_config.h"
// #include "Configurator.h"
#pragma message("fixme: search for TODO below")
#include "telnet.h"
#include "tools.h"
#if defined(CONFIG_WITH_METRICS)
@@ -38,7 +39,7 @@ static void * console_thread();
void console_start();
static const char * TAG = "console";
extern bool bypass_network_manager;
extern void register_squeezelite();
extern void launchsqueezelite();
static EXT_RAM_ATTR QueueHandle_t uart_queue;
static EXT_RAM_ATTR struct {
@@ -92,16 +93,17 @@ void console_set_bool_parameter(cJSON * root,char * nvs_name, struct arg_lit *ar
ESP_LOGE(TAG,"Invalid json parameter. Cannot set %s from %s",arg->hdr.longopts?arg->hdr.longopts:arg->hdr.glossary,nvs_name);
return;
}
if ((p = config_alloc_get(NVS_TYPE_STR, nvs_name)) != NULL) {
enabled = strcmp(p,"1") == 0 || strcasecmp(p,"y") == 0;
cJSON_AddBoolToObject(root,arg->hdr.longopts,enabled);
FREE_AND_NULL(p);
}
#if defined(CONFIG_WITH_METRICS)
if(enabled){
metrics_add_feature(nvs_name,"enabled");
}
#endif
// if ((p = config_alloc_get(NVS_TYPE_STR, nvs_name)) != NULL) {
// enabled = strcmp(p,"1") == 0 || strcasecmp(p,"y") == 0;
// cJSON_AddBoolToObject(root,arg->hdr.longopts,enabled);
// FREE_AND_NULL(p);
// }
// #if defined(CONFIG_WITH_METRICS)
// if(enabled){
// metrics_add_feature(nvs_name,"enabled");
// }
// #endif
// TODO: Add support for the commented code
}
struct arg_end *getParmsEnd(struct arg_hdr * * argtable){
@@ -215,48 +217,52 @@ void process_autoexec(){
char autoexec_name[21]={0};
char * autoexec_value=NULL;
uint8_t autoexec_flag=0;
// TODO: Add support for the commented code
void * cmd = run_command;
char * str_flag = config_alloc_get(NVS_TYPE_STR, "autoexec");
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.");
}
if(str_flag !=NULL ){
autoexec_flag=atoi(str_flag);
ESP_LOGI(TAG,"autoexec is set to %s auto-process", autoexec_flag>0?"perform":"skip");
if(autoexec_flag == 1) {
do {
snprintf(autoexec_name,sizeof(autoexec_name)-1,"autoexec%u",i++);
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_network_manager && strstr(autoexec_value, "join ")!=NULL ){
ESP_LOGW(TAG,"Ignoring wifi join command.");
}
else if(is_recovery_running && !strstr(autoexec_value, "squeezelite " ) ){
ESP_LOGW(TAG,"Ignoring command. ");
}
else {
ESP_LOGI(TAG,"Running command %s = %s", autoexec_name, autoexec_value);
run_command(autoexec_value);
}
ESP_LOGD(TAG,"Freeing memory for command %s name", autoexec_name);
free(autoexec_value);
}
else {
ESP_LOGD(TAG,"No matching command found for name %s", autoexec_name);
break;
}
} while(1);
}
free(str_flag);
}
else
{
ESP_LOGD(TAG,"No matching command found for name autoexec.");
}
// char * str_flag = config_alloc_get(NVS_TYPE_STR, "autoexec");
// 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.");
// }
// if(str_flag !=NULL ){
// autoexec_flag=atoi(str_flag);
// ESP_LOGI(TAG,"autoexec is set to %s auto-process", autoexec_flag>0?"perform":"skip");
// if(autoexec_flag == 1) {
// do {
// snprintf(autoexec_name,sizeof(autoexec_name)-1,"autoexec%u",i++);
// 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_network_manager && strstr(autoexec_value, "join ")!=NULL ){
// ESP_LOGW(TAG,"Ignoring wifi join command.");
// }
// else if(is_recovery_running && !strstr(autoexec_value, "squeezelite " ) ){
// ESP_LOGW(TAG,"Ignoring command. ");
// }
// else {
// ESP_LOGI(TAG,"Running command %s = %s", autoexec_name, autoexec_value);
// run_command(autoexec_value);
// }
// ESP_LOGD(TAG,"Freeing memory for command %s name", autoexec_name);
// free(autoexec_value);
// }
// else {
// ESP_LOGD(TAG,"No matching command found for name %s", autoexec_name);
// break;
// }
// } while(1);
// }
// free(str_flag);
// }
// else
// {
// ESP_LOGD(TAG,"No matching command found for name autoexec.");
// }
// TODO: Add support for the commented code
}
static ssize_t stdin_read(int fd, void* data, size_t size) {
@@ -373,11 +379,7 @@ void console_start() {
MEMTRACE_PRINT_DELTA_MESSAGE("Registering wifi commands");
register_wifi();
if(!is_recovery_running){
MEMTRACE_PRINT_DELTA_MESSAGE("Registering squeezelite commands");
register_squeezelite();
}
else {
if(is_recovery_running){
MEMTRACE_PRINT_DELTA_MESSAGE("Registering recovery commands");
register_ota_cmd();
}

View File

@@ -22,7 +22,6 @@ typedef cJSON * parm_values_fn_t(void);
esp_err_t cmd_to_json(const esp_console_cmd_t *cmd);
esp_err_t cmd_to_json_with_cb(const esp_console_cmd_t *cmd, parm_values_fn_t parm_values_fn);
int arg_parse_msg(int argc, char **argv, struct arg_hdr ** args);
void console_set_bool_parameter(cJSON * root,char * nvs_name, struct arg_lit *arg);
cJSON * get_cmd_list();
#ifdef __cplusplus
}

View File

@@ -11,7 +11,8 @@
#include "unity.h"
#include "platform_console.h"
#include "platform_esp32.h"
#include "platform_config.h"
// #include "Configurator.h"
#pragma message("fixme: search for TODO below")
#include "string.h"
struct arg_lit *arglit;
struct arg_int *argint;