enhancement: new "config" module to access configuration in RAM

This is to allow moving some tasks/stack memory to SPIRAM, saving on
precious IRAM. HTTP server should also be more responsive.
This commit is contained in:
Sebastien
2019-11-06 23:31:13 -05:00
parent 86f0d4c7ea
commit cdbb198d8a
38 changed files with 1219 additions and 510 deletions

View File

@@ -143,4 +143,4 @@ CONFIG_DEFAULT_AP_PASSWORD="squeezelite"
CONFIG_DEFAULT_AP_IP="192.168.4.1" CONFIG_DEFAULT_AP_IP="192.168.4.1"
CONFIG_DEFAULT_AP_GATEWAY="192.168.4.1" CONFIG_DEFAULT_AP_GATEWAY="192.168.4.1"
CONFIG_DEFAULT_AP_NETMASK="255.255.255.0" CONFIG_DEFAULT_AP_NETMASK="255.255.255.0"
CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info" CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info -s %s"

View File

@@ -116,7 +116,7 @@ CONFIG_DEFAULT_AP_GATEWAY="192.168.4.1"
CONFIG_DEFAULT_AP_NETMASK="255.255.255.0" CONFIG_DEFAULT_AP_NETMASK="255.255.255.0"
CONFIG_DEFAULT_AP_MAX_CONNECTIONS=4 CONFIG_DEFAULT_AP_MAX_CONNECTIONS=4
CONFIG_DEFAULT_AP_BEACON_INTERVAL=100 CONFIG_DEFAULT_AP_BEACON_INTERVAL=100
CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info" CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info -s %s"
CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y

View File

@@ -116,7 +116,7 @@ CONFIG_DEFAULT_AP_GATEWAY="192.168.4.1"
CONFIG_DEFAULT_AP_NETMASK="255.255.255.0" CONFIG_DEFAULT_AP_NETMASK="255.255.255.0"
CONFIG_DEFAULT_AP_MAX_CONNECTIONS=4 CONFIG_DEFAULT_AP_MAX_CONNECTIONS=4
CONFIG_DEFAULT_AP_BEACON_INTERVAL=100 CONFIG_DEFAULT_AP_BEACON_INTERVAL=100
CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info" CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info -s %s"
CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y

View File

@@ -139,4 +139,4 @@ CONFIG_DEFAULT_AP_PASSWORD="squeezelite"
CONFIG_DEFAULT_AP_IP="192.168.4.1" CONFIG_DEFAULT_AP_IP="192.168.4.1"
CONFIG_DEFAULT_AP_GATEWAY="192.168.4.1" CONFIG_DEFAULT_AP_GATEWAY="192.168.4.1"
CONFIG_DEFAULT_AP_NETMASK="255.255.255.0" CONFIG_DEFAULT_AP_NETMASK="255.255.255.0"
CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info" CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info -s %s"

View File

@@ -116,7 +116,7 @@ CONFIG_DEFAULT_AP_GATEWAY="192.168.4.1"
CONFIG_DEFAULT_AP_NETMASK="255.255.255.0" CONFIG_DEFAULT_AP_NETMASK="255.255.255.0"
CONFIG_DEFAULT_AP_MAX_CONNECTIONS=4 CONFIG_DEFAULT_AP_MAX_CONNECTIONS=4
CONFIG_DEFAULT_AP_BEACON_INTERVAL=100 CONFIG_DEFAULT_AP_BEACON_INTERVAL=100
CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info" CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info -s %s"
CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y

View File

@@ -116,7 +116,7 @@ CONFIG_DEFAULT_AP_GATEWAY="192.168.4.1"
CONFIG_DEFAULT_AP_NETMASK="255.255.255.0" CONFIG_DEFAULT_AP_NETMASK="255.255.255.0"
CONFIG_DEFAULT_AP_MAX_CONNECTIONS=4 CONFIG_DEFAULT_AP_MAX_CONNECTIONS=4
CONFIG_DEFAULT_AP_BEACON_INTERVAL=100 CONFIG_DEFAULT_AP_BEACON_INTERVAL=100
CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info" CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info -s %s"
CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y

View File

@@ -104,7 +104,7 @@ CONFIG_DEFAULT_AP_GATEWAY="192.168.4.1"
CONFIG_DEFAULT_AP_NETMASK="255.255.255.0" CONFIG_DEFAULT_AP_NETMASK="255.255.255.0"
CONFIG_DEFAULT_AP_MAX_CONNECTIONS=4 CONFIG_DEFAULT_AP_MAX_CONNECTIONS=4
CONFIG_DEFAULT_AP_BEACON_INTERVAL=100 CONFIG_DEFAULT_AP_BEACON_INTERVAL=100
CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info" CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info -s %s"
CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y

View File

@@ -104,7 +104,7 @@ CONFIG_DEFAULT_AP_GATEWAY="192.168.4.1"
CONFIG_DEFAULT_AP_NETMASK="255.255.255.0" CONFIG_DEFAULT_AP_NETMASK="255.255.255.0"
CONFIG_DEFAULT_AP_MAX_CONNECTIONS=4 CONFIG_DEFAULT_AP_MAX_CONNECTIONS=4
CONFIG_DEFAULT_AP_BEACON_INTERVAL=100 CONFIG_DEFAULT_AP_BEACON_INTERVAL=100
CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info" CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info -s %s"
CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y

View File

@@ -71,7 +71,7 @@ CONFIG_DEFAULT_AP_GATEWAY="192.168.4.1"
CONFIG_DEFAULT_AP_NETMASK="255.255.255.0" CONFIG_DEFAULT_AP_NETMASK="255.255.255.0"
CONFIG_DEFAULT_AP_MAX_CONNECTIONS=4 CONFIG_DEFAULT_AP_MAX_CONNECTIONS=4
CONFIG_DEFAULT_AP_BEACON_INTERVAL=100 CONFIG_DEFAULT_AP_BEACON_INTERVAL=100
CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info" CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info -s %s"
CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y
CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y

View File

@@ -137,4 +137,4 @@ CONFIG_DEFAULT_AP_PASSWORD="squeezelite"
CONFIG_DEFAULT_AP_IP="192.168.4.1" CONFIG_DEFAULT_AP_IP="192.168.4.1"
CONFIG_DEFAULT_AP_GATEWAY="192.168.4.1" CONFIG_DEFAULT_AP_GATEWAY="192.168.4.1"
CONFIG_DEFAULT_AP_NETMASK="255.255.255.0" CONFIG_DEFAULT_AP_NETMASK="255.255.255.0"
CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info" CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info -s %s"

View File

@@ -115,7 +115,7 @@ CONFIG_DEFAULT_AP_GATEWAY="192.168.4.1"
CONFIG_DEFAULT_AP_NETMASK="255.255.255.0" CONFIG_DEFAULT_AP_NETMASK="255.255.255.0"
CONFIG_DEFAULT_AP_MAX_CONNECTIONS=4 CONFIG_DEFAULT_AP_MAX_CONNECTIONS=4
CONFIG_DEFAULT_AP_BEACON_INTERVAL=100 CONFIG_DEFAULT_AP_BEACON_INTERVAL=100
CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info" CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info -s %s"
CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y

View File

@@ -112,7 +112,7 @@ CONFIG_DEFAULT_AP_GATEWAY="192.168.4.1"
CONFIG_DEFAULT_AP_NETMASK="255.255.255.0" CONFIG_DEFAULT_AP_NETMASK="255.255.255.0"
CONFIG_DEFAULT_AP_MAX_CONNECTIONS=4 CONFIG_DEFAULT_AP_MAX_CONNECTIONS=4
CONFIG_DEFAULT_AP_BEACON_INTERVAL=100 CONFIG_DEFAULT_AP_BEACON_INTERVAL=100
CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info" CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info -s %s"
CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y

View File

@@ -132,7 +132,7 @@ CONFIG_DEFAULT_AP_GATEWAY="192.168.4.1"
CONFIG_DEFAULT_AP_NETMASK="255.255.255.0" CONFIG_DEFAULT_AP_NETMASK="255.255.255.0"
CONFIG_DEFAULT_AP_MAX_CONNECTIONS=4 CONFIG_DEFAULT_AP_MAX_CONNECTIONS=4
CONFIG_DEFAULT_AP_BEACON_INTERVAL=100 CONFIG_DEFAULT_AP_BEACON_INTERVAL=100
CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info" CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info -s %s"
CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y

View File

@@ -103,7 +103,7 @@ CONFIG_DEFAULT_AP_GATEWAY="192.168.4.1"
CONFIG_DEFAULT_AP_NETMASK="255.255.255.0" CONFIG_DEFAULT_AP_NETMASK="255.255.255.0"
CONFIG_DEFAULT_AP_MAX_CONNECTIONS=4 CONFIG_DEFAULT_AP_MAX_CONNECTIONS=4
CONFIG_DEFAULT_AP_BEACON_INTERVAL=100 CONFIG_DEFAULT_AP_BEACON_INTERVAL=100
CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info" CONFIG_DEFAULT_COMMAND_LINE="squeezelite -o I2S -b 500:2000 -d all=info -s %s"
CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y

View File

@@ -91,7 +91,7 @@ static nvs_type_t str_to_type(const char *type)
return NVS_TYPE_ANY; return NVS_TYPE_ANY;
} }
static const char *type_to_str(nvs_type_t type) const char *type_to_str(nvs_type_t type)
{ {
for (int i = 0; i < TYPE_STR_PAIR_SIZE; i++) { for (int i = 0; i < TYPE_STR_PAIR_SIZE; i++) {
const type_str_pair_t *p = &type_str_pair[i]; const type_str_pair_t *p = &type_str_pair[i];

View File

@@ -7,6 +7,7 @@
CONDITIONS OF ANY KIND, either express or implied. CONDITIONS OF ANY KIND, either express or implied.
*/ */
#pragma once #pragma once
#include "nvs_flash.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@@ -14,7 +15,7 @@ extern "C" {
// Register NVS functions // Register NVS functions
void register_nvs(); void register_nvs();
const char *type_to_str(nvs_type_t type);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -27,6 +27,7 @@
#include "esp_partition.h" #include "esp_partition.h"
#include "esp_ota_ops.h" #include "esp_ota_ops.h"
#include "platform_esp32.h" #include "platform_esp32.h"
#include "nvs_utilities.h"
#ifdef CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS #ifdef CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS
#define WITH_TASKS_INFO 1 #define WITH_TASKS_INFO 1
@@ -126,6 +127,9 @@ esp_err_t guided_boot(esp_partition_subtype_t partition_subtype)
} }
esp_partition_iterator_release(it); esp_partition_iterator_release(it);
if(bFound) { if(bFound) {
if(!wait_for_commit()){
ESP_LOGW(TAG,"Unable to commit configuration. ");
}
ESP_LOGI(TAG, "Restarting!."); ESP_LOGI(TAG, "Restarting!.");
esp_restart(); esp_restart();
} }
@@ -136,6 +140,9 @@ esp_err_t guided_boot(esp_partition_subtype_t partition_subtype)
static int restart(int argc, char **argv) static int restart(int argc, char **argv)
{ {
if(!wait_for_commit()){
ESP_LOGW(TAG,"Unable to commit configuration. ");
}
ESP_LOGW(TAG, "Restarting"); ESP_LOGW(TAG, "Restarting");
esp_restart(); esp_restart();
return 0; return 0;
@@ -143,6 +150,10 @@ static int restart(int argc, char **argv)
void simple_restart() void simple_restart()
{ {
if(!wait_for_commit()){
ESP_LOGW(TAG,"Unable to commit configuration. ");
}
ESP_LOGW(TAG, "Restarting"); ESP_LOGW(TAG, "Restarting");
esp_restart(); esp_restart();
} }

View File

@@ -9,3 +9,4 @@
COMPONENT_ADD_INCLUDEDIRS := . COMPONENT_ADD_INCLUDEDIRS := .
COMPONENT_EXTRA_INCLUDES += $(PROJECT_PATH)/main/ COMPONENT_EXTRA_INCLUDES += $(PROJECT_PATH)/main/
COMPONENT_EXTRA_INCLUDES += $(PROJECT_PATH)/components/tools/

View File

@@ -402,7 +402,7 @@ void bt_sink_init(bt_cmd_cb_t cmd_cb, bt_data_cb_t data_cb)
*/ */
esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_FIXED; esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_FIXED;
char * pin_code = get_nvs_value_alloc_default(NVS_TYPE_STR, "bt_sink_pin", STR(CONFIG_BT_SINK_PIN), 0); char * pin_code = config_alloc_get_default(NVS_TYPE_STR, "bt_sink_pin", STR(CONFIG_BT_SINK_PIN), 0);
if(strlen(pin_code)>ESP_BT_PIN_CODE_LEN){ if(strlen(pin_code)>ESP_BT_PIN_CODE_LEN){
ESP_LOGW(BT_AV_TAG, "BT Sink pin code [%s] too long. ", pin_code); ESP_LOGW(BT_AV_TAG, "BT Sink pin code [%s] too long. ", pin_code);
@@ -487,7 +487,7 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
switch (event) { switch (event) {
case BT_APP_EVT_STACK_UP: { case BT_APP_EVT_STACK_UP: {
/* set up device name */ /* set up device name */
bt_name = (char * )get_nvs_value_alloc_default(NVS_TYPE_STR, "bt_name", CONFIG_BT_NAME, 0); bt_name = (char * )config_alloc_get_default(NVS_TYPE_STR, "bt_name", CONFIG_BT_NAME, 0);
esp_bt_dev_set_device_name(bt_name); esp_bt_dev_set_device_name(bt_name);
free(bt_name); free(bt_name);
esp_bt_gap_register_callback(bt_app_gap_cb); esp_bt_gap_register_callback(bt_app_gap_cb);

View File

@@ -166,7 +166,7 @@ void hal_bluetooth_init(const char * options)
} }
if(squeezelite_args.sink_name->count == 0) if(squeezelite_args.sink_name->count == 0)
{ {
squeezelite_conf.sink_name = get_nvs_value_alloc_default(NVS_TYPE_STR, "a2dp_sink_name", CONFIG_A2DP_SINK_NAME, 0); squeezelite_conf.sink_name = config_alloc_get_default(NVS_TYPE_STR, "a2dp_sink_name", CONFIG_A2DP_SINK_NAME, 0);
if(squeezelite_conf.sink_name == NULL){ if(squeezelite_conf.sink_name == NULL){
ESP_LOGW(TAG,"Unable to retrieve the a2dp sink name from nvs"); ESP_LOGW(TAG,"Unable to retrieve the a2dp sink name from nvs");
squeezelite_conf.sink_name = strdup(CONFIG_A2DP_SINK_NAME); squeezelite_conf.sink_name = strdup(CONFIG_A2DP_SINK_NAME);
@@ -511,7 +511,7 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
/* set up device name */ /* set up device name */
char * a2dp_dev_name = get_nvs_value_alloc_default(NVS_TYPE_STR, "a2dp_dev_name", CONFIG_A2DP_DEV_NAME, 0); char * a2dp_dev_name = config_alloc_get_default(NVS_TYPE_STR, "a2dp_dev_name", CONFIG_A2DP_DEV_NAME, 0);
if(a2dp_dev_name == NULL){ if(a2dp_dev_name == NULL){
ESP_LOGW(TAG,"Unable to retrieve the a2dp device name from nvs"); ESP_LOGW(TAG,"Unable to retrieve the a2dp device name from nvs");
esp_bt_dev_set_device_name(CONFIG_A2DP_DEV_NAME); esp_bt_dev_set_device_name(CONFIG_A2DP_DEV_NAME);

View File

@@ -9,4 +9,5 @@
COMPONENT_ADD_INCLUDEDIRS := . COMPONENT_ADD_INCLUDEDIRS := .
CFLAGS += -Os -DPOSIX -DLINKALL -DLOOPBACK -DNO_FAAD -DEMBEDDED -DTREMOR_ONLY -DBYTES_PER_FRAME=4 CFLAGS += -Os -DPOSIX -DLINKALL -DLOOPBACK -DNO_FAAD -DEMBEDDED -DTREMOR_ONLY -DBYTES_PER_FRAME=4
CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_DEBUG #CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_DEBUG
CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_INFO

View File

@@ -50,7 +50,7 @@ static void vCallbackFunction( TimerHandle_t xTimer ) {
} }
bool led_blink_core(int idx, int ontime, int offtime, bool pushed) { bool led_blink_core(int idx, int ontime, int offtime, bool pushed) {
if (!leds[idx].gpio) return false; if (!leds[idx].gpio || leds[idx].gpio<0 ) return false;
ESP_LOGD(TAG,"led_blink_core"); ESP_LOGD(TAG,"led_blink_core");
if (leds[idx].timer) { if (leds[idx].timer) {
@@ -96,7 +96,7 @@ bool led_blink_core(int idx, int ontime, int offtime, bool pushed) {
} }
bool led_unpush(int idx) { bool led_unpush(int idx) {
if (!leds[idx].gpio) return false; if (!leds[idx].gpio || leds[idx].gpio<0) return false;
led_blink_core(idx, leds[idx].pushedon, leds[idx].pushedoff, true); led_blink_core(idx, leds[idx].pushedon, leds[idx].pushedoff, true);
leds[idx].pushed = false; leds[idx].pushed = false;
@@ -105,6 +105,10 @@ bool led_unpush(int idx) {
} }
bool led_config(int idx, gpio_num_t gpio, int onstate) { bool led_config(int idx, gpio_num_t gpio, int onstate) {
if(gpio<0){
ESP_LOGW(TAG,"LED GPIO not configured");
return false;
}
ESP_LOGD(TAG,"Index %d, GPIO %d, on state %s", idx, gpio, onstate>0?"On":"Off"); ESP_LOGD(TAG,"Index %d, GPIO %d, on state %s", idx, gpio, onstate>0?"On":"Off");
if (idx >= MAX_LED) return false; if (idx >= MAX_LED) return false;
leds[idx].gpio = gpio; leds[idx].gpio = gpio;

View File

@@ -56,7 +56,7 @@ void raop_sink_init(raop_cmd_cb_t cmd_cb, raop_data_cb_t data_cb) {
ESP_ERROR_CHECK( mdns_init() ); ESP_ERROR_CHECK( mdns_init() );
ESP_ERROR_CHECK( mdns_hostname_set(hostname) ); ESP_ERROR_CHECK( mdns_hostname_set(hostname) );
char * sink_name_buffer= (char *)get_nvs_value_alloc(NVS_TYPE_STR, "airplay_name"); char * sink_name_buffer= (char *)config_alloc_get(NVS_TYPE_STR, "airplay_name");
if(sink_name_buffer != NULL){ if(sink_name_buffer != NULL){
memset(sink_name, 0x00, sizeof(sink_name)); memset(sink_name, 0x00, sizeof(sink_name));
strncpy(sink_name,sink_name_buffer,sizeof(sink_name)-1 ); strncpy(sink_name,sink_name_buffer,sizeof(sink_name)-1 );

View File

@@ -8,6 +8,6 @@ COMPONENT_ADD_INCLUDEDIRS := .
COMPONENT_ADD_INCLUDEDIRS += include COMPONENT_ADD_INCLUDEDIRS += include
COMPONENT_EXTRA_INCLUDES += $(PROJECT_PATH)/main/ COMPONENT_EXTRA_INCLUDES += $(PROJECT_PATH)/main/
COMPONENT_EXTRA_INCLUDES += $(PROJECT_PATH)/components/tools COMPONENT_EXTRA_INCLUDES += $(PROJECT_PATH)/components/tools
CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_INFO -DCONFIG_OTA_ALLOW_HTTP=1
CFLAGS += -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG -DCONFIG_OTA_ALLOW_HTTP=1 #CFLAGS += -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG -DCONFIG_OTA_ALLOW_HTTP=1
COMPONENT_EMBED_TXTFILES := ${PROJECT_PATH}/server_certs/github.pem COMPONENT_EMBED_TXTFILES := ${PROJECT_PATH}/server_certs/github.pem

View File

@@ -329,7 +329,7 @@ esp_err_t process_recovery_ota(const char * bin_url){
#define OTA_CORE 0 #define OTA_CORE 0
#warning "OTA will run on core 0" #warning "OTA will run on core 0"
#else #else
#warning "OTA will run on core 1" #pragma message "OTA will run on core 1"
#define OTA_CORE 1 #define OTA_CORE 1
#endif #endif
ESP_LOGI(TAG, "Starting ota on core %u for : %s", OTA_CORE,urlPtr); ESP_LOGI(TAG, "Starting ota on core %u for : %s", OTA_CORE,urlPtr);
@@ -343,12 +343,20 @@ esp_err_t process_recovery_ota(const char * bin_url){
esp_err_t start_ota(const char * bin_url, bool bFromAppMain) esp_err_t start_ota(const char * bin_url, bool bFromAppMain)
{ {
// uint8_t * get_nvs_value_alloc_default(NVS_TYPE_BLOB, "certs", server_cert_pem_start , server_cert_pem_end-server_cert_pem_start); // uint8_t * config_alloc_get_default(NVS_TYPE_BLOB, "certs", server_cert_pem_start , server_cert_pem_end-server_cert_pem_start);
#if RECOVERY_APPLICATION #if RECOVERY_APPLICATION
return process_recovery_ota(bin_url); return process_recovery_ota(bin_url);
#else #else
ESP_LOGW(TAG, "Called to update the firmware from url: %s",bin_url); ESP_LOGW(TAG, "Called to update the firmware from url: %s",bin_url);
store_nvs_value(NVS_TYPE_STR, "fwurl", 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;
}
if(!wait_for_commit()){
ESP_LOGW(TAG,"Unable to commit configuration. ");
}
ESP_LOGW(TAG, "Rebooting to recovery to complete the installation"); ESP_LOGW(TAG, "Rebooting to recovery to complete the installation");
return guided_factory(); return guided_factory();
return ESP_OK; return ESP_OK;

View File

@@ -289,14 +289,17 @@ $(document).ready(function(){
var val = $(this).val(); var val = $(this).val();
if (key != '') { if (key != '') {
headers["X-Custom-"+key] = val; headers["X-Custom-"+key] = val;
data[key] = val; data[key] = {};
data[key].value = val;
data[key].type = 33;
} }
}); });
var key = $("#nvs-new-key").val(); var key = $("#nvs-new-key").val();
var val = $("#nvs-new-value").val(); var val = $("#nvs-new-value").val();
if (key != '') { if (key != '') {
headers["X-Custom-"+key] = val; headers["X-Custom-"+key] = val;
data[key] = val; data[key] = {};
data[key].value = val;
} }
$.ajax({ $.ajax({
url: '/config.json', url: '/config.json',
@@ -454,7 +457,7 @@ $(document).ready(function(){
//start timers //start timers
startCheckStatusInterval(); startCheckStatusInterval();
startRefreshAPInterval(); //startRefreshAPInterval();
$('[data-toggle="tooltip"]').tooltip({ $('[data-toggle="tooltip"]').tooltip({
html: true, html: true,
@@ -718,16 +721,16 @@ function getConfig() {
Object.keys(data).sort().forEach(function(key, i) { Object.keys(data).sort().forEach(function(key, i) {
if (data.hasOwnProperty(key)) { if (data.hasOwnProperty(key)) {
if (key == 'autoexec') { if (key == 'autoexec') {
if (data["autoexec"] === "1") { if (data["autoexec"].value === "1") {
$("#autoexec-cb")[0].checked=true; $("#autoexec-cb")[0].checked=true;
} else { } else {
$("#autoexec-cb")[0].checked=false; $("#autoexec-cb")[0].checked=false;
} }
} else if (key == 'autoexec1') { } else if (key == 'autoexec1') {
$("textarea#autoexec1").val(data[key]); $("textarea#autoexec1").val(data[key].value);
} else if (key == 'host_name') { } else if (key == 'host_name') {
$("dhcp-name1").val(data[key]); $("dhcp-name1").val(data[key].value);
$("dhcp-name2").val(data[key]); $("dhcp-name2").val(data[key].value);
} }
$("tbody#nvsTable").append( $("tbody#nvsTable").append(
@@ -738,7 +741,7 @@ function getConfig() {
"</td>"+ "</td>"+
"</tr>" "</tr>"
); );
$("input#"+key).val(data[key]); $("input#"+key).val(data[key].value);
} }
}); });
$("tbody#nvsTable").append( $("tbody#nvsTable").append(

View File

@@ -7,7 +7,8 @@
# please read the SDK documents if you need to do this. # please read the SDK documents if you need to do this.
# #
COMPONENT_EMBED_FILES := style.css code.js index.html bootstrap.min.css.gz jquery.min.js.gz popper.min.js.gz bootstrap.min.js.gz COMPONENT_EMBED_FILES := style.css code.js index.html bootstrap.min.css.gz jquery.min.js.gz popper.min.js.gz bootstrap.min.js.gz
CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_DEBUG \ #CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_DEBUG
CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_INFO \
-I$(COMPONENT_PATH)/../tools -I$(COMPONENT_PATH)/../tools
COMPONENT_ADD_INCLUDEDIRS := . COMPONENT_ADD_INCLUDEDIRS := .
COMPONENT_ADD_INCLUDEDIRS += $(COMPONENT_PATH)/../tools COMPONENT_ADD_INCLUDEDIRS += $(COMPONENT_PATH)/../tools

View File

@@ -42,9 +42,8 @@ function to process requests, decode URLs, serve files, etc. etc.
#include "esp_system.h" #include "esp_system.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "config.h"
#define NVS_PARTITION_NAME "nvs"
#define NUM_BUFFER_LEN 101
/* @brief tag used for ESP serial console messages */ /* @brief tag used for ESP serial console messages */
static const char TAG[] = "http_server"; static const char TAG[] = "http_server";
@@ -210,67 +209,19 @@ void http_server_send_resource_file(struct netconn *conn,const uint8_t * start,
} }
} }
err_t http_server_nvs_dump(struct netconn *conn, nvs_type_t nvs_type) { err_t http_server_send_config_json(struct netconn *conn) {
nvs_entry_info_t info; char * json = config_alloc_get_json(false);
char * num_buffer = NULL; if(json!=NULL){
cJSON * nvs_json = cJSON_CreateObject(); ESP_LOGD(TAG, "config json : %s",json );
num_buffer = malloc(NUM_BUFFER_LEN);
nvs_iterator_t it = nvs_entry_find(settings_partition, NULL, nvs_type);
if(it == NULL) {
ESP_LOGW(TAG, "No nvs entry found in %s",NVS_PARTITION_NAME );
}
while (it != NULL) {
nvs_entry_info(it, &info);
memset(num_buffer,0x00,NUM_BUFFER_LEN);
if(strstr(info.namespace_name, current_namespace)) {
void * value = get_nvs_value_alloc(nvs_type,info.key);
if(value==NULL)
{
ESP_LOGE(TAG,"nvs read failed.");
netconn_write(conn, http_503_hdr, sizeof(http_503_hdr) - 1, NETCONN_NOCOPY); //200ok
free(num_buffer);
cJSON_Delete(nvs_json);
return ESP_FAIL;
}
switch (nvs_type) {
case NVS_TYPE_I8:
snprintf(num_buffer, NUM_BUFFER_LEN-1, "%i", *(int8_t*)value);
break;
case NVS_TYPE_I16:
snprintf(num_buffer, NUM_BUFFER_LEN-1, "%i", *(int16_t*)value);
break;
case NVS_TYPE_I32:
snprintf(num_buffer, NUM_BUFFER_LEN-1, "%i", *(int32_t*)value);
break;
case NVS_TYPE_U8:
snprintf(num_buffer, NUM_BUFFER_LEN-1, "%u", *(uint8_t*)value);
break;
case NVS_TYPE_U16:
snprintf(num_buffer, NUM_BUFFER_LEN-1, "%u", *(uint16_t*)value);
break;
case NVS_TYPE_U32:
snprintf(num_buffer, NUM_BUFFER_LEN-1, "%u", *(uint32_t*)value);
break;
case NVS_TYPE_STR:
// string will be processed directly below
break;
case NVS_TYPE_I64:
case NVS_TYPE_U64:
default:
ESP_LOGE(TAG, "nvs type %u not supported", nvs_type);
break;
}
cJSON_AddItemToObject(nvs_json, info.key, cJSON_CreateString((nvs_type==NVS_TYPE_STR)?(char *)value:num_buffer));
free(value );
}
it = nvs_entry_next(it);
}
ESP_LOGD(TAG,"config json : %s\n", cJSON_Print(nvs_json));
netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY);
netconn_write(conn, cJSON_Print(nvs_json), strlen(cJSON_Print(nvs_json)), NETCONN_NOCOPY); netconn_write(conn, json, strlen(json), NETCONN_NOCOPY);
cJSON_Delete(nvs_json); free(json);
free(num_buffer); }
else{
ESP_LOGD(TAG, "Error retrieving config json string. ");
netconn_write(conn, http_503_hdr, sizeof(http_503_hdr) - 1, NETCONN_NOCOPY);
}
return ESP_OK; return ESP_OK;
} }
@@ -336,7 +287,7 @@ void http_server_process_config(struct netconn *conn, char *inbuf) {
void dump_net_buffer(void * buf, u16_t buflen) { void dump_net_buffer(void * buf, u16_t buflen) {
char * curbuf = malloc(buflen+1); char * curbuf = malloc(buflen+1);
ESP_LOGD(TAG,"netconn buffer, length=%u",buflen); ESP_LOGV(TAG, "netconn buffer, length=%u",buflen);
if(curbuf==NULL) { if(curbuf==NULL) {
ESP_LOGE(TAG, "Unable to show netconn buffer. Malloc failed"); ESP_LOGE(TAG, "Unable to show netconn buffer. Malloc failed");
} }
@@ -354,22 +305,22 @@ void http_server_netconn_serve(struct netconn *conn) {
err_t err; err_t err;
ip_addr_t remote_add; ip_addr_t remote_add;
u16_t port; u16_t port;
ESP_LOGD(TAG,"Serving page. Getting device AP address."); ESP_LOGV(TAG, "Serving page. Getting device AP address.");
const char new_line[2] = "\n"; const char new_line[2] = "\n";
char * ap_ip_address= get_nvs_value_alloc_default(NVS_TYPE_STR, "ap_ip_address", DEFAULT_AP_IP, 0); char * ap_ip_address= config_alloc_get_default(NVS_TYPE_STR, "ap_ip_address", DEFAULT_AP_IP, 0);
if(ap_ip_address==NULL){ if(ap_ip_address==NULL){
ESP_LOGE(TAG, "Unable to retrieve default AP IP Address"); ESP_LOGE(TAG, "Unable to retrieve default AP IP Address");
netconn_write(conn, http_503_hdr, sizeof(http_503_hdr) - 1, NETCONN_NOCOPY); netconn_write(conn, http_503_hdr, sizeof(http_503_hdr) - 1, NETCONN_NOCOPY);
netconn_close(conn); netconn_close(conn);
return; return;
} }
ESP_LOGD(TAG,"Getting remote device IP address."); ESP_LOGV(TAG, "Getting remote device IP address.");
netconn_getaddr(conn, &remote_add, &port, 0); netconn_getaddr(conn, &remote_add, &port, 0);
char * remote_address = strdup(ip4addr_ntoa(ip_2_ip4(&remote_add))); char * remote_address = strdup(ip4addr_ntoa(ip_2_ip4(&remote_add)));
ESP_LOGD(TAG, "Local Access Point IP address is: %s. Remote device IP address is %s. Receiving request buffer", ap_ip_address, remote_address); ESP_LOGD(TAG, "Local Access Point IP address is: %s. Remote device IP address is %s. Receiving request buffer", ap_ip_address, remote_address);
err = netconn_recv(conn, &inbuf); err = netconn_recv(conn, &inbuf);
if(err == ERR_OK) { if(err == ERR_OK) {
ESP_LOGD(TAG,"Getting data buffer."); ESP_LOGV(TAG, "Getting data buffer.");
netbuf_data(inbuf, (void**)&buf, &buflen); netbuf_data(inbuf, (void**)&buf, &buflen);
dump_net_buffer(buf, buflen); dump_net_buffer(buf, buflen);
int lenH = 0; int lenH = 0;
@@ -433,14 +384,25 @@ void http_server_netconn_serve(struct netconn *conn) {
} }
//dynamic stuff //dynamic stuff
else if(strstr(line, "GET /scan.json ")) {
ESP_LOGI(TAG, "Starting wifi scan");
wifi_manager_scan_async();
}
else if(strstr(line, "GET /ap.json ")) { else if(strstr(line, "GET /ap.json ")) {
/* if we can get the mutex, write the last version of the AP list */ /* if we can get the mutex, write the last version of the AP list */
ESP_LOGI(TAG, "Processing ap.json request"); ESP_LOGI(TAG, "Processing ap.json request");
if(wifi_manager_lock_json_buffer(( TickType_t ) 10)) { if(wifi_manager_lock_json_buffer(( TickType_t ) 10)) {
netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY);
char *buff = wifi_manager_get_ap_list_json(); char *buff = wifi_manager_alloc_get_ap_list_json();
netconn_write(conn, buff, strlen(buff), NETCONN_NOCOPY);
wifi_manager_unlock_json_buffer(); wifi_manager_unlock_json_buffer();
if(buff!=NULL){
netconn_write(conn, buff, strlen(buff), NETCONN_NOCOPY);
free(buff);
}
else {
ESP_LOGD(TAG, "Error retrieving ap list json string. ");
netconn_write(conn, http_503_hdr, sizeof(http_503_hdr) - 1, NETCONN_NOCOPY);
}
} }
else { else {
netconn_write(conn, http_503_hdr, sizeof(http_503_hdr) - 1, NETCONN_NOCOPY); netconn_write(conn, http_503_hdr, sizeof(http_503_hdr) - 1, NETCONN_NOCOPY);
@@ -454,7 +416,7 @@ void http_server_netconn_serve(struct netconn *conn) {
else if(strstr(line, "GET /config.json ")) { else if(strstr(line, "GET /config.json ")) {
ESP_LOGI(TAG, "Serving config.json"); ESP_LOGI(TAG, "Serving config.json");
ESP_LOGI(TAG, "About to get config from flash"); ESP_LOGI(TAG, "About to get config from flash");
http_server_nvs_dump(conn,NVS_TYPE_STR); http_server_send_config_json(conn);
ESP_LOGD(TAG, "Done serving config.json"); ESP_LOGD(TAG, "Done serving config.json");
} }
else if(strstr(line, "POST /config.json ")) { else if(strstr(line, "POST /config.json ")) {
@@ -483,8 +445,9 @@ void http_server_netconn_serve(struct netconn *conn) {
} }
else { else {
ESP_LOGV(TAG, "http_server_netconn_serve: POST config.json Storing parameter"); ESP_LOGV(TAG, "http_server_netconn_serve: POST config.json Storing parameter");
err= store_nvs_value(NVS_TYPE_STR, last_parm_name , last_parm); if(config_set_value(NVS_TYPE_STR, last_parm_name , last_parm) != ESP_OK){
if(err!=ESP_OK) ESP_LOGE(TAG,"Unable to save nvs value. Error: %s",esp_err_to_name(err)); ESP_LOGE(TAG, "Unable to save nvs value.");
}
} }
} }
if(last_parm_name!=NULL) { if(last_parm_name!=NULL) {
@@ -498,6 +461,7 @@ void http_server_netconn_serve(struct netconn *conn) {
else { else {
netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); //200ok netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); //200ok
if(bOTA) { if(bOTA) {
#if RECOVERY_APPLICATION #if RECOVERY_APPLICATION
ESP_LOGW(TAG, "Starting process OTA for url %s",otaURL); ESP_LOGW(TAG, "Starting process OTA for url %s",otaURL);
#else #else
@@ -515,10 +479,20 @@ void http_server_netconn_serve(struct netconn *conn) {
else if(strstr(line, "POST /connect.json ")) { else if(strstr(line, "POST /connect.json ")) {
ESP_LOGI(TAG, "http_server_netconn_serve: POST /connect.json"); ESP_LOGI(TAG, "http_server_netconn_serve: POST /connect.json");
bool found = false; bool found = false;
int lenS = 0, lenP = 0; int lenS = 0, lenP = 0, lenN = 0;
char *ssid = NULL, *password = NULL; char *ssid = NULL, *password = NULL;
ssid = http_server_get_header(save_ptr, "X-Custom-ssid: ", &lenS); ssid = http_server_get_header(save_ptr, "X-Custom-ssid: ", &lenS);
password = http_server_get_header(save_ptr, "X-Custom-pwd: ", &lenP); password = http_server_get_header(save_ptr, "X-Custom-pwd: ", &lenP);
char * new_host_name_b = http_server_get_header(save_ptr, "X-Custom-host_name: ", &lenN);
if(lenN > 0){
lenN++;
char * new_host_name = malloc(lenN);
strlcpy(new_host_name, new_host_name_b, lenN);
if(config_set_value(NVS_TYPE_STR, "host_name", new_host_name) != ESP_OK){
ESP_LOGE(TAG, "Unable to save host name configuration");
}
free(new_host_name);
}
if(ssid && lenS <= MAX_SSID_SIZE && password && lenP <= MAX_PASSWORD_SIZE) { if(ssid && lenS <= MAX_SSID_SIZE && password && lenP <= MAX_PASSWORD_SIZE) {
wifi_config_t* config = wifi_manager_get_wifi_sta_config(); wifi_config_t* config = wifi_manager_get_wifi_sta_config();
@@ -577,15 +551,17 @@ void http_server_netconn_serve(struct netconn *conn) {
else if(strstr(line, "GET /status.json ")) { else if(strstr(line, "GET /status.json ")) {
ESP_LOGI(TAG, "Serving status.json"); ESP_LOGI(TAG, "Serving status.json");
if(wifi_manager_lock_json_buffer(( TickType_t ) 10)) { if(wifi_manager_lock_json_buffer(( TickType_t ) 10)) {
char *buff = wifi_manager_get_ip_info_json(); char *buff = wifi_manager_alloc_get_ip_info_json();
wifi_manager_unlock_json_buffer();
if(buff) { if(buff) {
netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY);
netconn_write(conn, buff, strlen(buff), NETCONN_NOCOPY); netconn_write(conn, buff, strlen(buff), NETCONN_NOCOPY);
free(buff);
} }
else { else {
netconn_write(conn, http_503_hdr, sizeof(http_503_hdr) - 1, NETCONN_NOCOPY); netconn_write(conn, http_503_hdr, sizeof(http_503_hdr) - 1, NETCONN_NOCOPY);
} }
wifi_manager_unlock_json_buffer();
} }
else { else {
netconn_write(conn, http_503_hdr, sizeof(http_503_hdr) - 1, NETCONN_NOCOPY); netconn_write(conn, http_503_hdr, sizeof(http_503_hdr) - 1, NETCONN_NOCOPY);

View File

@@ -87,7 +87,6 @@ uint16_t ap_num = MAX_AP_NUM;
wifi_ap_record_t *accessp_records=NULL; wifi_ap_record_t *accessp_records=NULL;
cJSON * accessp_cjson=NULL; cJSON * accessp_cjson=NULL;
char *ip_info_json = NULL; char *ip_info_json = NULL;
char *host_name = NULL;
char * release_url=NULL; char * release_url=NULL;
cJSON * ip_info_cjson=NULL; cJSON * ip_info_cjson=NULL;
wifi_config_t* wifi_manager_config_sta = NULL; wifi_config_t* wifi_manager_config_sta = NULL;
@@ -189,7 +188,22 @@ char * get_disconnect_code_desc(uint8_t reason){
} }
return ""; return "";
} }
void set_host_name(){
esp_err_t err;
ESP_LOGD(TAG, "Retrieving host name from nvs");
char * host_name = (char * )config_alloc_get(NVS_TYPE_STR, "host_name");
if(host_name ==NULL){
ESP_LOGE(TAG, "Could not retrieve host name from nvs");
}
else {
ESP_LOGD(TAG, "Setting host name to : %s",host_name);
if((err=tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA, host_name)) !=ESP_OK){
ESP_LOGE(TAG, "Unable to set host name. Error: %s",esp_err_to_name(err));
}
free(host_name);
}
}
bool isGroupBitSet(uint8_t bit){ bool isGroupBitSet(uint8_t bit){
EventBits_t uxBits= xEventGroupGetBits(wifi_manager_event_group); EventBits_t uxBits= xEventGroupGetBits(wifi_manager_event_group);
@@ -230,7 +244,7 @@ void wifi_manager_init_wifi(){
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_NULL) ); ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_NULL) );
ESP_LOGD(TAG, "Initializing wifi. Starting wifi"); ESP_LOGD(TAG, "Initializing wifi. Starting wifi");
ESP_ERROR_CHECK( esp_wifi_start() ); ESP_ERROR_CHECK( esp_wifi_start() );
taskYIELD(); /* allows the freeRTOS scheduler to take over if needed. */ taskYIELD();
ESP_LOGD(TAG, "Initializing wifi. done"); ESP_LOGD(TAG, "Initializing wifi. done");
} }
@@ -266,17 +280,8 @@ void wifi_manager_start(){
wifi_manager_sta_ip = (char*)malloc(sizeof(char) * IP4ADDR_STRLEN_MAX); wifi_manager_sta_ip = (char*)malloc(sizeof(char) * IP4ADDR_STRLEN_MAX);
wifi_manager_safe_update_sta_ip_string(NULL); wifi_manager_safe_update_sta_ip_string(NULL);
ESP_LOGD(TAG, "Retrieving host name from nvs");
host_name = (char * )get_nvs_value_alloc_default(NVS_TYPE_STR, "host_name", "squeezelite-esp32", 0);
if(host_name ==NULL){
ESP_LOGE(TAG, "Could not retrieve host name from nvs");
}
else {
ESP_LOGD(TAG, "Found host name %s ", host_name);
}
ESP_LOGD(TAG, "Getting release url "); ESP_LOGD(TAG, "Getting release url ");
char * release_url = (char * )get_nvs_value_alloc_default(NVS_TYPE_STR, "release_url", QUOTE(SQUEEZELITE_ESP32_RELEASE_URL), 0); char * release_url = (char * )config_alloc_get_default(NVS_TYPE_STR, "release_url", QUOTE(SQUEEZELITE_ESP32_RELEASE_URL), 0);
if(release_url == NULL){ if(release_url == NULL){
ESP_LOGE(TAG, "Unable to retrieve the release url from nvs"); ESP_LOGE(TAG, "Unable to retrieve the release url from nvs");
} }
@@ -331,24 +336,18 @@ esp_err_t wifi_manager_save_sta_config(){
nvs_close(handle); nvs_close(handle);
ESP_LOGD(TAG, "wifi_manager_wrote wifi_sta_config: ssid:%s password:%s",wifi_manager_config_sta->sta.ssid,wifi_manager_config_sta->sta.password); ESP_LOGD(TAG, "wifi_manager_wrote wifi_sta_config: ssid:%s password:%s",wifi_manager_config_sta->sta.ssid,wifi_manager_config_sta->sta.password);
// ESP_LOGD(TAG, "wifi_manager_wrote wifi_settings: sta_static_ip (0 = dhcp client, 1 = static ip): %i",wifi_settings.sta_static_ip);
// ESP_LOGD(TAG, "wifi_manager_wrote wifi_settings: sta_ip_addr: %s", ip4addr_ntoa(&wifi_settings.sta_static_ip_config.ip));
// ESP_LOGD(TAG, "wifi_manager_wrote wifi_settings: sta_gw_addr: %s", ip4addr_ntoa(&wifi_settings.sta_static_ip_config.gw));
// ESP_LOGD(TAG, "wifi_manager_wrote wifi_settings: sta_netmask: %s", ip4addr_ntoa(&wifi_settings.sta_static_ip_config.netmask));
} }
return ESP_OK; return ESP_OK;
} }
#define RETRIEVE_CONFIG_STRING_VALUE(name,def,var) value = get_nvs_value_alloc_default(NVS_TYPE_STR, name, def, 0); if(value!=NULL){ strlcpy(var, value, sizeof(var)); free(value); value=NULL;}
bool wifi_manager_fetch_wifi_sta_config(){ bool wifi_manager_fetch_wifi_sta_config(){
nvs_handle handle; nvs_handle handle;
esp_err_t esp_err; esp_err_t esp_err;
ESP_LOGD(TAG, "Fetching wifi sta config."); ESP_LOGD(TAG, "Fetching wifi sta config.");
if(nvs_open(wifi_manager_nvs_namespace, NVS_READONLY, &handle) == ESP_OK){ esp_err=nvs_open(wifi_manager_nvs_namespace, NVS_READONLY, &handle);
if(esp_err == ESP_OK){
if(wifi_manager_config_sta == NULL){ if(wifi_manager_config_sta == NULL){
ESP_LOGD(TAG, "Allocating memory for structure."); ESP_LOGD(TAG, "Allocating memory for structure.");
wifi_manager_config_sta = (wifi_config_t*)malloc(sizeof(wifi_config_t)); wifi_manager_config_sta = (wifi_config_t*)malloc(sizeof(wifi_config_t));
@@ -363,7 +362,7 @@ bool wifi_manager_fetch_wifi_sta_config(){
esp_err = nvs_get_blob(handle, "ssid", buff, &sz); esp_err = nvs_get_blob(handle, "ssid", buff, &sz);
if(esp_err != ESP_OK){ if(esp_err != ESP_OK){
ESP_LOGI(TAG, "No ssid found in nvs."); ESP_LOGI(TAG, "No ssid found in nvs.");
free(buff); FREE_AND_NULL(buff);
nvs_close(handle); nvs_close(handle);
return false; return false;
} }
@@ -390,35 +389,35 @@ bool wifi_manager_fetch_wifi_sta_config(){
return wifi_manager_config_sta->sta.ssid[0] != '\0'; return wifi_manager_config_sta->sta.ssid[0] != '\0';
} }
else{ else{
ESP_LOGE(TAG,"Failed to open nvs namespace %s.",wifi_manager_nvs_namespace); ESP_LOGW(TAG, "wifi manager has no previous configuration. %s",esp_err_to_name(esp_err));
return false; return false;
} }
} }
cJSON * wifi_manager_get_new_json(cJSON **old){ cJSON * wifi_manager_get_new_json(cJSON **old){
ESP_LOGD(TAG,"wifi_manager_get_new_json called"); ESP_LOGV(TAG, "wifi_manager_get_new_json called");
cJSON * root=*old; cJSON * root=*old;
if(root!=NULL){ if(root!=NULL){
cJSON_Delete(root); cJSON_Delete(root);
*old=NULL; *old=NULL;
} }
ESP_LOGD(TAG,"wifi_manager_get_new_json done"); ESP_LOGV(TAG, "wifi_manager_get_new_json done");
return cJSON_CreateObject(); return cJSON_CreateObject();
} }
cJSON * wifi_manager_get_new_array_json(cJSON **old){ cJSON * wifi_manager_get_new_array_json(cJSON **old){
ESP_LOGD(TAG,"wifi_manager_get_new_array_json called"); ESP_LOGV(TAG, "wifi_manager_get_new_array_json called");
cJSON * root=*old; cJSON * root=*old;
if(root!=NULL){ if(root!=NULL){
cJSON_Delete(root); cJSON_Delete(root);
*old=NULL; *old=NULL;
} }
ESP_LOGD(TAG,"wifi_manager_get_new_array_json done"); ESP_LOGV(TAG, "wifi_manager_get_new_array_json done");
return cJSON_CreateArray(); return cJSON_CreateArray();
} }
cJSON * wifi_manager_get_basic_info(cJSON **old){ cJSON * wifi_manager_get_basic_info(cJSON **old){
const esp_app_desc_t* desc = esp_ota_get_app_description(); const esp_app_desc_t* desc = esp_ota_get_app_description();
ESP_LOGD(TAG,"wifi_manager_get_basic_info called"); ESP_LOGV(TAG, "wifi_manager_get_basic_info called");
cJSON *root = wifi_manager_get_new_json(old); cJSON *root = wifi_manager_get_new_json(old);
cJSON_AddItemToObject(root, "project_name", cJSON_CreateString(desc->project_name)); cJSON_AddItemToObject(root, "project_name", cJSON_CreateString(desc->project_name));
cJSON_AddItemToObject(root, "version", cJSON_CreateString(desc->version)); cJSON_AddItemToObject(root, "version", cJSON_CreateString(desc->version));
@@ -515,9 +514,18 @@ void wifi_manager_generate_access_points_json(cJSON ** ap_list){
cJSON_AddNumberToObject(radio, "low_rate", ap_rec.phy_lr?1:0); cJSON_AddNumberToObject(radio, "low_rate", ap_rec.phy_lr?1:0);
cJSON_AddItemToObject(ap,"radio", radio); cJSON_AddItemToObject(ap,"radio", radio);
cJSON_AddItemToArray(*ap_list, ap); cJSON_AddItemToArray(*ap_list, ap);
ESP_LOGD(TAG,"New access point found: %s", cJSON_Print(ap)); char * ap_json = cJSON_PrintUnformatted(ap);
if(ap_json!=NULL){
ESP_LOGD(TAG, "New access point found: %s", ap_json);
free(ap_json);
} }
ESP_LOGV(TAG,"Full access point list: %s", cJSON_Print(*ap_list)); }
char * ap_list_json = cJSON_PrintUnformatted(*ap_list);
if(ap_list_json!=NULL){
ESP_LOGV(TAG, "Full access point list: %s", ap_list_json);
free(ap_list_json);
}
} }
bool wifi_manager_lock_sta_ip_string(TickType_t xTicksToWait){ bool wifi_manager_lock_sta_ip_string(TickType_t xTicksToWait){
@@ -575,8 +583,8 @@ void wifi_manager_unlock_json_buffer(){
xSemaphoreGive( wifi_manager_json_mutex ); xSemaphoreGive( wifi_manager_json_mutex );
} }
char* wifi_manager_get_ap_list_json(){ char* wifi_manager_alloc_get_ap_list_json(){
return cJSON_Print(accessp_cjson); return cJSON_PrintUnformatted(accessp_cjson);
} }
@@ -836,14 +844,13 @@ void set_status_message(message_severity_t severity, const char * message){
} }
char* wifi_manager_get_ip_info_json(){ char* wifi_manager_alloc_get_ip_info_json(){
return cJSON_Print(ip_info_cjson); return cJSON_PrintUnformatted(ip_info_cjson);
} }
void wifi_manager_destroy(){ void wifi_manager_destroy(){
vTaskDelete(task_wifi_manager); vTaskDelete(task_wifi_manager);
task_wifi_manager = NULL; task_wifi_manager = NULL;
free(host_name);
/* heap buffers */ /* heap buffers */
free(ip_info_json); free(ip_info_json);
free(release_url); free(release_url);
@@ -973,45 +980,54 @@ void wifi_manager_config_ap(){
.ssid_len = 0, .ssid_len = 0,
}, },
}; };
ESP_LOGD(TAG,"Configuring Access Point."); ESP_LOGI(TAG, "Configuring Access Point.");
ESP_ERROR_CHECK(tcpip_adapter_dhcps_stop(TCPIP_ADAPTER_IF_AP)); /* stop AP DHCP server */ ESP_ERROR_CHECK(tcpip_adapter_dhcps_stop(TCPIP_ADAPTER_IF_AP)); /* stop AP DHCP server */
value = get_nvs_value_alloc_default(NVS_TYPE_STR, "ap_ssid", CONFIG_DEFAULT_AP_SSID, 0); /*
* Set access point mode IP adapter configuration
*/
value = config_alloc_get_default(NVS_TYPE_STR, "ap_ip_address", DEFAULT_AP_IP, 0);
if(value!=NULL){ if(value!=NULL){
strlcpy((char *)ap_config.ap.ssid, value,sizeof(ap_config.ap.ssid) ); ESP_LOGI(TAG, "IP Address: %s", value);
ESP_LOGD(TAG,"AP SSID: %s", (char *)ap_config.ap.ssid);
}
FREE_AND_NULL(value);
value = get_nvs_value_alloc_default(NVS_TYPE_STR, "ap_pwd", DEFAULT_AP_PASSWORD, 0);
if(value!=NULL){
strlcpy((char *)ap_config.ap.password, value,sizeof(ap_config.ap.password) );
ESP_LOGD(TAG,"AP Password: %s", (char *)ap_config.ap.password);
}
FREE_AND_NULL(value);
value = get_nvs_value_alloc_default(NVS_TYPE_STR, "ap_ip_address", DEFAULT_AP_IP, 0);
if(value!=NULL){
ESP_LOGD(TAG,"IP Address: %s", value);
inet_pton(AF_INET,value, &info.ip); /* access point is on a static IP */ inet_pton(AF_INET,value, &info.ip); /* access point is on a static IP */
} }
FREE_AND_NULL(value); FREE_AND_NULL(value);
value = get_nvs_value_alloc_default(NVS_TYPE_STR, "ap_ip_gateway", CONFIG_DEFAULT_AP_GATEWAY, 0); value = config_alloc_get_default(NVS_TYPE_STR, "ap_ip_gateway", CONFIG_DEFAULT_AP_GATEWAY, 0);
if(value!=NULL){ if(value!=NULL){
ESP_LOGD(TAG,"Gateway: %s", value); ESP_LOGI(TAG, "Gateway: %s", value);
inet_pton(AF_INET,value, &info.gw); /* access point is on a static IP */ inet_pton(AF_INET,value, &info.gw); /* access point is on a static IP */
} }
FREE_AND_NULL(value); FREE_AND_NULL(value);
value = get_nvs_value_alloc_default(NVS_TYPE_STR, "ap_ip_netmask", CONFIG_DEFAULT_AP_NETMASK, 0); value = config_alloc_get_default(NVS_TYPE_STR, "ap_ip_netmask", CONFIG_DEFAULT_AP_NETMASK, 0);
if(value!=NULL){ if(value!=NULL){
ESP_LOGD(TAG,"Netmask: %s", value); ESP_LOGI(TAG, "Netmask: %s", value);
inet_pton(AF_INET,value, &info.netmask); /* access point is on a static IP */ inet_pton(AF_INET,value, &info.netmask); /* access point is on a static IP */
} }
FREE_AND_NULL(value); FREE_AND_NULL(value);
value = get_nvs_value_alloc_default(NVS_TYPE_STR, "ap_channel", STR(CONFIG_DEFAULT_AP_CHANNEL), 0); ESP_LOGD(TAG, "Setting tcp_ip info for interface TCPIP_ADAPTER_IF_AP");
ESP_ERROR_CHECK(tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_AP, &info));
/*
* Set Access Point configuration
*/
value = config_alloc_get_default(NVS_TYPE_STR, "ap_ssid", CONFIG_DEFAULT_AP_SSID, 0);
if(value!=NULL){ if(value!=NULL){
ESP_LOGD(TAG,"Channel: %s", value); strlcpy((char *)ap_config.ap.ssid, value,sizeof(ap_config.ap.ssid) );
ESP_LOGI(TAG, "AP SSID: %s", (char *)ap_config.ap.ssid);
}
FREE_AND_NULL(value);
value = config_alloc_get_default(NVS_TYPE_STR, "ap_pwd", DEFAULT_AP_PASSWORD, 0);
if(value!=NULL){
strlcpy((char *)ap_config.ap.password, value,sizeof(ap_config.ap.password) );
ESP_LOGI(TAG, "AP Password: %s", (char *)ap_config.ap.password);
}
FREE_AND_NULL(value);
value = config_alloc_get_default(NVS_TYPE_STR, "ap_channel", STR(CONFIG_DEFAULT_AP_CHANNEL), 0);
if(value!=NULL){
ESP_LOGI(TAG, "Channel: %s", value);
ap_config.ap.channel=atoi(value); ap_config.ap.channel=atoi(value);
} }
FREE_AND_NULL(value); FREE_AND_NULL(value);
@@ -1021,13 +1037,11 @@ void wifi_manager_config_ap(){
ap_config.ap.max_connection = DEFAULT_AP_MAX_CONNECTIONS; ap_config.ap.max_connection = DEFAULT_AP_MAX_CONNECTIONS;
ap_config.ap.beacon_interval = DEFAULT_AP_BEACON_INTERVAL; ap_config.ap.beacon_interval = DEFAULT_AP_BEACON_INTERVAL;
ESP_LOGD(TAG,"Auth Mode: %d", ap_config.ap.authmode); ESP_LOGI(TAG, "Auth Mode: %d", ap_config.ap.authmode);
ESP_LOGD(TAG,"SSID Hidden: %d", ap_config.ap.ssid_hidden); ESP_LOGI(TAG, "SSID Hidden: %d", ap_config.ap.ssid_hidden);
ESP_LOGD(TAG,"Max Connections: %d", ap_config.ap.max_connection); ESP_LOGI(TAG, "Max Connections: %d", ap_config.ap.max_connection);
ESP_LOGD(TAG,"Beacon interval: %d", ap_config.ap.beacon_interval); ESP_LOGI(TAG, "Beacon interval: %d", ap_config.ap.beacon_interval);
ESP_LOGD(TAG,"Setting tcp_ip info for interface TCPIP_ADAPTER_IF_AP");
ESP_ERROR_CHECK(tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_AP, &info));
ESP_LOGD(TAG, "Starting dhcps on interface TCPIP_ADAPTER_IF_AP"); ESP_LOGD(TAG, "Starting dhcps on interface TCPIP_ADAPTER_IF_AP");
ESP_ERROR_CHECK(tcpip_adapter_dhcps_start(TCPIP_ADAPTER_IF_AP)); /* start AP DHCP server */ ESP_ERROR_CHECK(tcpip_adapter_dhcps_start(TCPIP_ADAPTER_IF_AP)); /* start AP DHCP server */
@@ -1203,10 +1217,8 @@ void wifi_manager( void * pvParameters ){
} }
ESP_LOGD(TAG, "MESSAGE: ORDER_CONNECT_STA - setting config for WIFI_IF_STA"); ESP_LOGD(TAG, "MESSAGE: ORDER_CONNECT_STA - setting config for WIFI_IF_STA");
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, wifi_manager_get_wifi_sta_config())); ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, wifi_manager_get_wifi_sta_config()));
ESP_LOGD(TAG,"Setting host name to : %s",host_name);
if((err=tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA, host_name)) !=ESP_OK){ set_host_name();
ESP_LOGE(TAG,"Unable to set host name. Error: %s",esp_err_to_name(err));
}
ESP_LOGI(TAG, "Wifi Connecting..."); ESP_LOGI(TAG, "Wifi Connecting...");
ESP_ERROR_CHECK(esp_wifi_connect()); ESP_ERROR_CHECK(esp_wifi_connect());
} }
@@ -1338,13 +1350,6 @@ void wifi_manager( void * pvParameters ){
/* if it was a restore attempt connection, we clear the bit */ /* if it was a restore attempt connection, we clear the bit */
xEventGroupClearBits(wifi_manager_event_group, WIFI_MANAGER_REQUEST_RESTORE_STA_BIT); xEventGroupClearBits(wifi_manager_event_group, WIFI_MANAGER_REQUEST_RESTORE_STA_BIT);
/* erase configuration that could not be used to connect */
// if(wifi_manager_config_sta){
// ESP_LOGW(TAG, "Erasing wifi manager config.");
// memset(wifi_manager_config_sta, 0x00, sizeof(wifi_config_t));
// /* save empty connection info in NVS memory */
// wifi_manager_save_sta_config();
// }
ESP_LOGD(TAG, "Issuing ORDER_START_AP to trigger AP start."); ESP_LOGD(TAG, "Issuing ORDER_START_AP to trigger AP start.");
/* start SoftAP */ /* start SoftAP */
wifi_manager_send_message(ORDER_START_AP, NULL); wifi_manager_send_message(ORDER_START_AP, NULL);

View File

@@ -48,7 +48,7 @@ extern "C" {
#if RECOVERY_APPLICATION==1 #if RECOVERY_APPLICATION==1
#elif RECOVERY_APPLICATION==0 #elif RECOVERY_APPLICATION==0
#warning "compiling for squeezelite." #pragma message "compiling for squeezelite."
#else #else
#error "unknown configuration" #error "unknown configuration"
#endif #endif
@@ -268,8 +268,8 @@ void filter_unique( wifi_ap_record_t * aplist, uint16_t * ap_num);
void wifi_manager( void * pvParameters ); void wifi_manager( void * pvParameters );
char* wifi_manager_get_ap_list_json(); char* wifi_manager_alloc_get_ap_list_json();
char* wifi_manager_get_ip_info_json(); char* wifi_manager_alloc_get_ip_info_json();
cJSON * wifi_manager_clear_ap_list_json(cJSON **old); cJSON * wifi_manager_clear_ap_list_json(cJSON **old);
/** /**

View File

@@ -1,6 +1,6 @@
set(COMPONENT_ADD_INCLUDEDIRS . ) set(COMPONENT_ADD_INCLUDEDIRS . )
set(COMPONENT_SRCS "esp_app_main.c" "platform_esp32.c" "cmd_wifi.c" "console.c" "nvs_utilities.c" "cmd_squeezelite.c") set(COMPONENT_SRCS "esp_app_main.c" "platform_esp32.c" "cmd_wifi.c" "console.c" "nvs_utilities.c" "cmd_squeezelite.c" "config.c")
set(REQUIRES esp_common) set(REQUIRES esp_common)
set(REQUIRES_COMPONENTS freertos squeezelite nvs_flash esp32 spi_flash newlib log console ota tools ) set(REQUIRES_COMPONENTS freertos squeezelite nvs_flash esp32 spi_flash newlib log console ota tools )

View File

@@ -48,13 +48,13 @@ static void * squeezelite_thread(){
// Let's not wait on WiFi to allow squeezelite to run in bluetooth mode // Let's not wait on WiFi to allow squeezelite to run in bluetooth mode
// ESP_LOGI(TAG,"Waiting for WiFi."); // ESP_LOGI(TAG,"Waiting for WiFi.");
// while(!wait_for_wifi()){usleep(100000);}; // while(!wait_for_wifi()){usleep(100000);};
ESP_LOGD(TAG ,"Number of args received: %u",thread_parms.argc ); ESP_LOGV(TAG ,"Number of args received: %u",thread_parms.argc );
ESP_LOGD(TAG ,"Values:"); ESP_LOGV(TAG ,"Values:");
for(int i = 0;i<thread_parms.argc; i++){ for(int i = 0;i<thread_parms.argc; i++){
ESP_LOGD(TAG ," %s",thread_parms.argv[i]); ESP_LOGV(TAG ," %s",thread_parms.argv[i]);
} }
ESP_LOGD(TAG,"Starting Squeezelite runner Thread"); ESP_LOGV(TAG,"Starting Squeezelite runner Thread");
esp_pthread_cfg_t cfg = esp_pthread_get_default_config(); esp_pthread_cfg_t cfg = esp_pthread_get_default_config();
cfg.thread_name= "squeezelite-run"; cfg.thread_name= "squeezelite-run";
cfg.inherit_cfg = true; cfg.inherit_cfg = true;
@@ -80,9 +80,9 @@ static int launchsqueezelite(int argc, char **argv)
{ {
ESP_LOGV(TAG ,"Begin"); ESP_LOGV(TAG ,"Begin");
ESP_LOGD(TAG, "Parameters:"); ESP_LOGV(TAG, "Parameters:");
for(int i = 0;i<argc; i++){ for(int i = 0;i<argc; i++){
ESP_LOGD(TAG, " %s",argv[i]); ESP_LOGV(TAG, " %s",argv[i]);
} }
ESP_LOGV(TAG,"Saving args in thread structure"); ESP_LOGV(TAG,"Saving args in thread structure");

623
main/config.c Normal file
View File

@@ -0,0 +1,623 @@
/*
* Squeezelite for esp32
*
* (c) Sebastien 2019
* Philippe G. 2019, philippe_44@outlook.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
//#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
#include "config.h"
#include "nvs_utilities.h"
#include <stdio.h>
#include <string.h>
#include "esp_system.h"
#include "esp_log.h"
#include "esp_console.h"
#include "esp_vfs_dev.h"
#include "driver/uart.h"
#include "linenoise/linenoise.h"
#include "argtable3/argtable3.h"
#include "cmd_decl.h"
#include "esp_vfs_fat.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "nvs_utilities.h"
#include "cJSON.h"
#include "freertos/timers.h"
#include "freertos/event_groups.h"
#define CONFIG_COMMIT_DELAY 1000
#define LOCK_MAX_WAIT 20*CONFIG_COMMIT_DELAY
static const char * TAG = "config";
cJSON * nvs_json=NULL;
TimerHandle_t timer;
SemaphoreHandle_t config_mutex = NULL;
EventGroupHandle_t config_group;
/* @brief indicate that the ESP32 is currently connected. */
const int CONFIG_PENDING_CHANGE_BIT = BIT0;
const int CONFIG_LOAD_BIT = BIT1;
bool config_lock(TickType_t xTicksToWait);
void config_unlock();
extern esp_err_t nvs_load_config();
void config_raise_change(bool flag);
cJSON_bool config_is_entry_changed(cJSON * entry);
bool config_set_group_bit(int bit_num,bool flag);
cJSON * config_set_value_safe(nvs_type_t nvs_type, const char *key, void * value);
static void vCallbackFunction( TimerHandle_t xTimer );
void config_set_entry_changed_flag(cJSON * entry, cJSON_bool flag);
void config_init(){
ESP_LOGD(TAG, "Creating mutex for Config");
config_mutex = xSemaphoreCreateMutex();
ESP_LOGD(TAG, "Creating event group");
config_group = xEventGroupCreate();
ESP_LOGD(TAG, "Loading config from nvs");
if(nvs_json !=NULL){
cJSON_Delete(nvs_json);
}
nvs_json = cJSON_CreateObject();
config_set_group_bit(CONFIG_LOAD_BIT,true);
nvs_load_config();
config_set_group_bit(CONFIG_LOAD_BIT,false);
config_start_timer();
}
void config_start_timer(){
ESP_LOGD(TAG, "Starting config timer");
timer = xTimerCreate("configTimer", CONFIG_COMMIT_DELAY / portTICK_RATE_MS, pdFALSE, NULL, vCallbackFunction);
if( xTimerStart( timer , CONFIG_COMMIT_DELAY/ portTICK_RATE_MS ) != pdPASS ) {
ESP_LOGE(TAG, "config commitment timer failed to start.");
}
}
cJSON * config_set_value_safe(nvs_type_t nvs_type, const char *key, void * value){
char * num_buffer = NULL;
num_buffer = malloc(NUM_BUFFER_LEN);
memset(num_buffer,0x00,NUM_BUFFER_LEN);
cJSON * entry = cJSON_CreateObject();
if(entry == NULL) {
ESP_LOGE(TAG, "Unable to allocate memory for entry %s",key);
return NULL;
}
cJSON_AddNumberToObject(entry,"type", nvs_type );
switch (nvs_type) {
case NVS_TYPE_I8:
snprintf(num_buffer, NUM_BUFFER_LEN-1, "%i", *(int8_t*)value);
cJSON_AddNumberToObject(entry,"value", *(int8_t*)value );
break;
case NVS_TYPE_I16:
snprintf(num_buffer, NUM_BUFFER_LEN-1, "%i", *(int16_t*)value);
cJSON_AddNumberToObject(entry,"value", *(int16_t*)value );
break;
case NVS_TYPE_I32:
snprintf(num_buffer, NUM_BUFFER_LEN-1, "%i", *(int32_t*)value);
cJSON_AddNumberToObject(entry,"value", *(int32_t*)value );
break;
case NVS_TYPE_U8:
snprintf(num_buffer, NUM_BUFFER_LEN-1, "%u", *(uint8_t*)value);
cJSON_AddNumberToObject(entry,"value", *(uint8_t*)value );
break;
case NVS_TYPE_U16:
snprintf(num_buffer, NUM_BUFFER_LEN-1, "%u", *(uint16_t*)value);
cJSON_AddNumberToObject(entry,"value", *(uint16_t*)value );
break;
case NVS_TYPE_U32:
snprintf(num_buffer, NUM_BUFFER_LEN-1, "%u", *(uint32_t*)value);
cJSON_AddNumberToObject(entry,"value", *(uint32_t*)value );
break;
case NVS_TYPE_STR:
cJSON_AddStringToObject(entry, "value", (char *)value);
break;
case NVS_TYPE_I64:
case NVS_TYPE_U64:
default:
ESP_LOGE(TAG, "nvs type %u not supported", nvs_type);
break;
}
cJSON * existing = cJSON_GetObjectItemCaseSensitive(nvs_json, key);
if(existing!=NULL ) {
ESP_LOGV(TAG, "Changing existing entry [%s].", key);
char * exist_str = cJSON_PrintUnformatted(existing);
if(exist_str!=NULL){
ESP_LOGV(TAG,"Existing entry: %s", exist_str);
free(exist_str);
}
else {
ESP_LOGV(TAG,"Failed to print existing entry");
}
// set commit flag as equal so we can compare
cJSON * chg_flag =cJSON_AddBoolToObject(entry,"chg",config_is_entry_changed(existing));
if(!cJSON_Compare(entry,existing,false)){
char * entry_str = cJSON_PrintUnformatted(entry);
if(entry_str!=NULL){
ESP_LOGD(TAG,"New config object: \n%s", entry_str );
free(entry_str);
}
else {
ESP_LOGD(TAG,"Failed to print entry");
}
cJSON_Delete(chg_flag);
ESP_LOGI(TAG, "Setting changed flag config [%s]", key);
config_set_entry_changed_flag(entry,true);
ESP_LOGI(TAG, "Updating config [%s]", key);
cJSON_ReplaceItemInObject(nvs_json,key, entry);
entry_str = cJSON_PrintUnformatted(entry);
if(entry_str!=NULL){
ESP_LOGD(TAG,"New config: %s", entry_str );
free(entry_str);
}
else {
ESP_LOGD(TAG,"Failed to print entry");
}
}
else {
ESP_LOGD(TAG, "Config not changed. ");
}
}
else {
// This is a new entry.
config_set_entry_changed_flag(entry,true);
cJSON_AddItemToObject(nvs_json, key, entry);
}
free(num_buffer);
return entry;
}
nvs_type_t config_get_entry_type(cJSON * entry){
if(entry==NULL){
ESP_LOGE(TAG,"null pointer received!");
return 0;
}
cJSON * entry_type = cJSON_GetObjectItemCaseSensitive(entry, "type");
if(entry_type ==NULL ) {
ESP_LOGE(TAG, "Entry type not found in nvs cache for existing setting.");
return 0;
}
return entry_type->valuedouble;
}
void config_set_entry_changed_flag(cJSON * entry, cJSON_bool flag){
if(entry==NULL){
ESP_LOGE(TAG,"null pointer received!");
return;
}
bool bIsConfigLoading=((xEventGroupGetBits(config_group) & CONFIG_LOAD_BIT)!=0);
bool changedFlag=bIsConfigLoading?false:flag;
cJSON * changed = cJSON_GetObjectItemCaseSensitive(entry, "chg");
if(changed ==NULL ) {
ESP_LOGV(TAG, "Adding change flag. ");
cJSON_AddBoolToObject(entry,"chg",changedFlag);
}
else {
if(cJSON_IsTrue(changed) && changedFlag){
ESP_LOGW(TAG, "Commit flag not changed!");
}
else{
ESP_LOGV(TAG, "Updating change flag to %s",changedFlag?"TRUE":"FALSE");
cJSON_Delete(changed);
cJSON_AddBoolToObject(entry,"chg",changedFlag);
}
}
if(changedFlag) config_raise_change(true);
}
cJSON_bool config_is_entry_changed(cJSON * entry){
if(entry==NULL){
ESP_LOGE(TAG,"null pointer received!");
return true;
}
cJSON * changed = cJSON_GetObjectItemCaseSensitive(entry, "chg");
if(changed ==NULL ) {
ESP_LOGE(TAG, "Change flag not found! ");
return true;
}
return cJSON_IsTrue(changed);
}
void * config_safe_alloc_get_entry_value(nvs_type_t nvs_type, cJSON * entry){
void * value=NULL;
if(entry==NULL){
ESP_LOGE(TAG,"null pointer received!");
}
ESP_LOGV(TAG, "getting config value type %s", type_to_str(nvs_type));
cJSON * entry_value = cJSON_GetObjectItemCaseSensitive(entry, "value");
if(entry_value==NULL ) {
char * entry_str = cJSON_PrintUnformatted(entry);
if(entry_str!=NULL){
ESP_LOGE(TAG, "Missing config value!. Object: \n%s", entry_str);
free(entry_str);
}
else{
ESP_LOGE(TAG, "Missing config value");
}
return NULL;
}
nvs_type_t type = config_get_entry_type(entry);
if(nvs_type != type){
// requested value type different than the stored type
char * entry_str = cJSON_PrintUnformatted(entry);
if(entry_str!=NULL){
ESP_LOGE(TAG, "Requested value type %s, found value type %s instead, Object: \n%s", type_to_str(nvs_type), type_to_str(type),entry_str);
free(entry_str);
}
else{
ESP_LOGE(TAG, "Requested value type %s, found value type %s instead", type_to_str(nvs_type), type_to_str(type));
}
return NULL;
}
if (nvs_type == NVS_TYPE_I8) {
value=malloc(sizeof(int8_t));
*(int8_t *)value = (int8_t)entry_value->valuedouble;
} else if (nvs_type == NVS_TYPE_U8) {
value=malloc(sizeof(uint8_t));
*(uint8_t *)value = (uint8_t)entry_value->valuedouble;
} else if (nvs_type == NVS_TYPE_I16) {
value=malloc(sizeof(int16_t));
*(int16_t *)value = (int16_t)entry_value->valuedouble;
} else if (nvs_type == NVS_TYPE_U16) {
value=malloc(sizeof(uint16_t));
*(uint16_t *)value = (uint16_t)entry_value->valuedouble;
} else if (nvs_type == NVS_TYPE_I32) {
value=malloc(sizeof(int32_t));
*(int32_t *)value = (int32_t)entry_value->valuedouble;
} else if (nvs_type == NVS_TYPE_U32) {
value=malloc(sizeof(uint32_t));
*(uint32_t *)value = (uint32_t)entry_value->valuedouble;
} else if (nvs_type == NVS_TYPE_I64) {
value=malloc(sizeof(int64_t));
*(int64_t *)value = (int64_t)entry_value->valuedouble;
} else if (nvs_type == NVS_TYPE_U64) {
value=malloc(sizeof(uint64_t));
*(uint64_t *)value = (uint64_t)entry_value->valuedouble;
} else if (nvs_type == NVS_TYPE_STR) {
if(!cJSON_IsString(entry_value)){
char * entry_str = cJSON_PrintUnformatted(entry);
if(entry_str!=NULL){
ESP_LOGE(TAG, "requested value type string, config type is different. key: %s, value: %s, type %d, Object: \n%s",
entry_value->string,
entry_value->valuestring,
entry_value->type,
entry_str);
free(entry_str);
}
else {
ESP_LOGE(TAG, "requested value type string, config type is different. key: %s, value: %s, type %d",
entry_value->string,
entry_value->valuestring,
entry_value->type);
}
}
else {
value=(void *)strdup(cJSON_GetStringValue(entry_value));
if(value==NULL){
char * entry_str = cJSON_PrintUnformatted(entry);
if(entry_str!=NULL){
ESP_LOGE(TAG, "strdup failed on value for object \n%s",entry_str);
free(entry_str);
}
else {
ESP_LOGE(TAG, "strdup failed on value");
}
}
}
} else if (nvs_type == NVS_TYPE_BLOB) {
ESP_LOGE(TAG, "Unsupported type NVS_TYPE_BLOB");
}
return value;
}
void config_commit_to_nvs(){
ESP_LOGI(TAG,"Committing configuration to nvs. Locking config object.");
ESP_LOGV(TAG,"config_commit_to_nvs. Locking config object.");
if(!config_lock(LOCK_MAX_WAIT/portTICK_PERIOD_MS)){
ESP_LOGE(TAG, "config_commit_to_nvs: Unable to lock config for commit ");
return ;
}
if(nvs_json==NULL){
ESP_LOGE(TAG, ": cJSON nvs cache object not set.");
return;
}
ESP_LOGV(TAG,"config_commit_to_nvs. Config Locked!");
cJSON * entry=nvs_json->child;
while(entry!= NULL){
char * entry_str = cJSON_PrintUnformatted(entry);
if(entry_str!=NULL){
ESP_LOGV(TAG,"config_commit_to_nvs processing item %s",entry_str);
free(entry_str);
}
if(config_is_entry_changed(entry)){
ESP_LOGD(TAG, "Committing entry %s value to nvs.",(entry->string==NULL)?"UNKNOWN":entry->string);
nvs_type_t type = config_get_entry_type(entry);
void * value = config_safe_alloc_get_entry_value(type, entry);
if(value!=NULL){
esp_err_t err = store_nvs_value(type,entry->string,value);
free(value);
if(err!=ESP_OK){
char * entry_str = cJSON_PrintUnformatted(entry);
if(entry_str!=NULL){
ESP_LOGE(TAG, "Error comitting value to nvs for key %s, Object: \n%s",entry->string,entry_str);
free(entry_str);
}
else {
ESP_LOGE(TAG, "Error comitting value to nvs for key %s",entry->string);
}
}
else {
config_set_entry_changed_flag(entry, false);
}
}
else {
char * entry_str = cJSON_PrintUnformatted(entry);
if(entry_str!=NULL){
ESP_LOGE(TAG, "Unable to retrieve value. Error comitting value to nvs for key %s, Object: \n%s",entry->string,entry_str);
free(entry_str);
}
else {
ESP_LOGE(TAG, "Unable to retrieve value. Error comitting value to nvs for key %s",entry->string);
}
}
}
else {
ESP_LOGV(TAG,"config_commit_to_nvs. Item already committed. Ignoring.");
}
taskYIELD(); /* allows the freeRTOS scheduler to take over if needed. */
entry = entry->next;
}
ESP_LOGV(TAG,"config_commit_to_nvs. Resetting the global commit flag.");
config_raise_change(false);
ESP_LOGV(TAG,"config_commit_to_nvs. Releasing the lock object.");
config_unlock();
}
bool config_has_changes(){
return (xEventGroupGetBits(config_group) & CONFIG_PENDING_CHANGE_BIT)!=0;
}
bool wait_for_commit(){
bool needs_commit=(xEventGroupGetBits(config_group) & CONFIG_PENDING_CHANGE_BIT)!=0;
if(needs_commit){
ESP_LOGD(TAG,"Waiting for config commit ...");
needs_commit = (xEventGroupWaitBits(config_group, CONFIG_PENDING_CHANGE_BIT,pdFALSE, pdTRUE, (CONFIG_COMMIT_DELAY*5) / portTICK_PERIOD_MS) & CONFIG_PENDING_CHANGE_BIT)!=0;
if(needs_commit){
ESP_LOGE(TAG,"Timeout waiting for config commit.");
}
else
{
ESP_LOGI(TAG,"Config committed!");
}
}
return needs_commit;
}
bool config_lock(TickType_t xTicksToWait) {
ESP_LOGV(TAG, "Locking config json object");
if( xSemaphoreTake( config_mutex, xTicksToWait ) == pdTRUE ) {
ESP_LOGV(TAG, "config Json object locked!");
return true;
}
else {
ESP_LOGE(TAG, "Semaphore take failed. Unable to lock config Json object mutex");
return false;
}
}
void config_unlock() {
ESP_LOGV(TAG, "Unlocking json buffer!");
xSemaphoreGive( config_mutex );
}
static void vCallbackFunction( TimerHandle_t xTimer ) {
if(config_has_changes()){
ESP_LOGI(TAG, "configuration has some uncommitted entries");
config_commit_to_nvs();
}
else{
ESP_LOGV(TAG,"commit timer: commit flag not set");
}
xTimerReset( xTimer, 10 );
}
void config_raise_change(bool flag){
if(config_set_group_bit(CONFIG_PENDING_CHANGE_BIT,flag))
{
ESP_LOGD(TAG,"Config change indicator was %s",flag?"Set":"Cleared");
}
}
bool config_set_group_bit(int bit_num,bool flag){
bool result = true;
int curFlags=xEventGroupGetBits(config_group);
if((curFlags & CONFIG_LOAD_BIT) && bit_num == CONFIG_PENDING_CHANGE_BIT ){
ESP_LOGD(TAG,"Loading config, ignoring changes");
result = false;
}
if(result){
bool curBit=(xEventGroupGetBits(config_group) & bit_num);
if(curBit == flag){
ESP_LOGV(TAG,"Flag %d already %s", bit_num, flag?"Set":"Cleared");
result = false;
}
}
if(result){
ESP_LOGV(TAG,"%s Flag %d ", flag?"Setting":"Clearing",bit_num);
if(!flag){
xEventGroupClearBits(config_group, bit_num);
}
else {
xEventGroupSetBits(config_group, bit_num);
}
}
return result;
}
void config_set_default(nvs_type_t type, const char *key, void * default_value, size_t blob_size) {
if(!config_lock(LOCK_MAX_WAIT/portTICK_PERIOD_MS)){
ESP_LOGE(TAG, "Unable to lock config");
return;
}
ESP_LOGV(TAG, "Checking if key %s exists in nvs cache for type %s.", key,type_to_str(type));
cJSON * entry = cJSON_GetObjectItemCaseSensitive(nvs_json, key);
if(entry !=NULL){
ESP_LOGV(TAG, "Entry found.");
}
else {
// Value was not found
ESP_LOGW(TAG, "Adding default value for [%s].", key);
entry=config_set_value_safe(type, key, default_value);
if(entry == NULL){
ESP_LOGE(TAG, "Failed to add value to cache!");
}
char * entry_str = cJSON_PrintUnformatted(entry);
if(entry_str!=NULL){
ESP_LOGD(TAG, "Value added to default for object: \n%s",entry_str);
free(entry_str);
}
}
config_unlock();
}
void config_delete_key(const char *key){
nvs_handle nvs;
ESP_LOGD(TAG, "Deleting nvs entry for [%s]", key);
if(!config_lock(LOCK_MAX_WAIT/portTICK_PERIOD_MS)){
ESP_LOGE(TAG, "Unable to lock config for delete");
return false;
}
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) {
ESP_LOGD(TAG, "key [%s] erased from nvs.",key);
err = nvs_commit(nvs);
if (err == ESP_OK) {
ESP_LOGD(TAG, "nvs erase committed.");
}
else {
ESP_LOGE(TAG, "Unable to commit nvs erase operation for key [%s]. %s.",key,esp_err_to_name(err));
}
}
else {
ESP_LOGE(TAG, "Unable to delete nvs key [%s]. %s. ",key, esp_err_to_name(err));
}
nvs_close(nvs);
}
else {
ESP_LOGE(TAG, "Error opening nvs: %s. Unable to delete nvs key [%s].",esp_err_to_name(err),key);
}
cJSON * entry = cJSON_GetObjectItemCaseSensitive(nvs_json, key);
if(entry !=NULL){
ESP_LOGI(TAG, "Removing config key [%s]", entry->string);
cJSON_Delete(entry);
}
else {
ESP_LOGW(TAG, "Unable to remove config key [%s]: not found.", key);
}
config_unlock();
}
void * config_alloc_get(nvs_type_t nvs_type, const char *key) {
return config_alloc_get_default(nvs_type, key, NULL, 0);
}
void * config_alloc_get_default(nvs_type_t nvs_type, const char *key, void * default_value, size_t blob_size) {
void * value = NULL;
ESP_LOGV(TAG, "Retrieving key %s from nvs cache for type %s.", key,type_to_str(nvs_type));
if(nvs_json==NULL){
ESP_LOGE(TAG,"configuration not loaded!");
return value;
}
if(!config_lock(LOCK_MAX_WAIT/portTICK_PERIOD_MS)){
ESP_LOGE(TAG, "Unable to lock config");
return value;
}
ESP_LOGD(TAG,"Getting config entry for key %s",key);
cJSON * entry = cJSON_GetObjectItemCaseSensitive(nvs_json, key);
if(entry !=NULL){
ESP_LOGV(TAG, "Entry found, getting value.");
value = config_safe_alloc_get_entry_value(nvs_type, entry);
}
else if(default_value!=NULL){
// Value was not found
ESP_LOGW(TAG, "Adding new config value for key [%s]",key);
entry=config_set_value_safe(nvs_type, key, default_value);
if(entry == NULL){
ESP_LOGE(TAG, "Failed to add value to cache");
}
else {
char * entry_str = cJSON_PrintUnformatted(entry);
if(entry_str!=NULL){
ESP_LOGV(TAG, "Value added configuration object for key [%s]: \n%s", entry->string,entry_str);
free(entry_str);
}
else {
ESP_LOGV(TAG, "Value added configuration object for key [%s]", entry->string);
}
value = config_safe_alloc_get_entry_value(nvs_type, entry);
}
}
else{
ESP_LOGW(TAG,"Value not found for key %s",key);
}
config_unlock();
return value;
}
char * config_alloc_get_json(bool bFormatted){
char * json_buffer = NULL;
if(!config_lock(LOCK_MAX_WAIT/portTICK_PERIOD_MS)){
ESP_LOGE(TAG, "Unable to lock config after %d ms",LOCK_MAX_WAIT);
return strdup("{\"error\":\"Unable to lock configuration object.\"}");
}
if(bFormatted){
json_buffer= cJSON_Print(nvs_json);
}
else {
json_buffer= cJSON_PrintUnformatted(nvs_json);
}
config_unlock();
return json_buffer;
}
esp_err_t config_set_value(nvs_type_t nvs_type, const char *key, void * value){
esp_err_t result = ESP_OK;
if(!config_lock(LOCK_MAX_WAIT/portTICK_PERIOD_MS)){
ESP_LOGE(TAG, "Unable to lock config after %d ms",LOCK_MAX_WAIT);
result = ESP_FAIL;
}
cJSON * entry = config_set_value_safe(nvs_type, key, value);
if(entry == NULL){
result = ESP_FAIL;
}
else{
char * entry_str = cJSON_PrintUnformatted(entry);
if(entry_str!=NULL){
ESP_LOGV(TAG,"config_set_value result: \n%s",entry_str);
free(entry_str);
}
else {
ESP_LOGV(TAG,"config_set_value completed");
}
}
config_unlock();
return result;
}

24
main/config.h Normal file
View File

@@ -0,0 +1,24 @@
#pragma once
#include <stdio.h>
#include <string.h>
#include "esp_system.h"
#include "nvs_utilities.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
bool config_has_uncommitted();
void config_commit_to_nvs();
void config_start_timer();
void config_init();
void * config_alloc_get_default(nvs_type_t type, const char *key, void * default_value, size_t blob_size);
void config_delete_key(const char *key);
void config_set_default(nvs_type_t type, const char *key, void * default_value, size_t blob_size);
void * config_alloc_get(nvs_type_t nvs_type, const char *key) ;
bool wait_for_commit();
char * config_alloc_get_json(bool bFormatted);
esp_err_t config_set_value(nvs_type_t nvs_type, const char *key, void * value);

View File

@@ -55,7 +55,7 @@ void process_autoexec(){
char * autoexec_value=NULL; char * autoexec_value=NULL;
uint8_t autoexec_flag=0; uint8_t autoexec_flag=0;
char * str_flag = get_nvs_value_alloc(NVS_TYPE_STR, "autoexec"); char * str_flag = config_alloc_get(NVS_TYPE_STR, "autoexec");
if(!bypass_wifi_manager){ if(!bypass_wifi_manager){
ESP_LOGW(TAG, "Procesing autoexec commands while wifi_manager active. Wifi related commands will be ignored."); ESP_LOGW(TAG, "Procesing autoexec commands while wifi_manager active. Wifi related commands will be ignored.");
} }
@@ -65,12 +65,12 @@ void process_autoexec(){
if(str_flag !=NULL ){ if(str_flag !=NULL ){
autoexec_flag=atoi(str_flag); autoexec_flag=atoi(str_flag);
ESP_LOGI(TAG,"autoexec flag value found with value %u, from string value: %s", autoexec_flag, str_flag); ESP_LOGI(TAG,"autoexec is set to %s auto-process", autoexec_flag>0?"perform":"skip");
if(autoexec_flag == 1) { if(autoexec_flag == 1) {
do { do {
snprintf(autoexec_name,sizeof(autoexec_name)-1,"autoexec%u",i++); snprintf(autoexec_name,sizeof(autoexec_name)-1,"autoexec%u",i++);
ESP_LOGD(TAG,"Getting command name %s", autoexec_name); ESP_LOGD(TAG,"Getting command name %s", autoexec_name);
autoexec_value= get_nvs_value_alloc(NVS_TYPE_STR, autoexec_name); autoexec_value= config_alloc_get(NVS_TYPE_STR, autoexec_name);
if(autoexec_value!=NULL ){ if(autoexec_value!=NULL ){
if(!bypass_wifi_manager && strstr(autoexec_value, "join ")!=NULL ){ if(!bypass_wifi_manager && strstr(autoexec_value, "join ")!=NULL ){
ESP_LOGW(TAG,"Ignoring wifi join command."); ESP_LOGW(TAG,"Ignoring wifi join command.");
@@ -97,11 +97,7 @@ void process_autoexec(){
} }
else else
{ {
ESP_LOGD(TAG,"No matching command found for name autoexec. Adding default entries"); ESP_LOGD(TAG,"No matching command found for name autoexec.");
char autoexec_dft[]="0";
char autoexec1_dft[256]="squeezelite -o I2S -b 500:2000 -d all=info -M esp32";
store_nvs_value(NVS_TYPE_STR,"autoexec",autoexec_dft);
store_nvs_value(NVS_TYPE_STR,"autoexec1",autoexec1_dft);
} }
} }
@@ -262,6 +258,8 @@ static void * console_thread() {
run_command(line); run_command(line);
/* linenoise allocates line buffer on the heap, so need to free it */ /* linenoise allocates line buffer on the heap, so need to free it */
linenoiseFree(line); linenoiseFree(line);
config_commit_to_nvs();
taskYIELD();
} }
return NULL; return NULL;
} }

View File

@@ -44,6 +44,8 @@
#include "wifi_manager.h" #include "wifi_manager.h"
#include "squeezelite-ota.h" #include "squeezelite-ota.h"
#include <math.h> #include <math.h>
#include "config.h"
EventGroupHandle_t wifi_event_group; EventGroupHandle_t wifi_event_group;
bool enable_bt_sink=false; bool enable_bt_sink=false;
@@ -52,16 +54,17 @@ bool jack_mutes_amp=false;
bool bypass_wifi_manager=false; bool bypass_wifi_manager=false;
const int CONNECTED_BIT = BIT0; const int CONNECTED_BIT = BIT0;
#define JOIN_TIMEOUT_MS (10000) #define JOIN_TIMEOUT_MS (10000)
#define LOCAL_MAC_SIZE 20
static const char TAG[] = "esp_app_main"; static const char TAG[] = "esp_app_main";
#define DEFAULT_HOST_NAME "squeezelite"
char * fwurl = NULL; char * fwurl = NULL;
#ifdef CONFIG_SQUEEZEAMP #ifdef CONFIG_SQUEEZEAMP
#define LED_GREEN_GPIO 12 #define LED_GREEN_GPIO 12
#define LED_RED_GPIO 13 #define LED_RED_GPIO 13
#else #else
#define LED_GREEN_GPIO 0 #define LED_GREEN_GPIO -1
#define LED_RED_GPIO 0 #define LED_RED_GPIO -1
#endif #endif
static bool bWifiConnected=false; static bool bWifiConnected=false;
@@ -96,61 +99,14 @@ bool wait_for_wifi(){
} }
return connected; return connected;
} }
static void initialize_nvs() {
ESP_LOGI(TAG,"Initializing nvs from flash");
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_LOGW(TAG,"Error %s. Erasing nvs flash", esp_err_to_name(err));
ESP_ERROR_CHECK(nvs_flash_erase());
err = nvs_flash_init();
}
ESP_ERROR_CHECK(err);
ESP_LOGI(TAG,"Initializing nvs from partition %s",settings_partition);
err = nvs_flash_init_partition(settings_partition);
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_LOGW(TAG,"Error %s. Erasing nvs on partition %s",esp_err_to_name(err),settings_partition);
ESP_ERROR_CHECK(nvs_flash_erase_partition(settings_partition));
err = nvs_flash_init_partition(settings_partition);
}
if(err!=ESP_OK){
ESP_LOGE(TAG,"nvs init completed with error %s",esp_err_to_name(err));
}
ESP_ERROR_CHECK(err);
ESP_LOGD(TAG,"nvs init completed");
}
char * process_ota_url(){ char * process_ota_url(){
nvs_handle nvs;
ESP_LOGI(TAG,"Checking for update url"); ESP_LOGI(TAG,"Checking for update url");
char * fwurl=get_nvs_value_alloc(NVS_TYPE_STR, "fwurl"); char * fwurl=config_alloc_get(NVS_TYPE_STR, "fwurl");
if(fwurl!=NULL) if(fwurl!=NULL)
{ {
ESP_LOGD(TAG,"Deleting nvs entry for Firmware URL %s", fwurl); ESP_LOGD(TAG,"Deleting nvs entry for Firmware URL %s", fwurl);
esp_err_t err = nvs_open_from_partition(settings_partition, current_namespace, NVS_READWRITE, &nvs); config_delete_key("fwurl");
if (err == ESP_OK) {
err = nvs_erase_key(nvs, "fwurl");
if (err == ESP_OK) {
ESP_LOGD(TAG,"Firmware url erased from nvs.");
err = nvs_commit(nvs);
if (err == ESP_OK) {
ESP_LOGI(TAG, "Value with key '%s' erased", "fwurl");
ESP_LOGD(TAG,"nvs erase committed.");
}
else
{
ESP_LOGE(TAG,"Unable to commit nvs erase operation. Error : %s.",esp_err_to_name(err));
}
}
else
{
ESP_LOGE(TAG,"Error : %s. Unable to delete firmware url key.",esp_err_to_name(err));
}
nvs_close(nvs);
}
else
{
ESP_LOGE(TAG,"Error opening nvs: %s. Unable to delete firmware url key.",esp_err_to_name(err));
}
} }
return fwurl; return fwurl;
} }
@@ -164,7 +120,7 @@ char * process_ota_url(){
//CONFIG_WIFI_MANAGER_MAX_RETRY=2 //CONFIG_WIFI_MANAGER_MAX_RETRY=2
u16_t get_adjusted_volume(u16_t volume){ u16_t get_adjusted_volume(u16_t volume){
char * str_factor = get_nvs_value_alloc_default(NVS_TYPE_STR, "volumefactor", "3", 0); char * str_factor = config_alloc_get_default(NVS_TYPE_STR, "volumefactor", "3", 0);
if(str_factor != NULL ){ if(str_factor != NULL ){
float factor = atof(str_factor); float factor = atof(str_factor);
@@ -175,54 +131,103 @@ u16_t get_adjusted_volume(u16_t volume){
ESP_LOGW(TAG,"Error retrieving volume factor. Returning unmodified volume level. "); ESP_LOGW(TAG,"Error retrieving volume factor. Returning unmodified volume level. ");
return volume; return volume;
} }
} }
void register_default_nvs(){ void register_default_nvs(){
uint8_t mac[6];
char macStr[LOCAL_MAC_SIZE+1];
char default_ap_name[strlen(CONFIG_DEFAULT_AP_SSID)+sizeof(macStr)];
char default_host_name[strlen(DEFAULT_HOST_NAME)+sizeof(macStr)];
char default_command_line[strlen(CONFIG_DEFAULT_COMMAND_LINE)+sizeof(macStr)];
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "bt_sink_name", CONFIG_BT_NAME); esp_read_mac((uint8_t *)&mac, ESP_MAC_WIFI_STA);
nvs_value_set_default(NVS_TYPE_STR, "bt_sink_name", CONFIG_BT_NAME, 0); snprintf(macStr, LOCAL_MAC_SIZE-1,"-%x%x%x", mac[3], mac[4], mac[5]);
strcpy(default_ap_name,CONFIG_DEFAULT_AP_SSID);
strcat(default_ap_name,macStr);
strcpy(default_host_name,DEFAULT_HOST_NAME);
strcat(default_host_name,macStr);
if(!strstr(CONFIG_DEFAULT_COMMAND_LINE, "-n %s")){
snprintf(default_command_line, sizeof(default_command_line)-1,CONFIG_DEFAULT_COMMAND_LINE,default_host_name);
}
else{
strncpy(default_command_line, CONFIG_DEFAULT_COMMAND_LINE,sizeof(default_command_line)-1);
strncat(default_command_line, "-n ",sizeof(default_command_line)-1);
strncat(default_command_line, default_host_name,sizeof(default_command_line)-1);
}
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "autoexec", "1");
config_set_default(NVS_TYPE_STR,"autoexec","1", 0);
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "autoexec1",default_command_line);
config_set_default(NVS_TYPE_STR,"autoexec1",default_command_line,0);
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "volumefactor", "3");
config_set_default(NVS_TYPE_STR, "volumefactor", "3", 0);
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "bt_name", CONFIG_BT_NAME);
config_set_default(NVS_TYPE_STR, "bt_name", CONFIG_BT_NAME, 0);
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "bt_sink_pin", STR(CONFIG_BT_SINK_PIN)); ESP_LOGD(TAG,"Registering default value for key %s, value %s", "bt_sink_pin", STR(CONFIG_BT_SINK_PIN));
nvs_value_set_default(NVS_TYPE_STR, "bt_sink_pin", STR(CONFIG_BT_SINK_PIN), 0); config_set_default(NVS_TYPE_STR, "bt_sink_pin", STR(CONFIG_BT_SINK_PIN), 0);
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "host_name", "squeezelite-esp32"); ESP_LOGD(TAG,"Registering default value for key %s, value %s", "host_name", default_host_name);
nvs_value_set_default(NVS_TYPE_STR, "host_name", "squeezelite-esp32", 0); config_set_default(NVS_TYPE_STR, "host_name", default_host_name, 0);
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "release_url", SQUEEZELITE_ESP32_RELEASE_URL); ESP_LOGD(TAG,"Registering default value for key %s, value %s", "release_url", SQUEEZELITE_ESP32_RELEASE_URL);
nvs_value_set_default(NVS_TYPE_STR, "release_url", SQUEEZELITE_ESP32_RELEASE_URL, 0); config_set_default(NVS_TYPE_STR, "release_url", SQUEEZELITE_ESP32_RELEASE_URL, 0);
ESP_LOGD(TAG,"Registering default value for key %s, value %s","ap_ip_address",CONFIG_DEFAULT_AP_IP ); ESP_LOGD(TAG,"Registering default value for key %s, value %s","ap_ip_address",CONFIG_DEFAULT_AP_IP );
nvs_value_set_default(NVS_TYPE_STR, "ap_ip_address",CONFIG_DEFAULT_AP_IP , 0); config_set_default(NVS_TYPE_STR, "ap_ip_address",CONFIG_DEFAULT_AP_IP , 0);
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "ap_ip_gateway",CONFIG_DEFAULT_AP_GATEWAY ); ESP_LOGD(TAG,"Registering default value for key %s, value %s", "ap_ip_gateway",CONFIG_DEFAULT_AP_GATEWAY );
nvs_value_set_default(NVS_TYPE_STR, "ap_ip_gateway",CONFIG_DEFAULT_AP_GATEWAY , 0); config_set_default(NVS_TYPE_STR, "ap_ip_gateway",CONFIG_DEFAULT_AP_GATEWAY , 0);
ESP_LOGD(TAG,"Registering default value for key %s, value %s","ap_ip_netmask",CONFIG_DEFAULT_AP_NETMASK ); ESP_LOGD(TAG,"Registering default value for key %s, value %s","ap_ip_netmask",CONFIG_DEFAULT_AP_NETMASK );
nvs_value_set_default(NVS_TYPE_STR, "ap_ip_netmask",CONFIG_DEFAULT_AP_NETMASK , 0); config_set_default(NVS_TYPE_STR, "ap_ip_netmask",CONFIG_DEFAULT_AP_NETMASK , 0);
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "ap_channel",STR(CONFIG_DEFAULT_AP_CHANNEL)); ESP_LOGD(TAG,"Registering default value for key %s, value %s", "ap_channel",STR(CONFIG_DEFAULT_AP_CHANNEL));
nvs_value_set_default(NVS_TYPE_STR, "ap_channel",STR(CONFIG_DEFAULT_AP_CHANNEL) , 0); config_set_default(NVS_TYPE_STR, "ap_channel",STR(CONFIG_DEFAULT_AP_CHANNEL) , 0);
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "ap_ssid",CONFIG_DEFAULT_AP_SSID ); ESP_LOGD(TAG,"Registering default value for key %s, value %s", "ap_ssid", default_ap_name);
nvs_value_set_default(NVS_TYPE_STR, "ap_ssid",CONFIG_DEFAULT_AP_SSID , 0); config_set_default(NVS_TYPE_STR, "ap_ssid",default_ap_name , 0);
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "ap_password", CONFIG_DEFAULT_AP_PASSWORD); ESP_LOGD(TAG,"Registering default value for key %s, value %s", "ap_pwd", CONFIG_DEFAULT_AP_PASSWORD);
nvs_value_set_default(NVS_TYPE_STR, "ap_password", CONFIG_DEFAULT_AP_PASSWORD, 0); config_set_default(NVS_TYPE_STR, "ap_pwd", CONFIG_DEFAULT_AP_PASSWORD, 0);
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "airplay_name",CONFIG_AIRPLAY_NAME); ESP_LOGD(TAG,"Registering default value for key %s, value %s", "airplay_name",CONFIG_AIRPLAY_NAME);
nvs_value_set_default(NVS_TYPE_STR, "airplay_name",CONFIG_AIRPLAY_NAME , 0); config_set_default(NVS_TYPE_STR, "airplay_name",CONFIG_AIRPLAY_NAME , 0);
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "airplay_port", CONFIG_AIRPLAY_PORT); ESP_LOGD(TAG,"Registering default value for key %s, value %s", "airplay_port", CONFIG_AIRPLAY_PORT);
nvs_value_set_default(NVS_TYPE_STR, "airplay_port", CONFIG_AIRPLAY_PORT, 0); config_set_default(NVS_TYPE_STR, "airplay_port", CONFIG_AIRPLAY_PORT, 0);
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "a2dp_sink_name", CONFIG_A2DP_SINK_NAME); ESP_LOGD(TAG,"Registering default value for key %s, value %s", "a2dp_sink_name", CONFIG_A2DP_SINK_NAME);
nvs_value_set_default(NVS_TYPE_STR, "a2dp_sink_name", CONFIG_A2DP_SINK_NAME, 0); config_set_default(NVS_TYPE_STR, "a2dp_sink_name", CONFIG_A2DP_SINK_NAME, 0);
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "a2dp_dev_name", CONFIG_A2DP_DEV_NAME); ESP_LOGD(TAG,"Registering default value for key %s, value %s", "a2dp_dev_name", CONFIG_A2DP_DEV_NAME);
nvs_value_set_default(NVS_TYPE_STR, "a2dp_dev_name", CONFIG_A2DP_DEV_NAME, 0); config_set_default(NVS_TYPE_STR, "a2dp_dev_name", CONFIG_A2DP_DEV_NAME, 0);
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "bypass_wm", "0"); ESP_LOGD(TAG,"Registering default value for key %s, value %s", "bypass_wm", "0");
nvs_value_set_default(NVS_TYPE_STR, "bypass_wm", "0", 0); config_set_default(NVS_TYPE_STR, "bypass_wm", "0", 0);
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "enable_bt_sink", STR(CONFIG_BT_SINK)); ESP_LOGD(TAG,"Registering default value for key %s, value %s", "enable_bt_sink", STR(CONFIG_BT_SINK));
char * flag = get_nvs_value_alloc_default(NVS_TYPE_STR, "enable_bt_sink", STR(CONFIG_BT_SINK), 0); char * flag = config_alloc_get_default(NVS_TYPE_STR, "enable_bt_sink", STR(CONFIG_BT_SINK), 0);
if(flag !=NULL){
enable_bt_sink= (strcmp(flag,"1")==0 ||strcasecmp(flag,"y")==0); enable_bt_sink= (strcmp(flag,"1")==0 ||strcasecmp(flag,"y")==0);
free(flag); free(flag);
}
else {
ESP_LOGE(TAG,"Unable to get flag 'enable_bt_sink'");
}
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "enable_airplay", STR(CONFIG_AIRPLAY_SINK)); ESP_LOGD(TAG,"Registering default value for key %s, value %s", "enable_airplay", STR(CONFIG_AIRPLAY_SINK));
flag = get_nvs_value_alloc_default(NVS_TYPE_STR, "enable_airplay", STR(CONFIG_AIRPLAY_SINK), 0); flag = config_alloc_get_default(NVS_TYPE_STR, "enable_airplay", STR(CONFIG_AIRPLAY_SINK), 0);
if(flag !=NULL){
enable_airplay= (strcmp(flag,"1")==0 ||strcasecmp(flag,"y")==0); enable_airplay= (strcmp(flag,"1")==0 ||strcasecmp(flag,"y")==0);
free(flag); free(flag);
}
else {
ESP_LOGE(TAG,"Unable to get flag 'enable_airplay'");
}
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "jack_mutes_amp", "n"); ESP_LOGD(TAG,"Registering default value for key %s, value %s", "jack_mutes_amp", "n");
flag = get_nvs_value_alloc_default(NVS_TYPE_STR, "jack_mutes_amp", "n", 0); flag = config_alloc_get_default(NVS_TYPE_STR, "jack_mutes_amp", "n", 0);
if(flag !=NULL){
jack_mutes_amp= (strcmp(flag,"1")==0 ||strcasecmp(flag,"y")==0); jack_mutes_amp= (strcmp(flag,"1")==0 ||strcasecmp(flag,"y")==0);
free(flag); free(flag);
}
else {
ESP_LOGE(TAG,"Unable to get flag 'jack_mutes_amp'");
}
ESP_LOGD(TAG,"Done setting default values in nvs."); ESP_LOGD(TAG,"Done setting default values in nvs.");
} }
@@ -238,6 +243,9 @@ void app_main()
ESP_LOGI(TAG,"Starting app_main"); ESP_LOGI(TAG,"Starting app_main");
initialize_nvs(); initialize_nvs();
ESP_LOGI(TAG,"Setting up config subsystem.");
config_init();
ESP_LOGD(TAG,"Registering default values"); ESP_LOGD(TAG,"Registering default values");
register_default_nvs(); register_default_nvs();
@@ -246,7 +254,7 @@ void app_main()
ESP_LOGD(TAG,"Getting value for WM bypass, nvs 'bypass_wm'"); ESP_LOGD(TAG,"Getting value for WM bypass, nvs 'bypass_wm'");
char * bypass_wm = get_nvs_value_alloc_default(NVS_TYPE_STR, "bypass_wm", "0", 0); char * bypass_wm = config_alloc_get_default(NVS_TYPE_STR, "bypass_wm", "0", 0);
if(bypass_wm==NULL) if(bypass_wm==NULL)
{ {
ESP_LOGE(TAG, "Unable to retrieve the Wifi Manager bypass flag"); ESP_LOGE(TAG, "Unable to retrieve the Wifi Manager bypass flag");
@@ -257,6 +265,7 @@ void app_main()
} }
ESP_LOGD(TAG,"Configuring Green led"); ESP_LOGD(TAG,"Configuring Green led");
led_config(LED_GREEN, LED_GREEN_GPIO, 0); led_config(LED_GREEN, LED_GREEN_GPIO, 0);
ESP_LOGD(TAG,"Configuring Red led"); ESP_LOGD(TAG,"Configuring Red led");
led_config(LED_RED, LED_RED_GPIO, 0); led_config(LED_RED, LED_RED_GPIO, 0);

View File

@@ -1,3 +1,4 @@
//#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
#include "nvs_utilities.h" #include "nvs_utilities.h"
#include <stdio.h> #include <stdio.h>
@@ -13,10 +14,78 @@
#include "esp_vfs_fat.h" #include "esp_vfs_fat.h"
#include "nvs.h" #include "nvs.h"
#include "nvs_flash.h" #include "nvs_flash.h"
#include "nvs_utilities.h"
const char current_namespace[] = "config"; const char current_namespace[] = "config";
const char settings_partition[] = "settings"; const char settings_partition[] = "settings";
static const char * TAG = "platform_esp32"; static const char * TAG = "nvs_utilities";
void initialize_nvs() {
ESP_LOGI(TAG, "Initializing flash nvs ");
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_LOGW(TAG, "%s. Erasing nvs flash", esp_err_to_name(err));
ESP_ERROR_CHECK(nvs_flash_erase());
err = nvs_flash_init();
}
if(err != ESP_OK){
ESP_LOGE(TAG, "nvs_flash_init failed. %s.", esp_err_to_name(err));
}
ESP_ERROR_CHECK(err);
ESP_LOGI(TAG, "Initializing nvs partition %s",settings_partition);
err = nvs_flash_init_partition(settings_partition);
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_LOGW(TAG, "%s. Erasing nvs on partition %s",esp_err_to_name(err),settings_partition);
ESP_ERROR_CHECK(nvs_flash_erase_partition(settings_partition));
err = nvs_flash_init_partition(settings_partition);
}
if(err!=ESP_OK){
ESP_LOGE(TAG, "nvs_flash_init_partition failed. %s",esp_err_to_name(err));
}
ESP_ERROR_CHECK(err);
ESP_LOGD(TAG, "nvs init completed");
}
esp_err_t nvs_load_config(){
nvs_entry_info_t info;
esp_err_t err = ESP_OK;
size_t malloc_int = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
size_t malloc_spiram = heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
nvs_iterator_t it = nvs_entry_find(settings_partition, NULL, NVS_TYPE_ANY);
if(it == NULL) {
ESP_LOGW(TAG, "empty nvs partition %s, namespace %s",settings_partition,current_namespace );
}
while (it != NULL) {
nvs_entry_info(it, &info);
if(strstr(info.namespace_name, current_namespace)) {
void * value = get_nvs_value_alloc(info.type,info.key);
if(value==NULL)
{
ESP_LOGE(TAG, "nvs read failed.");
return ESP_FAIL;
}
config_set_value(info.type, info.key, value);
free(value );
}
it = nvs_entry_next(it);
}
char * json_string= config_alloc_get_json(false);
if(json_string!=NULL) {
ESP_LOGD(TAG, "config json : %s\n", json_string);
free(json_string);
}
ESP_LOGD(TAG,"Config memory usage. Heap internal:%zu (min:%zu) (used:%zu) external:%zu (min:%zu) (used:%zd)",
heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL),
malloc_int-heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
heap_caps_get_free_size(MALLOC_CAP_SPIRAM),
heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM),
malloc_spiram -heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
return err;
}
esp_err_t store_nvs_value(nvs_type_t type, const char *key, void * data) { esp_err_t store_nvs_value(nvs_type_t type, const char *key, void * data) {
if (type == NVS_TYPE_BLOB) if (type == NVS_TYPE_BLOB)
@@ -67,33 +136,6 @@ esp_err_t store_nvs_value_len(nvs_type_t type, const char *key, void * data,
nvs_close(nvs); nvs_close(nvs);
return err; return err;
} }
void nvs_value_set_default(nvs_type_t type, const char *key, void * default_value, size_t blob_size) {
free(get_nvs_value_alloc_default(type, key, default_value, blob_size));
}
void * get_nvs_value_alloc_default(nvs_type_t type, const char *key, void * default_value, size_t blob_size) {
void * current_value = get_nvs_value_alloc(type, key);
if(current_value == NULL && default_value != NULL){
if(type == NVS_TYPE_BLOB && blob_size == 0){
ESP_LOGE(TAG,"Unable to store default value for BLOB object' blob size was not specified");
return NULL;
}
else {
esp_err_t err = store_nvs_value_len(type, key, default_value, blob_size);
if(err!=ESP_OK){
ESP_LOGE(TAG,"Unable to store default nvs value for key %s. Error: %s", key,esp_err_to_name(err));
return NULL;
}
else{
ESP_LOGI(TAG,"Stored new default value for key %s", key);
}
}
}
if(current_value == NULL){
current_value = get_nvs_value_alloc(type, key);
}
return current_value;
}
void * get_nvs_value_alloc(nvs_type_t type, const char *key) { void * get_nvs_value_alloc(nvs_type_t type, const char *key) {
nvs_handle nvs; nvs_handle nvs;
esp_err_t err; esp_err_t err;

View File

@@ -2,18 +2,20 @@
#include "esp_err.h" #include "esp_err.h"
#include "nvs.h" #include "nvs.h"
#include "trace.h" #include "trace.h"
#include "config.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
extern const char current_namespace[]; extern const char current_namespace[];
extern const char settings_partition[]; extern const char settings_partition[];
#define NUM_BUFFER_LEN 101
void initialize_nvs();
esp_err_t store_nvs_value_len(nvs_type_t type, const char *key, void * data, size_t data_len); esp_err_t store_nvs_value_len(nvs_type_t type, const char *key, void * data, size_t data_len);
esp_err_t store_nvs_value(nvs_type_t type, const char *key, void * data); esp_err_t store_nvs_value(nvs_type_t type, const char *key, void * data);
esp_err_t get_nvs_value(nvs_type_t type, const char *key, void*value, const uint8_t buf_size); esp_err_t get_nvs_value(nvs_type_t type, const char *key, void*value, const uint8_t buf_size);
void * get_nvs_value_alloc(nvs_type_t type, const char *key); void * get_nvs_value_alloc(nvs_type_t type, const char *key);
esp_err_t erase_nvs(const char *key); esp_err_t erase_nvs(const char *key);
void * get_nvs_value_alloc_default(nvs_type_t type, const char *key, void * default_value, size_t blob_size);
void nvs_value_set_default(nvs_type_t type, const char *key, void * default_value, size_t blob_size);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif