瀏覽代碼

Console support WIP!

Some instabilities to tackle. BT Ring buffer were taken out.  DAC is
crashing with stack overflow.  So does A2DP after playing for a little
while.  This needs to be investigated.
Sebastien Leclerc 5 年之前
父節點
當前提交
8500b2180d
共有 41 個文件被更改,包括 3419 次插入657 次删除
  1. 1 1
      .gitignore
  2. 1 1
      .settings/language.settings.xml
  3. 7 0
      components/cmd_nvs/CMakeLists.txt
  4. 584 0
      components/cmd_nvs/cmd_nvs.c
  5. 21 0
      components/cmd_nvs/cmd_nvs.h
  6. 10 0
      components/cmd_nvs/component.mk
  7. 7 0
      components/cmd_system/CMakeLists.txt
  8. 342 0
      components/cmd_system/cmd_system.c
  9. 20 0
      components/cmd_system/cmd_system.h
  10. 10 0
      components/cmd_system/component.mk
  11. 7 0
      components/platform_esp32/CMakeLists.txt
  12. 12 15
      components/platform_esp32/bt_app_core.c
  13. 3 2
      components/platform_esp32/bt_app_core.h
  14. 21 0
      components/platform_esp32/cmd_decl.h
  15. 173 0
      components/platform_esp32/cmd_squeezelite.c
  16. 13 0
      components/platform_esp32/cmd_squeezelite.h
  17. 185 0
      components/platform_esp32/cmd_wifi.c
  18. 21 0
      components/platform_esp32/cmd_wifi.h
  19. 10 0
      components/platform_esp32/component.mk
  20. 316 0
      components/platform_esp32/console.c
  21. 18 0
      components/platform_esp32/console.h
  22. 147 0
      components/platform_esp32/esp_app_main.c
  23. 179 0
      components/platform_esp32/nvs_utilities.c
  24. 13 0
      components/platform_esp32/nvs_utilities.h
  25. 8 13
      components/platform_esp32/perf_trace.h
  26. 222 296
      components/platform_esp32/platform_esp32.c
  27. 165 0
      components/platform_esp32/platform_esp32.h
  28. 14 13
      main/Kconfig.projbuild
  29. 2 1
      main/component.mk
  30. 0 240
      main/esp_app_main.c
  31. 14 10
      main/main.c
  32. 3 3
      main/output.c
  33. 3 3
      main/output_bt.c
  34. 41 29
      main/output_dac.c
  35. 0 14
      main/perf_trace.c
  36. 10 10
      main/squeezelite.h
  37. 1 1
      main/stream.c
  38. 21 2
      main/utils.c
  39. 3 1
      partitions.csv
  40. 776 0
      sdkconfig
  41. 15 2
      sdkconfig.defaults

+ 1 - 1
.gitignore

@@ -32,7 +32,6 @@
 
 # Build files with potential private info
 build/
-sdkconfig
 sdkconfig.old
 
 # =========================
@@ -64,3 +63,4 @@ $RECYCLE.BIN/
 *.save
 libs/
 
+/cdump.cmd

+ 1 - 1
.settings/language.settings.xml

@@ -5,7 +5,7 @@
 			<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
 			<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
 			<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuildCommandParser" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser" keep-relative-paths="false" name="CDT GCC Build Output Parser" parameter="xtensa-esp32-elf-(gcc|g\+\+|c\+\+|cc|cpp|clang)" prefer-non-shared="true"/>
-			<provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-1625153668526123159" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="xtensa-esp32-elf-gcc ${FLAGS} -std=c++11 -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+			<provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-869409282784451881" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="xtensa-esp32-elf-gcc ${FLAGS} -std=c++11 -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
 				<language-scope id="org.eclipse.cdt.core.gcc"/>
 				<language-scope id="org.eclipse.cdt.core.g++"/>
 			</provider>

+ 7 - 0
components/cmd_nvs/CMakeLists.txt

@@ -0,0 +1,7 @@
+set(COMPONENT_ADD_INCLUDEDIRS .)
+
+set(COMPONENT_SRCS "cmd_nvs.c")
+
+set(COMPONENT_REQUIRES console nvs_flash)
+
+register_component()

+ 584 - 0
components/cmd_nvs/cmd_nvs.c

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

+ 21 - 0
components/cmd_nvs/cmd_nvs.h

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

+ 10 - 0
components/cmd_nvs/component.mk

@@ -0,0 +1,10 @@
+#
+# Component Makefile
+#
+# This Makefile should, at the very least, just include $(SDK_PATH)/Makefile. By default,
+# this will take the sources in the src/ directory, compile them and link them into
+# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
+# please read the SDK documents if you need to do this.
+#
+
+COMPONENT_ADD_INCLUDEDIRS := .

+ 7 - 0
components/cmd_system/CMakeLists.txt

@@ -0,0 +1,7 @@
+set(COMPONENT_ADD_INCLUDEDIRS .)
+
+set(COMPONENT_SRCS "cmd_system.c")
+
+set(COMPONENT_REQUIRES console spi_flash)
+
+register_component()

+ 342 - 0
components/cmd_system/cmd_system.c

@@ -0,0 +1,342 @@
+/* Console example — various system commands
+
+   This example code is in the Public Domain (or CC0 licensed, at your option.)
+
+   Unless required by applicable law or agreed to in writing, this
+   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+   CONDITIONS OF ANY KIND, either express or implied.
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include "esp_log.h"
+#include "esp_console.h"
+#include "esp_system.h"
+#include "esp_sleep.h"
+#include "esp_spi_flash.h"
+#include "driver/rtc_io.h"
+#include "driver/uart.h"
+#include "argtable3/argtable3.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "soc/rtc_cntl_reg.h"
+#include "esp32/rom/uart.h"
+#include "cmd_system.h"
+#include "sdkconfig.h"
+
+#ifdef CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS
+#define WITH_TASKS_INFO 1
+#endif
+
+static const char * TAG = "platform_esp32";
+
+static void register_free();
+static void register_heap();
+static void register_version();
+static void register_restart();
+static void register_deep_sleep();
+static void register_light_sleep();
+#if WITH_TASKS_INFO
+static void register_tasks();
+#endif
+
+void register_system()
+{
+    register_free();
+    register_heap();
+    register_version();
+    register_restart();
+    register_deep_sleep();
+    register_light_sleep();
+#if WITH_TASKS_INFO
+    register_tasks();
+#endif
+}
+
+/* 'version' command */
+static int get_version(int argc, char **argv)
+{
+    esp_chip_info_t info;
+    esp_chip_info(&info);
+    printf("IDF Version:%s\r\n", esp_get_idf_version());
+    printf("Chip info:\r\n");
+    printf("\tmodel:%s\r\n", info.model == CHIP_ESP32 ? "ESP32" : "Unknow");
+    printf("\tcores:%d\r\n", info.cores);
+    printf("\tfeature:%s%s%s%s%d%s\r\n",
+           info.features & CHIP_FEATURE_WIFI_BGN ? "/802.11bgn" : "",
+           info.features & CHIP_FEATURE_BLE ? "/BLE" : "",
+           info.features & CHIP_FEATURE_BT ? "/BT" : "",
+           info.features & CHIP_FEATURE_EMB_FLASH ? "/Embedded-Flash:" : "/External-Flash:",
+           spi_flash_get_chip_size() / (1024 * 1024), " MB");
+    printf("\trevision number:%d\r\n", info.revision);
+    return 0;
+}
+
+static void register_version()
+{
+    const esp_console_cmd_t cmd = {
+        .command = "version",
+        .help = "Get version of chip and SDK",
+        .hint = NULL,
+        .func = &get_version,
+    };
+    ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
+}
+
+/** 'restart' command restarts the program */
+
+static int restart(int argc, char **argv)
+{
+    ESP_LOGI(TAG, "Restarting");
+    esp_restart();
+}
+
+static void register_restart()
+{
+    const esp_console_cmd_t cmd = {
+        .command = "restart",
+        .help = "Software reset of the chip",
+        .hint = NULL,
+        .func = &restart,
+    };
+    ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
+}
+
+/** 'free' command prints available heap memory */
+
+static int free_mem(int argc, char **argv)
+{
+    printf("%d\n", esp_get_free_heap_size());
+    return 0;
+}
+
+static void register_free()
+{
+    const esp_console_cmd_t cmd = {
+        .command = "free",
+        .help = "Get the current size of free heap memory",
+        .hint = NULL,
+        .func = &free_mem,
+    };
+    ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
+}
+
+/* 'heap' command prints minumum heap size */
+static int heap_size(int argc, char **argv)
+{
+    uint32_t heap_size = heap_caps_get_minimum_free_size(MALLOC_CAP_DEFAULT);
+    ESP_LOGI(TAG, "min heap size: %u", heap_size);
+    return 0;
+}
+
+static void register_heap()
+{
+    const esp_console_cmd_t heap_cmd = {
+        .command = "heap",
+        .help = "Get minimum size of free heap memory that was available during program execution",
+        .hint = NULL,
+        .func = &heap_size,
+    };
+    ESP_ERROR_CHECK( esp_console_cmd_register(&heap_cmd) );
+
+}
+
+/** 'tasks' command prints the list of tasks and related information */
+#if WITH_TASKS_INFO
+
+static int tasks_info(int argc, char **argv)
+{
+    const size_t bytes_per_task = 40; /* see vTaskList description */
+    char *task_list_buffer = malloc(uxTaskGetNumberOfTasks() * bytes_per_task);
+    if (task_list_buffer == NULL) {
+        ESP_LOGE(TAG, "failed to allocate buffer for vTaskList output");
+        return 1;
+    }
+    fputs("Task Name\tStatus\tPrio\tHWM\tTask#", stdout);
+#ifdef CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID
+    fputs("\tAffinity", stdout);
+#endif
+    fputs("\n", stdout);
+    vTaskList(task_list_buffer);
+    fputs(task_list_buffer, stdout);
+    free(task_list_buffer);
+    return 0;
+}
+
+static void register_tasks()
+{
+    const esp_console_cmd_t cmd = {
+        .command = "tasks",
+        .help = "Get information about running tasks",
+        .hint = NULL,
+        .func = &tasks_info,
+    };
+    ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
+}
+
+#endif // WITH_TASKS_INFO
+
+/** 'deep_sleep' command puts the chip into deep sleep mode */
+
+static struct {
+    struct arg_int *wakeup_time;
+    struct arg_int *wakeup_gpio_num;
+    struct arg_int *wakeup_gpio_level;
+    struct arg_end *end;
+} deep_sleep_args;
+
+
+static int deep_sleep(int argc, char **argv)
+{
+    int nerrors = arg_parse(argc, argv, (void **) &deep_sleep_args);
+    if (nerrors != 0) {
+        arg_print_errors(stderr, deep_sleep_args.end, argv[0]);
+        return 1;
+    }
+    if (deep_sleep_args.wakeup_time->count) {
+        uint64_t timeout = 1000ULL * deep_sleep_args.wakeup_time->ival[0];
+        ESP_LOGI(TAG, "Enabling timer wakeup, timeout=%lluus", timeout);
+        ESP_ERROR_CHECK( esp_sleep_enable_timer_wakeup(timeout) );
+    }
+    if (deep_sleep_args.wakeup_gpio_num->count) {
+        int io_num = deep_sleep_args.wakeup_gpio_num->ival[0];
+        if (!rtc_gpio_is_valid_gpio(io_num)) {
+            ESP_LOGE(TAG, "GPIO %d is not an RTC IO", io_num);
+            return 1;
+        }
+        int level = 0;
+        if (deep_sleep_args.wakeup_gpio_level->count) {
+            level = deep_sleep_args.wakeup_gpio_level->ival[0];
+            if (level != 0 && level != 1) {
+                ESP_LOGE(TAG, "Invalid wakeup level: %d", level);
+                return 1;
+            }
+        }
+        ESP_LOGI(TAG, "Enabling wakeup on GPIO%d, wakeup on %s level",
+                 io_num, level ? "HIGH" : "LOW");
+
+        ESP_ERROR_CHECK( esp_sleep_enable_ext1_wakeup(1ULL << io_num, level) );
+    }
+    rtc_gpio_isolate(GPIO_NUM_12);
+    esp_deep_sleep_start();
+}
+
+static void register_deep_sleep()
+{
+    deep_sleep_args.wakeup_time =
+        arg_int0("t", "time", "<t>", "Wake up time, ms");
+    deep_sleep_args.wakeup_gpio_num =
+        arg_int0(NULL, "io", "<n>",
+                 "If specified, wakeup using GPIO with given number");
+    deep_sleep_args.wakeup_gpio_level =
+        arg_int0(NULL, "io_level", "<0|1>", "GPIO level to trigger wakeup");
+    deep_sleep_args.end = arg_end(3);
+
+    const esp_console_cmd_t cmd = {
+        .command = "deep_sleep",
+        .help = "Enter deep sleep mode. "
+        "Two wakeup modes are supported: timer and GPIO. "
+        "If no wakeup option is specified, will sleep indefinitely.",
+        .hint = NULL,
+        .func = &deep_sleep,
+        .argtable = &deep_sleep_args
+    };
+    ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
+}
+
+/** 'light_sleep' command puts the chip into light sleep mode */
+
+static struct {
+    struct arg_int *wakeup_time;
+    struct arg_int *wakeup_gpio_num;
+    struct arg_int *wakeup_gpio_level;
+    struct arg_end *end;
+} light_sleep_args;
+
+static int light_sleep(int argc, char **argv)
+{
+    int nerrors = arg_parse(argc, argv, (void **) &light_sleep_args);
+    if (nerrors != 0) {
+        arg_print_errors(stderr, light_sleep_args.end, argv[0]);
+        return 1;
+    }
+    esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
+    if (light_sleep_args.wakeup_time->count) {
+        uint64_t timeout = 1000ULL * light_sleep_args.wakeup_time->ival[0];
+        ESP_LOGI(TAG, "Enabling timer wakeup, timeout=%lluus", timeout);
+        ESP_ERROR_CHECK( esp_sleep_enable_timer_wakeup(timeout) );
+    }
+    int io_count = light_sleep_args.wakeup_gpio_num->count;
+    if (io_count != light_sleep_args.wakeup_gpio_level->count) {
+        ESP_LOGE(TAG, "Should have same number of 'io' and 'io_level' arguments");
+        return 1;
+    }
+    for (int i = 0; i < io_count; ++i) {
+        int io_num = light_sleep_args.wakeup_gpio_num->ival[i];
+        int level = light_sleep_args.wakeup_gpio_level->ival[i];
+        if (level != 0 && level != 1) {
+            ESP_LOGE(TAG, "Invalid wakeup level: %d", level);
+            return 1;
+        }
+        ESP_LOGI(TAG, "Enabling wakeup on GPIO%d, wakeup on %s level",
+                 io_num, level ? "HIGH" : "LOW");
+
+        ESP_ERROR_CHECK( gpio_wakeup_enable(io_num, level ? GPIO_INTR_HIGH_LEVEL : GPIO_INTR_LOW_LEVEL) );
+    }
+    if (io_count > 0) {
+        ESP_ERROR_CHECK( esp_sleep_enable_gpio_wakeup() );
+    }
+    if (CONFIG_CONSOLE_UART_NUM <= UART_NUM_1) {
+        ESP_LOGI(TAG, "Enabling UART wakeup (press ENTER to exit light sleep)");
+        ESP_ERROR_CHECK( uart_set_wakeup_threshold(CONFIG_CONSOLE_UART_NUM, 3) );
+        ESP_ERROR_CHECK( esp_sleep_enable_uart_wakeup(CONFIG_CONSOLE_UART_NUM) );
+    }
+    fflush(stdout);
+    uart_tx_wait_idle(CONFIG_CONSOLE_UART_NUM);
+    esp_light_sleep_start();
+    esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
+    const char *cause_str;
+    switch (cause) {
+    case ESP_SLEEP_WAKEUP_GPIO:
+        cause_str = "GPIO";
+        break;
+    case ESP_SLEEP_WAKEUP_UART:
+        cause_str = "UART";
+        break;
+    case ESP_SLEEP_WAKEUP_TIMER:
+        cause_str = "timer";
+        break;
+    default:
+        cause_str = "unknown";
+        printf("%d\n", cause);
+    }
+    ESP_LOGI(TAG, "Woke up from: %s", cause_str);
+    return 0;
+}
+
+static void register_light_sleep()
+{
+    light_sleep_args.wakeup_time =
+        arg_int0("t", "time", "<t>", "Wake up time, ms");
+    light_sleep_args.wakeup_gpio_num =
+        arg_intn(NULL, "io", "<n>", 0, 8,
+                 "If specified, wakeup using GPIO with given number");
+    light_sleep_args.wakeup_gpio_level =
+        arg_intn(NULL, "io_level", "<0|1>", 0, 8, "GPIO level to trigger wakeup");
+    light_sleep_args.end = arg_end(3);
+
+    const esp_console_cmd_t cmd = {
+        .command = "light_sleep",
+        .help = "Enter light sleep mode. "
+        "Two wakeup modes are supported: timer and GPIO. "
+        "Multiple GPIO pins can be specified using pairs of "
+        "'io' and 'io_level' arguments. "
+        "Will also wake up on UART input.",
+        .hint = NULL,
+        .func = &light_sleep,
+        .argtable = &light_sleep_args
+    };
+    ESP_ERROR_CHECK( esp_console_cmd_register(&cmd) );
+}
+

+ 20 - 0
components/cmd_system/cmd_system.h

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

+ 10 - 0
components/cmd_system/component.mk

@@ -0,0 +1,10 @@
+#
+# Component Makefile
+#
+# This Makefile should, at the very least, just include $(SDK_PATH)/Makefile. By default,
+# this will take the sources in the src/ directory, compile them and link them into
+# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
+# please read the SDK documents if you need to do this.
+#
+
+COMPONENT_ADD_INCLUDEDIRS := .

+ 7 - 0
components/platform_esp32/CMakeLists.txt

@@ -0,0 +1,7 @@
+set(COMPONENT_ADD_INCLUDEDIRS . )
+
+set(COMPONENT_SRCS "esp_app_main.c" "platform_esp32.c" "bt_app_core.c" "cmd_wifi.c" "console.c" "nvs_utilities.c" "cmd_squeezelite.c")
+set(REQUIRES esp_common)
+set(REQUIRES_COMPONENTS freertos nvs_flash esp32 spi_flash newlib log console )
+
+register_component()

+ 12 - 15
main/bt_app_core.c → components/platform_esp32/bt_app_core.c

@@ -5,35 +5,31 @@
    software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
    CONDITIONS OF ANY KIND, either express or implied.
 */
-#include "squeezelite.h"
-#include <stdint.h>
 
+#include <stdint.h>
+#include "bt_app_core.h"
+#include "esp_system.h"
 #include <string.h>
 #include <stdbool.h>
+#include "esp_log.h"
 #include "freertos/xtensa_api.h"
 #include "freertos/FreeRTOSConfig.h"
 #include "freertos/FreeRTOS.h"
 #include "freertos/queue.h"
 #include "freertos/task.h"
-#include "esp_log.h"
-#include "bt_app_core.h"
+
+static const char * TAG = "platform_esp32";
 
 static void bt_app_task_handler(void *arg);
 static bool bt_app_send_msg(bt_app_msg_t *msg);
 static void bt_app_work_dispatched(bt_app_msg_t *msg);
 
-static log_level loglevel;
-
 static xQueueHandle s_bt_app_task_queue = NULL;
 static xTaskHandle s_bt_app_task_handle = NULL;
 
-
-void bt_set_log_level(log_level level){
-	loglevel = level;
-}
 bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback)
 {
-	LOG_SDEBUG("%s event 0x%x, param len %d", __func__, event, param_len);
+	ESP_LOGV(TAG,"%s event 0x%x, param len %d", __func__, event, param_len);
 
     bt_app_msg_t msg;
     memset(&msg, 0, sizeof(bt_app_msg_t));
@@ -65,7 +61,7 @@ static bool bt_app_send_msg(bt_app_msg_t *msg)
     }
 
     if (xQueueSend(s_bt_app_task_queue, msg, 10 / portTICK_RATE_MS) != pdTRUE) {
-    	LOG_ERROR("%s xQueue send failed", __func__);
+    	ESP_LOGE(TAG,"%s xQueue send failed", __func__);
         return false;
     }
     return true;
@@ -83,13 +79,13 @@ static void bt_app_task_handler(void *arg)
     bt_app_msg_t msg;
     for (;;) {
         if (pdTRUE == xQueueReceive(s_bt_app_task_queue, &msg, (portTickType)portMAX_DELAY)) {
-        	LOG_SDEBUG("%s, sig 0x%x, 0x%x", __func__, msg.sig, msg.event);
+        	ESP_LOGV(TAG,"%s, sig 0x%x, 0x%x", __func__, msg.sig, msg.event);
             switch (msg.sig) {
             case BT_APP_SIG_WORK_DISPATCH:
                 bt_app_work_dispatched(&msg);
                 break;
             default:
-                LOG_WARN("%s, unhandled sig: %d", __func__, msg.sig);
+                ESP_LOGW(TAG,"%s, unhandled sig: %d", __func__, msg.sig);
                 break;
             } // switch (msg.sig)
 
@@ -99,13 +95,14 @@ static void bt_app_task_handler(void *arg)
         }
         else
         {
-        	LOG_DEBUG("No messaged received from queue.");
+        	ESP_LOGW(TAG,"No messaged received from queue.");
         }
     }
 }
 
 void bt_app_task_start_up(void)
 {
+
     s_bt_app_task_queue = xQueueCreate(10, sizeof(bt_app_msg_t));
     assert(s_bt_app_task_queue!=NULL);
     assert(xTaskCreate(bt_app_task_handler, "BtAppT", 2048, NULL, configMAX_PRIORITIES - 3, &s_bt_app_task_handle)==pdPASS);

+ 3 - 2
main/bt_app_core.h → components/platform_esp32/bt_app_core.h

@@ -8,7 +8,8 @@
 
 #ifndef __BT_APP_CORE_H__
 #define __BT_APP_CORE_H__
-
+#include "esp_log.h"
+#include "time.h"
 #include <stdint.h>
 #include <stdbool.h>
 #include <stdio.h>
@@ -43,5 +44,5 @@ bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, i
 void bt_app_task_start_up(void);
 
 void bt_app_task_shut_down(void);
-void bt_set_log_level(log_level level);
+
 #endif /* __BT_APP_CORE_H__ */

+ 21 - 0
components/platform_esp32/cmd_decl.h

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

+ 173 - 0
components/platform_esp32/cmd_squeezelite.c

@@ -0,0 +1,173 @@
+//size_t esp_console_split_argv(char *line, char **argv, size_t argv_size);
+#include "cmd_squeezelite.h"
+
+#include <stdio.h>
+#include <string.h>
+#include "cmd_decl.h"
+
+#include "esp_log.h"
+#include "esp_console.h"
+#include "argtable3/argtable3.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/event_groups.h"
+#include "pthread.h"
+#include "platform_esp32.h"
+#include "nvs.h"
+#include "nvs_flash.h"
+//extern char current_namespace[];
+static const char * TAG = "squeezelite_cmd";
+#define SQUEEZELITE_THREAD_STACK_SIZE 20480
+extern int main(int argc, char **argv);
+static int launchsqueezelite(int argc, char **argv);
+pthread_t thread_squeezelite;
+pthread_t thread_squeezelite_runner;
+/** Arguments used by 'squeezelite' function */
+static struct {
+    struct arg_str *parameters;
+    struct arg_end *end;
+} squeezelite_args;
+static struct {
+	int argc;
+	char ** argv;
+} thread_parms ;
+static void * squeezelite_runner_thread(){
+    ESP_LOGI(TAG ,"Calling squeezelite");
+	main(thread_parms.argc,thread_parms.argv);
+	return NULL;
+}
+#define ADDITIONAL_SQUEEZELILTE_ARGS 5
+static void * squeezelite_thread(){
+	int * exit_code;
+	static bool isRunning=false;
+	if(isRunning) {
+		ESP_LOGE(TAG,"Squeezelite already running. Exiting!");
+		return NULL;
+	}
+	isRunning=true;
+	ESP_LOGI(TAG,"Waiting for WiFi.");
+	while(!wait_for_wifi()){};
+	ESP_LOGD(TAG ,"Number of args received: %u",thread_parms.argc );
+	ESP_LOGV(TAG ,"Values:");
+    for(int i = 0;i<thread_parms.argc; i++){
+    	ESP_LOGV(TAG ,"     %s",thread_parms.argv[i]);
+    }
+
+    ESP_LOGD(TAG,"Starting Squeezelite runner Thread");
+    esp_pthread_cfg_t cfg = esp_pthread_get_default_config();
+    cfg.thread_name= "squeezelite-run";
+    cfg.inherit_cfg = true;
+    cfg.stack_size = SQUEEZELITE_THREAD_STACK_SIZE ;
+    esp_pthread_set_cfg(&cfg);
+    pthread_attr_t attr;
+	pthread_attr_init(&attr);
+	pthread_create(&thread_squeezelite_runner, &attr, squeezelite_runner_thread,NULL);
+	pthread_attr_destroy(&attr);
+	// Wait for thread completion so we can free up memory.
+	pthread_join(thread_squeezelite_runner,(void **)&exit_code);
+
+	ESP_LOGV(TAG ,"Exited from squeezelite's main(). Freeing argv structure.");
+	for(int i=0;i<thread_parms.argc;i++){
+		ESP_LOGV(TAG ,"Freeing char buffer for parameter %u", i+1);
+		free(thread_parms.argv[i]);
+	}
+	ESP_LOGV(TAG ,"Freeing argv pointer");
+	free(thread_parms.argv);
+	isRunning=false;
+	return NULL;
+}
+//static int launchsqueezelite_dft(int _argc, char **_argv){
+//	nvs_handle nvs;
+//	esp_err_t err;
+//	optListStruct * curOpt=&optList[0];
+//	ESP_LOGV(TAG ,"preparing to allocate memory ");
+//	int argc =_argc+50; // todo: max number of parms?
+//	char ** argv = malloc(sizeof(char**)*argc);
+//	memset(argv,'\0',sizeof(char**)*argc);
+//	int curOptNum=0;
+//	argv[curOptNum++]=strdup(_argv[0]);
+//	ESP_LOGV(TAG ,"nvs_open\n");
+//	err = nvs_open(current_namespace, NVS_READONLY, &nvs);
+//	if (err != ESP_OK) {
+//		return err;
+//	}
+//
+//	while(curOpt->optName!=NULL){
+//		ESP_LOGV(TAG ,"Checking option %s with default value %s",curOpt->optName, curOpt->defaultValue);
+//		if(!strcmp(curOpt->relatedcommand,"squeezelite"))
+//		{
+//			ESP_LOGV(TAG ,"option is for Squeezelite command, processing it");
+//			// this is a squeezelite option
+//			if(curOpt->cmdLinePrefix!=NULL){
+//				ESP_LOGV(TAG ,"adding prefix %s",curOpt->cmdLinePrefix);
+//				argv[curOptNum++]=strdup(curOpt->cmdLinePrefix);
+//			}
+//			size_t len;
+//			if ( (nvs_get_str(nvs, curOpt->optName, NULL, &len)) == ESP_OK) {
+//				char *str = (char *)malloc(len);
+//				nvs_get_str(nvs, curOpt->optName, str, &len);
+//				ESP_LOGV(TAG ,"assigning retrieved value %s",str);
+//				argv[curOptNum++]=str;
+//
+//			}
+//		}
+//		curOpt++;
+//	}
+//	nvs_close(nvs);
+//	ESP_LOGV(TAG ,"calling launchsqueezelite with parameters");
+//	launchsqueezelite(argc, argv);
+//	ESP_LOGV(TAG ,"back from calling launchsqueezelite");
+//	return 0;
+//}
+
+static int launchsqueezelite(int argc, char **argv)
+{
+	ESP_LOGV(TAG ,"Begin");
+
+    ESP_LOGV(TAG, "Parameters:");
+    for(int i = 0;i<argc; i++){
+    	ESP_LOGV(TAG, "     %s",argv[i]);
+    }
+    ESP_LOGV(TAG,"Saving args in thread structure");
+
+    thread_parms.argc=0;
+    thread_parms.argv = malloc(sizeof(char**)*(argc+ADDITIONAL_SQUEEZELILTE_ARGS));
+	memset(thread_parms.argv,'\0',sizeof(char**)*(argc+ADDITIONAL_SQUEEZELILTE_ARGS));
+
+	for(int i=0;i<argc;i++){
+		ESP_LOGD(TAG ,"assigning parm %u : %s",i,argv[i]);
+		thread_parms.argv[thread_parms.argc++]=strdup(argv[i]);
+	}
+
+	if(argc==1){
+		// There isn't a default configuration that would actually work
+		// if no parameter is passed.
+		ESP_LOGV(TAG ,"Adding argv value at %u. Prev value: %s",thread_parms.argc,thread_parms.argv[thread_parms.argc-1]);
+		thread_parms.argv[thread_parms.argc++]=strdup("-?");
+	}
+
+    ESP_LOGD(TAG,"Starting Squeezelite Thread");
+    esp_pthread_cfg_t cfg = esp_pthread_get_default_config();
+    cfg.thread_name= "squeezelite";
+    cfg.inherit_cfg = true;
+    esp_pthread_set_cfg(&cfg);
+    pthread_attr_t attr;
+	pthread_attr_init(&attr);
+	pthread_create(&thread_squeezelite, &attr, squeezelite_thread,NULL);
+	pthread_attr_destroy(&attr);
+	ESP_LOGD(TAG ,"Back to console thread!");
+    return 0;
+}
+void register_squeezelite(){
+
+	squeezelite_args.parameters = arg_str0(NULL, NULL, "<parms>", "command line for squeezelite. -h for help, --defaults to launch with default values.");
+	squeezelite_args.end = arg_end(1);
+	const esp_console_cmd_t launch_squeezelite = {
+		.command = "squeezelite",
+		.help = "Starts squeezelite",
+		.hint = NULL,
+		.func = &launchsqueezelite,
+		.argtable = &squeezelite_args
+	};
+	ESP_ERROR_CHECK( esp_console_cmd_register(&launch_squeezelite) );
+
+}

+ 13 - 0
components/platform_esp32/cmd_squeezelite.h

@@ -0,0 +1,13 @@
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Register WiFi functions
+void register_squeezelite();
+
+#ifdef __cplusplus
+}
+#endif
+

+ 185 - 0
components/platform_esp32/cmd_wifi.c

@@ -0,0 +1,185 @@
+/* Console example — WiFi commands
+
+   This example code is in the Public Domain (or CC0 licensed, at your option.)
+
+   Unless required by applicable law or agreed to in writing, this
+   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+   CONDITIONS OF ANY KIND, either express or implied.
+*/
+
+#include "cmd_wifi.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "cmd_decl.h"
+#include "esp_log.h"
+#include "esp_console.h"
+#include "argtable3/argtable3.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/event_groups.h"
+#include "esp_wifi.h"
+#include "tcpip_adapter.h"
+#include "esp_event.h"
+
+#define JOIN_TIMEOUT_MS (10000)
+
+static EventGroupHandle_t wifi_event_group;
+const int CONNECTED_BIT = BIT0;
+static const char * TAG = "cmd_wifi";
+/** Arguments used by 'join' function */
+static struct {
+    struct arg_int *timeout;
+    struct arg_str *ssid;
+    struct arg_str *password;
+    struct arg_end *end;
+} join_args;
+
+///** Arguments used by 'join' function */
+//static struct {
+//    struct arg_int *autoconnect;
+//    struct arg_end *end;
+//} auto_connect_args;
+
+static void event_handler(void* arg, esp_event_base_t event_base, 
+                                int32_t event_id, void* event_data)
+{
+    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
+        esp_wifi_connect();
+        xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
+    } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
+        xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
+    }
+}
+bool wait_for_wifi(){
+
+	bool connected=(xEventGroupGetBits(wifi_event_group) & CONNECTED_BIT)!=0;
+
+	if(!connected){
+		ESP_LOGD(TAG,"Waiting for WiFi...");
+	    connected = (xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
+	                                   pdFALSE, pdTRUE, JOIN_TIMEOUT_MS / portTICK_PERIOD_MS)& CONNECTED_BIT)!=0;
+	    if(!connected){
+	    	ESP_LOGD(TAG,"wifi timeout.");
+	    }
+	    else
+	    {
+	    	ESP_LOGI(TAG,"WiFi Connected!");
+	    }
+	}
+
+
+    return connected;
+
+}
+static void initialise_wifi(void)
+{
+    static bool initialized = false;
+    if (initialized) {
+        return;
+    }
+    tcpip_adapter_init();
+    wifi_event_group = xEventGroupCreate();
+    ESP_ERROR_CHECK(esp_event_loop_create_default());
+    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
+    ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
+    ESP_ERROR_CHECK( esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &event_handler, NULL) );
+    ESP_ERROR_CHECK( esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL) );
+    ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
+    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_NULL) );
+    ESP_ERROR_CHECK( esp_wifi_start() );
+    initialized = true;
+}
+
+static bool wifi_join(const char *ssid, const char *pass, int timeout_ms)
+{
+    initialise_wifi();
+    wifi_config_t wifi_config = { 0 };
+    strncpy((char *) wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid));
+    if (pass) {
+        strncpy((char *) wifi_config.sta.password, pass, sizeof(wifi_config.sta.password));
+    }
+
+    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
+    ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
+    ESP_ERROR_CHECK( esp_wifi_connect() );
+
+    int bits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
+                                   pdFALSE, pdTRUE, timeout_ms / portTICK_PERIOD_MS);
+    return (bits & CONNECTED_BIT) != 0;
+}
+
+
+static int set_auto_connect(int argc, char **argv)
+{
+//    int nerrors = arg_parse(argc, argv, (void **) &join_args);
+//    if (nerrors != 0) {
+//        arg_print_errors(stderr, join_args.end, argv[0]);
+//        return 1;
+//    }
+//    ESP_LOGI(__func__, "Connecting to '%s'",
+//             join_args.ssid->sval[0]);
+//
+//    /* set default value*/
+//    if (join_args.timeout->count == 0) {
+//        join_args.timeout->ival[0] = JOIN_TIMEOUT_MS;
+//    }
+//
+//    bool connected = wifi_join(join_args.ssid->sval[0],
+//                               join_args.password->sval[0],
+//                               join_args.timeout->ival[0]);
+//    if (!connected) {
+//        ESP_LOGW(__func__, "Connection timed out");
+//        return 1;
+//    }
+//    ESP_LOGI(__func__, "Connected");
+    return 0;
+}
+static int connect(int argc, char **argv)
+{
+    int nerrors = arg_parse(argc, argv, (void **) &join_args);
+    if (nerrors != 0) {
+        arg_print_errors(stderr, join_args.end, argv[0]);
+        return 1;
+    }
+    ESP_LOGI(__func__, "Connecting to '%s'",
+             join_args.ssid->sval[0]);
+
+    /* set default value*/
+    if (join_args.timeout->count == 0) {
+        join_args.timeout->ival[0] = JOIN_TIMEOUT_MS;
+    }
+
+    bool connected = wifi_join(join_args.ssid->sval[0],
+                               join_args.password->sval[0],
+                               join_args.timeout->ival[0]);
+    if (!connected) {
+        ESP_LOGW(__func__, "Connection timed out");
+        return 1;
+    }
+    ESP_LOGI(__func__, "Connected");
+    return 0;
+}
+void register_wifi_join()
+{
+    join_args.timeout = arg_int0(NULL, "timeout", "<t>", "Connection timeout, ms");
+    join_args.ssid = arg_str1(NULL, NULL, "<ssid>", "SSID of AP");
+    join_args.password = arg_str0(NULL, NULL, "<pass>", "PSK of AP");
+    join_args.end = arg_end(2);
+
+    const esp_console_cmd_t join_cmd = {
+        .command = "join",
+        .help = "Join WiFi AP as a station",
+        .hint = NULL,
+        .func = &connect,
+        .argtable = &join_args
+    };
+    ESP_ERROR_CHECK( esp_console_cmd_register(&join_cmd) );
+}
+
+void register_wifi()
+{
+    register_wifi_join();
+    initialise_wifi();
+}
+

+ 21 - 0
components/platform_esp32/cmd_wifi.h

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

+ 10 - 0
components/platform_esp32/component.mk

@@ -0,0 +1,10 @@
+#
+# Component Makefile
+#
+# This Makefile should, at the very least, just include $(SDK_PATH)/Makefile. By default,
+# this will take the sources in the src/ directory, compile them and link them into
+# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
+# please read the SDK documents if you need to do this.
+#
+CFLAGS += -Os -DPOSIX -DLINKALL -DLOOPBACK -DNO_FAAD -DEMBEDDED -DTREMOR_ONLY -DBYTES_PER_FRAME=4 	
+CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_DEBUG

+ 316 - 0
components/platform_esp32/console.c

@@ -0,0 +1,316 @@
+/* Console example
+
+ This example code is in the Public Domain (or CC0 licensed, at your option.)
+
+ Unless required by applicable law or agreed to in writing, this
+ software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ CONDITIONS OF ANY KIND, either express or implied.
+ */
+
+#include <stdio.h>
+#include <stdlib.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 "esp_vfs_fat.h"
+#include "nvs.h"
+#include "nvs_flash.h"
+#include "pthread.h"
+#include "platform_esp32.h"
+#include "cmd_decl.h"
+#include "console.h"
+
+#include "cmd_squeezelite.h"
+#include "nvs_utilities.h"
+pthread_t thread_console;
+static void * console_thread();
+void console_start();
+static const char * TAG = "console";
+extern char current_namespace[];
+/* Prompt to be printed before each line.
+ * This can be customized, made dynamic, etc.
+ */
+const char* prompt = LOG_COLOR_I "squeezelite-esp32> " LOG_RESET_COLOR;
+
+/* Console command history can be stored to and loaded from a file.
+ * The easiest way to do this is to use FATFS filesystem on top of
+ * wear_levelling library.
+ */
+
+#define MOUNT_PATH "/data"
+#define HISTORY_PATH MOUNT_PATH "/history.txt"
+void run_command(char * line);
+//optListStruct * getOptionByName(char * option){
+//	optListStruct * curOpt=&optList[0];
+//	while(curOpt->optName !=NULL){
+//		if(!strcmp(curOpt->optName, option)){
+//			return curOpt;
+//		}
+//		curOpt++;
+//	}
+//	return NULL;
+//}
+//
+//static int list_options(int argc, char **argv)
+//{
+//	nvs_handle nvs;
+//	esp_err_t err;
+//
+//	err = nvs_open(current_namespace, NVS_READONLY, &nvs);
+//	if (err != ESP_OK) {
+//		return err;
+//	}
+//	//
+//	optListStruct * curOpt=&optList[0];
+//	printf("System Configuration Options.\n");
+//	while(curOpt->optName!=NULL){
+//        printf("Option: %s\n"
+//        		"     Description: %20s\n"
+//        		"     Default Value: %20s\n"
+//        		"     Current Value: ",curOpt->optName, curOpt->description, curOpt->defaultValue);
+//        size_t len;
+//        if ( (nvs_get_str(nvs, curOpt->optName, NULL, &len)) == ESP_OK) {
+//            char *str = (char *)malloc(len);
+//            if ( (nvs_get_str(nvs, curOpt->optName, str, &len)) == ESP_OK) {
+//                printf("%20s\n", str);
+//            }
+//            free(str);
+//        }
+//        else
+//        {
+//        	if(store_nvs_value(NVS_TYPE_STR, curOpt->optName,curOpt->defaultValue, strlen(curOpt->defaultValue))==ESP_OK)
+//        	{
+//        		printf("%20s\n", curOpt->defaultValue);
+//        	}
+//        	else
+//        	{
+//        		printf("Error.  Invalid key\n");
+//        	}
+//        }
+//        curOpt++;
+//	}
+//	printf("\n");
+//	nvs_close(nvs);
+//    return 0;
+//}
+//void register_list_options(){
+//	const esp_console_cmd_t config_list = {
+//		.command = "config-list",
+//		.help = "Lists available configuration options.",
+//		.hint = NULL,
+//		.func = &list_options,
+//		.argtable = NULL
+//	};
+//
+//	ESP_ERROR_CHECK( esp_console_cmd_register(&config_list) );
+//
+//}
+void process_autoexec(){
+	int i=1;
+	char autoexec_name[21]={0};
+	char * autoexec_value=NULL;
+	int * autoexec_flag = get_nvs_value_alloc(NVS_TYPE_U8, "autoexec");
+	if(autoexec_flag!=NULL)
+	{
+		ESP_LOGI(TAG,"autoexec flag value found with value %d", *autoexec_flag);
+		printf("printf -- autoexec flag value found with value %d", *autoexec_flag);
+		if(*autoexec_flag == 1)
+		{
+			do {
+				snprintf(autoexec_name,sizeof(autoexec_name)-1,"autoexec%u",i++);
+				ESP_LOGD(TAG,"Getting command name %s", autoexec_name);
+				autoexec_value= get_nvs_value_alloc(NVS_TYPE_STR, autoexec_name);
+				if(autoexec_value!=NULL){
+					ESP_LOGI(TAG,"Running command %s = %s", autoexec_name, autoexec_value);
+					run_command(autoexec_value);
+					free(autoexec_value);
+				}
+				else
+				{
+					ESP_LOGD(TAG,"No matching command found for name %s", autoexec_name);
+					break;
+				}
+			} while(1);
+		}
+		free(autoexec_flag);
+	}
+	else
+	{
+		ESP_LOGD(TAG,"No matching command found for name autoexec. Adding default entries");
+		uint8_t autoexec_dft=0;
+		char autoexec1_dft[]="join " CONFIG_WIFI_SSID CONFIG_WIFI_PASSWORD;
+		char autoexec2_dft[]="squeezelite -o \"DAC\" -b 500:2000 -d all=debug -M esp32 -r \"44100,4800\" -N \"playername.txt\"";
+		store_nvs_value(NVS_TYPE_U8,"autoexec",&autoexec_dft);
+		store_nvs_value(NVS_TYPE_U8,"autoexec1",autoexec1_dft);
+		store_nvs_value(NVS_TYPE_U8,"autoexec2",autoexec2_dft);
+	}
+}
+static void initialize_filesystem() {
+	static wl_handle_t wl_handle;
+	const esp_vfs_fat_mount_config_t mount_config = {
+			.max_files = 10,
+			.format_if_mount_failed = true,
+			.allocation_unit_size = 4096
+			};
+	esp_err_t err = esp_vfs_fat_spiflash_mount(MOUNT_PATH, "storage",
+			&mount_config, &wl_handle);
+	if (err != ESP_OK) {
+		ESP_LOGE(TAG, "Failed to mount FATFS (%s)", esp_err_to_name(err));
+		return;
+	}
+}
+
+static void initialize_nvs() {
+	esp_err_t err = nvs_flash_init();
+	if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
+		ESP_ERROR_CHECK(nvs_flash_erase());
+		err = nvs_flash_init();
+	}
+	ESP_ERROR_CHECK(err);
+}
+
+void initialize_console() {
+
+	/* Disable buffering on stdin */
+	setvbuf(stdin, NULL, _IONBF, 0);
+
+	/* Minicom, screen, idf_monitor send CR when ENTER key is pressed */
+	esp_vfs_dev_uart_set_rx_line_endings(ESP_LINE_ENDINGS_CR);
+	/* Move the caret to the beginning of the next line on '\n' */
+	esp_vfs_dev_uart_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF);
+
+	/* Configure UART. Note that REF_TICK is used so that the baud rate remains
+	 * correct while APB frequency is changing in light sleep mode.
+	 */
+	const uart_config_t uart_config = { .baud_rate =
+			CONFIG_CONSOLE_UART_BAUDRATE, .data_bits = UART_DATA_8_BITS,
+			.parity = UART_PARITY_DISABLE, .stop_bits = UART_STOP_BITS_1,
+			.use_ref_tick = true };
+	ESP_ERROR_CHECK(uart_param_config(CONFIG_CONSOLE_UART_NUM, &uart_config));
+
+	/* Install UART driver for interrupt-driven reads and writes */
+	ESP_ERROR_CHECK(
+			uart_driver_install(CONFIG_CONSOLE_UART_NUM, 256, 0, 0, NULL, 0));
+
+	/* Tell VFS to use UART driver */
+	esp_vfs_dev_uart_use_driver(CONFIG_CONSOLE_UART_NUM);
+
+	/* Initialize the console */
+	esp_console_config_t console_config = { .max_cmdline_args = 8,
+			.max_cmdline_length = 256,
+#if CONFIG_LOG_COLORS
+			.hint_color = atoi(LOG_COLOR_CYAN)
+#endif
+			};
+	ESP_ERROR_CHECK(esp_console_init(&console_config));
+
+	/* Configure linenoise line completion library */
+	/* Enable multiline editing. If not set, long commands will scroll within
+	 * single line.
+	 */
+	linenoiseSetMultiLine(1);
+
+	/* Tell linenoise where to get command completions and hints */
+	linenoiseSetCompletionCallback(&esp_console_get_completion);
+	linenoiseSetHintsCallback((linenoiseHintsCallback*) &esp_console_get_hint);
+
+	/* Set command history size */
+	linenoiseHistorySetMaxLen(100);
+
+	/* Load command history from filesystem */
+	linenoiseHistoryLoad(HISTORY_PATH);
+}
+
+void console_start() {
+	initialize_nvs();
+	initialize_filesystem();
+	initialize_console();
+
+	/* Register commands */
+	esp_console_register_help_command();
+	register_system();
+	register_wifi();
+	register_nvs();
+	register_squeezelite();
+	printf("\n"
+			"Type 'help' to get the list of commands.\n"
+			"Use UP/DOWN arrows to navigate through command history.\n"
+			"Press TAB when typing command name to auto-complete.\n"
+			"\n"
+			"To automatically execute lines at startup:\n"
+			"\tSet NVS variable autoexec (U8) = 1 to enable, 0 to disable automatic execution.\n"
+			"\tSet NVS variable autoexec[1~9] (string)to a command that should be executed automatically\n"
+			"\n"
+			"\n");
+
+	/* Figure out if the terminal supports escape sequences */
+	int probe_status = linenoiseProbe();
+	if (probe_status) { /* zero indicates success */
+		printf("\n****************************\n"
+				"Your terminal application does not support escape sequences.\n"
+				"Line editing and history features are disabled.\n"
+				"On Windows, try using Putty instead.\n"
+				"****************************\n");
+		linenoiseSetDumbMode(1);
+#if CONFIG_LOG_COLORS
+		/* Since the terminal doesn't support escape sequences,
+		 * don't use color codes in the prompt.
+		 */
+		prompt = "squeezelite-esp32> ";
+#endif //CONFIG_LOG_COLORS
+
+	}
+    esp_pthread_cfg_t cfg = esp_pthread_get_default_config();
+    cfg.thread_name= "console";
+    cfg.inherit_cfg = true;
+    esp_pthread_set_cfg(&cfg);
+	pthread_attr_t attr;
+	pthread_attr_init(&attr);
+	pthread_create(&thread_console, &attr, console_thread, NULL);
+	pthread_attr_destroy(&attr);
+}
+void run_command(char * line){
+	/* Try to run the command */
+	int ret;
+	esp_err_t err = esp_console_run(line, &ret);
+
+	if (err == ESP_ERR_NOT_FOUND) {
+		printf("Unrecognized command\n");
+	} else if (err == ESP_ERR_INVALID_ARG) {
+		// command was empty
+	} else if (err == ESP_OK && ret != ESP_OK) {
+		printf("Command returned non-zero error code: 0x%x (%s)\n", ret,
+				esp_err_to_name(err));
+	} else if (err != ESP_OK) {
+		printf("Internal error: %s\n", esp_err_to_name(err));
+	}
+}
+static void * console_thread() {
+	process_autoexec();
+	/* Main loop */
+	while (1) {
+		/* Get a line using linenoise.
+		 * The line is returned when ENTER is pressed.
+		 */
+		char* line = linenoise(prompt);
+		if (line == NULL) { /* Ignore empty lines */
+			continue;
+		}
+		/* Add the command to the history */
+		linenoiseHistoryAdd(line);
+
+		/* Save command history to filesystem */
+		linenoiseHistorySave(HISTORY_PATH);
+		printf("\n");
+		run_command(line);
+		/* linenoise allocates line buffer on the heap, so need to free it */
+		linenoiseFree(line);
+	}
+	return NULL;
+}
+

+ 18 - 0
components/platform_esp32/console.h

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

+ 147 - 0
components/platform_esp32/esp_app_main.c

@@ -0,0 +1,147 @@
+/* Scan Example
+
+   This example code is in the Public Domain (or CC0 licensed, at your option.)
+
+   Unless required by applicable law or agreed to in writing, this
+   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+   CONDITIONS OF ANY KIND, either express or implied.
+*/
+
+/*
+    This example shows how to use the All Channel Scan or Fast Scan to connect
+    to a Wi-Fi network.
+
+    In the Fast Scan mode, the scan will stop as soon as the first network matching
+    the SSID is found. In this mode, an application can set threshold for the
+    authentication mode and the Signal strength. Networks that do not meet the
+    threshold requirements will be ignored.
+
+    In the All Channel Scan mode, the scan will end only after all the channels
+    are scanned, and connection will start with the best network. The networks
+    can be sorted based on Authentication Mode or Signal Strength. The priority
+    for the Authentication mode is:  WPA2 > WPA > WEP > Open
+*/
+#include "platform_esp32.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include "esp_bt.h"
+#include "esp_bt_device.h"
+#include "esp_bt_main.h"
+#include "esp_gap_bt_api.h"
+#include "esp_a2dp_api.h"
+#include "esp_avrc_api.h"
+#include "esp_log.h"
+#include "esp_pthread.h"
+#include "esp_system.h"
+#include "esp_wifi.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/event_groups.h"
+#include "freertos/task.h"
+#include "freertos/timers.h"
+#include "nvs.h"
+#include "nvs_flash.h"
+#include "nvs_utilities.h"
+#include "pthread.h"
+#include "string.h"
+#include "sys/socket.h"
+#include <signal.h>
+#include "esp_system.h"
+#include <signal.h>
+
+/*Set the SSID and Password via "make menuconfig"*/
+#define DEFAULT_SSID CONFIG_WIFI_SSID
+#define DEFAULT_PWD CONFIG_WIFI_PASSWORD
+
+#if CONFIG_WIFI_ALL_CHANNEL_SCAN
+#define DEFAULT_SCAN_METHOD WIFI_ALL_CHANNEL_SCAN
+#elif CONFIG_WIFI_FAST_SCAN
+#define DEFAULT_SCAN_METHOD WIFI_FAST_SCAN
+#else
+#define DEFAULT_SCAN_METHOD WIFI_FAST_SCAN
+#endif /*CONFIG_SCAN_METHOD*/
+
+#if CONFIG_WIFI_CONNECT_AP_BY_SIGNAL
+#define DEFAULT_SORT_METHOD WIFI_CONNECT_AP_BY_SIGNAL
+#elif CONFIG_WIFI_CONNECT_AP_BY_SECURITY
+#define DEFAULT_SORT_METHOD WIFI_CONNECT_AP_BY_SECURITY
+#else
+#define DEFAULT_SORT_METHOD WIFI_CONNECT_AP_BY_SIGNAL
+#endif /*CONFIG_SORT_METHOD*/
+
+#if CONFIG_FAST_SCAN_THRESHOLD
+#define DEFAULT_RSSI CONFIG_FAST_SCAN_MINIMUM_SIGNAL
+#if CONFIG_EXAMPLE_OPEN
+#define DEFAULT_AUTHMODE WIFI_AUTH_OPEN
+#elif CONFIG_EXAMPLE_WEP
+#define DEFAULT_AUTHMODE WIFI_AUTH_WEP
+#elif CONFIG_EXAMPLE_WPA
+#define DEFAULT_AUTHMODE WIFI_AUTH_WPA_PSK
+#elif CONFIG_EXAMPLE_WPA2
+#define DEFAULT_AUTHMODE WIFI_AUTH_WPA2_PSK
+#else
+#define DEFAULT_AUTHMODE WIFI_AUTH_OPEN
+#endif
+#else
+#define DEFAULT_RSSI -127
+#define DEFAULT_AUTHMODE WIFI_AUTH_OPEN
+#endif /*CONFIG_FAST_SCAN_THRESHOLD*/
+extern char current_namespace[];
+static const char * TAG = "platform_esp32";
+
+
+
+//static void event_handler(void* arg, esp_event_base_t event_base,
+//                                int32_t event_id, void* event_data)
+//{
+//    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
+//        esp_wifi_connect();
+//    } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
+//        esp_wifi_connect();
+//    } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
+//        ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
+//        ESP_LOGI(TAG, "got ip: %s.", ip4addr_ntoa(&event->ip_info.ip));
+//        ESP_LOGD(TAG,"Signaling wifi connected. Locking.\n");
+//    	pthread_mutex_lock(&wifi_connect_suspend_mutex);
+//    	ESP_LOGD(TAG,"Signaling wifi connected. Broadcasting.\n");
+//		pthread_cond_broadcast(&wifi_connect_suspend_cond);
+//		ESP_LOGD(TAG,"Signaling wifi connected. Unlocking.\n");
+//		pthread_mutex_unlock(&wifi_connect_suspend_mutex);
+//    }
+//}
+//
+///* Initialize Wi-Fi as sta and set scan method */
+//static void wifi_scan(void)
+//{
+//
+//    tcpip_adapter_init();
+//    ESP_ERROR_CHECK(esp_event_loop_create_default());
+//
+//    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
+//    ESP_ERROR_CHECK(esp_wifi_init(&cfg));
+//
+//    ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
+//    ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL));
+//
+//    wifi_config_t wifi_config = {
+//        .sta = {
+//            .ssid = DEFAULT_SSID,
+//            .password = DEFAULT_PWD,
+//            .scan_method = DEFAULT_SCAN_METHOD,
+//            .sort_method = DEFAULT_SORT_METHOD,
+//            .threshold.rssi = DEFAULT_RSSI,
+//            .threshold.authmode = DEFAULT_AUTHMODE,
+//        },
+//    };
+//    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
+//    ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
+//    ESP_ERROR_CHECK(esp_wifi_start());
+//}
+
+
+void app_main()
+{
+
+	console_start();
+}

+ 179 - 0
components/platform_esp32/nvs_utilities.c

@@ -0,0 +1,179 @@
+#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"
+
+extern char current_namespace[];
+static const char * TAG = "platform_esp32";
+
+esp_err_t store_nvs_value(nvs_type_t type, const char *key, void * data) {
+	if (type == NVS_TYPE_BLOB)
+		return ESP_ERR_NVS_TYPE_MISMATCH;
+	return store_nvs_value_len(type, key, data,0);
+}
+esp_err_t store_nvs_value_len(nvs_type_t type, const char *key, void * data,
+		size_t data_len) {
+	esp_err_t err;
+	nvs_handle nvs;
+
+	if (type == NVS_TYPE_ANY) {
+		return ESP_ERR_NVS_TYPE_MISMATCH;
+	}
+
+	err = nvs_open(current_namespace, NVS_READWRITE, &nvs);
+	if (err != ESP_OK) {
+		return err;
+	}
+
+	if (type == NVS_TYPE_I8) {
+		err = nvs_set_i8(nvs, key, *(int8_t *) data);
+	} else if (type == NVS_TYPE_U8) {
+		err = nvs_set_u8(nvs, key, *(uint8_t *) data);
+	} else if (type == NVS_TYPE_I16) {
+		err = nvs_set_i16(nvs, key, *(int16_t *) data);
+	} else if (type == NVS_TYPE_U16) {
+		err = nvs_set_u16(nvs, key, *(uint16_t *) data);
+	} else if (type == NVS_TYPE_I32) {
+		err = nvs_set_i32(nvs, key, *(int32_t *) data);
+	} else if (type == NVS_TYPE_U32) {
+		err = nvs_set_u32(nvs, key, *(uint32_t *) data);
+	} else if (type == NVS_TYPE_I64) {
+		err = nvs_set_i64(nvs, key, *(int64_t *) data);
+	} else if (type == NVS_TYPE_U64) {
+		err = nvs_set_u64(nvs, key, *(uint64_t *) data);
+	} else if (type == NVS_TYPE_STR) {
+		err = nvs_set_str(nvs, key, data);
+	} else if (type == NVS_TYPE_BLOB) {
+		err = nvs_set_blob(nvs, key, (void *) data, data_len);
+	}
+	if (err == ESP_OK) {
+		err = nvs_commit(nvs);
+		if (err == ESP_OK) {
+			ESP_LOGI(TAG, "Value stored under key '%s'", key);
+		}
+	}
+	nvs_close(nvs);
+	return err;
+}
+void * get_nvs_value_alloc(nvs_type_t type, const char *key) {
+	nvs_handle nvs;
+	esp_err_t err;
+	void * value=NULL;
+
+	err = nvs_open(current_namespace, NVS_READONLY, &nvs);
+	if (err != ESP_OK) {
+		return value;
+	}
+
+	if (type == NVS_TYPE_I8) {
+		value=malloc(sizeof(int8_t));
+		err = nvs_get_i8(nvs, key, (int8_t *) value);
+		printf("value found = %d\n",*(int8_t *)value);
+	} else if (type == NVS_TYPE_U8) {
+		value=malloc(sizeof(uint8_t));
+		err = nvs_get_u8(nvs, key, (uint8_t *) value);
+		printf("value found = %u\n",*(uint8_t *)value);
+	} else if (type == NVS_TYPE_I16) {
+		value=malloc(sizeof(int16_t));
+		err = nvs_get_i16(nvs, key, (int16_t *) value);
+		printf("value found = %d\n",*(int16_t *)value);
+	} else if (type == NVS_TYPE_U16) {
+		value=malloc(sizeof(uint16_t));
+		err = nvs_get_u16(nvs, key, (uint16_t *) value);
+		printf("value found = %u\n",*(uint16_t *)value);
+	} else if (type == NVS_TYPE_I32) {
+		value=malloc(sizeof(int32_t));
+		err = nvs_get_i32(nvs, key, (int32_t *) value);
+	} else if (type == NVS_TYPE_U32) {
+		value=malloc(sizeof(uint32_t));
+		err = nvs_get_u32(nvs, key, (uint32_t *) value);
+	} else if (type == NVS_TYPE_I64) {
+		value=malloc(sizeof(int64_t));
+		err = nvs_get_i64(nvs, key, (int64_t *) value);
+	} else if (type == NVS_TYPE_U64) {
+		value=malloc(sizeof(uint64_t));
+		err = nvs_get_u64(nvs, key, (uint64_t *) value);
+	} else if (type == NVS_TYPE_STR) {
+		size_t len;
+		if ((err = nvs_get_str(nvs, key, NULL, &len)) == ESP_OK) {
+			value=malloc(sizeof(len+1));
+			err = nvs_get_str(nvs, key, value, &len);
+			}
+	} else if (type == NVS_TYPE_BLOB) {
+		size_t len;
+		if ((err = nvs_get_blob(nvs, key, NULL, &len)) == ESP_OK) {
+			value=malloc(sizeof(len+1));
+			err = nvs_get_blob(nvs, key, value, &len);
+		}
+	}
+	if(err!=ESP_OK){
+		free(value);
+		value=NULL;
+	}
+	nvs_close(nvs);
+	return value;
+}
+esp_err_t get_nvs_value(nvs_type_t type, const char *key, void*value, const uint8_t buf_size) {
+	nvs_handle nvs;
+	esp_err_t err;
+
+	err = nvs_open(current_namespace, NVS_READONLY, &nvs);
+	if (err != ESP_OK) {
+		return err;
+	}
+
+	if (type == NVS_TYPE_I8) {
+		err = nvs_get_i8(nvs, key, (int8_t *) value);
+	} else if (type == NVS_TYPE_U8) {
+		err = nvs_get_u8(nvs, key, (uint8_t *) value);
+	} else if (type == NVS_TYPE_I16) {
+		err = nvs_get_i16(nvs, key, (int16_t *) value);
+	} else if (type == NVS_TYPE_U16) {
+		err = nvs_get_u16(nvs, key, (uint16_t *) value);
+	} else if (type == NVS_TYPE_I32) {
+		err = nvs_get_i32(nvs, key, (int32_t *) value);
+	} else if (type == NVS_TYPE_U32) {
+		err = nvs_get_u32(nvs, key, (uint32_t *) value);
+	} else if (type == NVS_TYPE_I64) {
+		err = nvs_get_i64(nvs, key, (int64_t *) value);
+	} else if (type == NVS_TYPE_U64) {
+		err = nvs_get_u64(nvs, key, (uint64_t *) value);
+	} else if (type == NVS_TYPE_STR) {
+		size_t len;
+		if ((err = nvs_get_str(nvs, key, NULL, &len)) == ESP_OK) {
+			if (len > buf_size) {
+				//ESP_LOGE("Error reading value for %s.  Buffer size: %d, Value Length: %d", key, buf_size, len);
+				err = ESP_FAIL;
+			} else {
+				err = nvs_get_str(nvs, key, value, &len);
+			}
+		}
+	} else if (type == NVS_TYPE_BLOB) {
+		size_t len;
+		if ((err = nvs_get_blob(nvs, key, NULL, &len)) == ESP_OK) {
+
+			if (len > buf_size) {
+				//ESP_LOGE("Error reading value for %s.  Buffer size: %d, Value Length: %d",
+				//		key, buf_size, len);
+				err = ESP_FAIL;
+			} else {
+				err = nvs_get_blob(nvs, key, value, &len);
+			}
+		}
+	}
+
+	nvs_close(nvs);
+	return err;
+}
+

+ 13 - 0
components/platform_esp32/nvs_utilities.h

@@ -0,0 +1,13 @@
+#pragma once
+#include "esp_err.h"
+#include "nvs.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+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 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);
+#ifdef __cplusplus
+}
+#endif

+ 8 - 13
main/perf_trace.h → components/platform_esp32/perf_trace.h

@@ -1,5 +1,8 @@
 
 #pragma once
+#include "time.h"
+#include "sys/time.h"
+#include "esp_system.h"
 #define PERF_MAX LONG_MAX
 #define MIN_MAX_VAL(x) x==PERF_MAX?0:x
 #define CURR_SAMPLE_RATE output.current_sample_rate>0?output.current_sample_rate:1
@@ -52,22 +55,14 @@
 static inline bool hasTimeElapsed(time_t delayMS, bool bforce)
 {
 	static time_t lastTime=0;
-	if (lastTime <= gettime_ms() ||bforce)
+	struct timeval tv;
+	gettimeofday(&tv, NULL);
+	if (lastTime <= tv.tv_sec * 1000 + tv.tv_usec / 1000 ||bforce)
 	{
-		lastTime = gettime_ms() + delayMS;
+		lastTime = tv.tv_sec * 1000 + tv.tv_usec / 1000 + delayMS;
 		return true;
 	}
 	else
 		return false;
 }
-//#define MAX_PERF_NAME_LEN 10
-//#define MAX_PERF_FORMAT_LEN 12
-//typedef enum  {BUFFER_TYPE,DURATION_TYPE,LAST } perf_formats;
-//typedef struct _perf_stats {
-//	uint32_t min;
-//	uint32_t max;
-//	uint32_t current;
-//	char name[MAX_PERF_NAME_LEN+1];
-//	uint32_t timer_start;
-//	perf_formats fmt;
-//} perf_stats;
+

+ 222 - 296
main/esp32.c → components/platform_esp32/platform_esp32.c

@@ -1,104 +1,77 @@
-#include <signal.h>
-
-#include "sdkconfig.h"
-#include "esp_system.h" 
-#include "squeezelite.h"
-#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include "esp_log.h"
+#include "esp_system.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
-
-#include "freertos/FreeRTOS.h"
-#include "freertos/task.h"
-#include "freertos/timers.h"
-#include "nvs.h"
-#include "nvs_flash.h"
-#include "esp_system.h"
-#include "esp_log.h"
-#include "perf_trace.h"
-
 #include "esp_bt.h"
-#include "bt_app_core.h"
-#include "esp_bt_main.h"
 #include "esp_bt_device.h"
+#include "esp_bt_main.h"
 #include "esp_gap_bt_api.h"
 #include "esp_a2dp_api.h"
 #include "esp_avrc_api.h"
+#include "esp_console.h"
 #include "esp_pthread.h"
+#include "esp_system.h"
+#include "esp_wifi.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/event_groups.h"
+#include "freertos/task.h"
+#include "freertos/timers.h"
+#include "nvs.h"
+#include "nvs_flash.h"
+#include "nvs_utilities.h"
 #include "pthread.h"
+#include "string.h"
+//#include "esp_event.h"
+#include "sys/socket.h"
+#include <signal.h>
 
-const char *  art_a2dp_connected[]={"\n\n",
-		"           ___  _____  _____     _____                            _           _ _ \n",
-		"     /\\   |__ \\|  __ \\|  __ \\   / ____|                          | |         | | |\n",
-		"    /  \\     ) | |  | | |__) | | |     ___  _ __  _ __   ___  ___| |_ ___  __| | |\n",
-		"   / /\\ \\   / /| |  | |  ___/  | |    / _ \\| '_ \\| '_ \\ / _ \\/ __| __/ _ \\/ _` | |\n",
-		"  / ____ \\ / /_| |__| | |      | |___| (_) | | | | | | |  __/ (__| ||  __/ (_| |_|\n",
-		" /_/    \\_\\____|_____/|_|       \\_____\\___/|_| |_|_| |_|\\___|\\___|\\__\\___|\\__,_(_)\n\n",
-		"\0"};
-const char * art_a2dp_connecting[]= {"\n\n",
-		 "           ___  _____  _____     _____                            _   _                   \n",
-		 "     /\\   |__ \\|  __ \\|  __ \\   / ____|                          | | (_)                  \n",
-		 "    /  \\     ) | |  | | |__) | | |     ___  _ __  _ __   ___  ___| |_ _ _ __   __ _       \n",
-		 "   / /\\ \\   / /| |  | |  ___/  | |    / _ \\| '_ \\| '_ \\ / _ \\/ __| __| | '_ \\ / _` |      \n",
-		 "  / ____ \\ / /_| |__| | |      | |___| (_) | | | | | | |  __/ (__| |_| | | | | (_| |_ _ _ \n",
-		 " /_/    \\_\\____|_____/|_|       \\_____\\___/|_| |_|_| |_|\\___|\\___|\\__|_|_| |_|\\__, (_|_|_)\n",
-		 "                                                                               __/ |       \n",
-		 "                                                                              |___/        \n\n",
-		 "\0"};
+#include <signal.h>
+#include "platform_esp32.h"
+#include "../../main/squeezelite.h"
+#include "argtable3/argtable3.h"
+
+#define STATS_REPORT_DELAY_MS 15000
+static const char * TAG = "platform_esp32";
+extern char * get_output_state_desc(output_state state);
 
-char * get_output_state_desc(output_state state){
-	switch (state) {
-	case OUTPUT_OFF:
-		return STR(OUTPUT_OFF);
-	case OUTPUT_STOPPED:
-		return STR(OUTPUT_STOPPED);
-	case OUTPUT_BUFFER:
-		return STR(OUTPUT_BUFFER);
-	case OUTPUT_RUNNING:
-		return STR(OUTPUT_RUNNING);
-	case OUTPUT_PAUSE_FRAMES:
-		return STR(OUTPUT_PAUSE_FRAMES);
-	case OUTPUT_SKIP_FRAMES:
-		return STR(OUTPUT_SKIP_FRAMES);
-	case OUTPUT_START_AT:
-		return STR(OUTPUT_START_AT);
-	default:
-		return "OUTPUT_UNKNOWN_STATE";
-	}
-	return "";
-}
-#define BT_AV_TAG               "BT_AV"
-extern log_level loglevel;
 extern struct outputstate output;
 extern struct buffer *outputbuf;
-#ifdef USE_BT_RING_BUFFER
-#define LOCK_BT   mutex_lock(btbuf->mutex)
-#define UNLOCK_BT mutex_unlock(btbuf->mutex)
-extern struct buffer *btbuf;
-#else
+extern struct buffer *streambuf;
 extern uint8_t * btout;
-#endif
 time_t disconnect_time=0;
-#define LOCK   mutex_lock(outputbuf->mutex)
-#define UNLOCK mutex_unlock(outputbuf->mutex)
-int64_t connecting_timeout = 0;
+#define LOCK_S   pthread_mutex_lock(&(streambuf->mutex))
+#define UNLOCK_S pthread_mutex_unlock(&(streambuf->mutex))
 
-#ifndef CONFIG_A2DP_SINK_NAME
-#define CONFIG_A2DP_SINK_NAME "btspeaker" // fix some compile errors when BT is not chosen
-#endif
-#ifndef CONFIG_A2DP_CONNECT_TIMEOUT_MS
-#define CONFIG_A2DP_CONNECT_TIMEOUT_MS 2000
-#endif
-#ifndef CONFIG_A2DP_DEV_NAME
-#define CONFIG_A2DP_DEV_NAME "espsqueezelite"
-#endif
-#ifndef CONFIG_A2DP_CONTROL_DELAY_MS
-#define CONFIG_A2DP_CONTROL_DELAY_MS 1000
-#endif
+#define LOCK   pthread_mutex_lock(&(outputbuf->mutex))
+#define UNLOCK pthread_mutex_unlock(&(outputbuf->mutex))
+int64_t connecting_timeout = 0;
+static const char *  art_a2dp_connected[]={"\n",
+		"           ___  _____  _____     _____                            _           _ _ ",
+		"     /\\   |__ \\|  __ \\|  __ \\   / ____|                          | |         | | |",
+		"    /  \\     ) | |  | | |__) | | |     ___  _ __  _ __   ___  ___| |_ ___  __| | |",
+		"   / /\\ \\   / /| |  | |  ___/  | |    / _ \\| '_ \\| '_ \\ / _ \\/ __| __/ _ \\/ _` | |",
+		"  / ____ \\ / /_| |__| | |      | |___| (_) | | | | | | |  __/ (__| ||  __/ (_| |_|",
+		" /_/    \\_\\____|_____/|_|       \\_____\\___/|_| |_|_| |_|\\___|\\___|\\__\\___|\\__,_(_)\n",
+		"\0"};
+static const char * art_a2dp_connecting[]= {"\n",
+		 "           ___  _____  _____     _____                            _   _                   ",
+		 "     /\\   |__ \\|  __ \\|  __ \\   / ____|                          | | (_)                  ",
+		 "    /  \\     ) | |  | | |__) | | |     ___  _ __  _ __   ___  ___| |_ _ _ __   __ _       ",
+		 "   / /\\ \\   / /| |  | |  ___/  | |    / _ \\| '_ \\| '_ \\ / _ \\/ __| __| | '_ \\ / _` |      ",
+		 "  / ____ \\ / /_| |__| | |      | |___| (_) | | | | | | |  __/ (__| |_| | | | | (_| |_ _ _ ",
+		 " /_/    \\_\\____|_____/|_|       \\_____\\___/|_| |_|_| |_|\\___|\\___|\\__|_|_| |_|\\__, (_|_|_)",
+		 "                                                                               __/ |       ",
+		 "                                                                              |___/        \n",
+		 "\0"};
 
 static void bt_app_av_state_connecting(uint16_t event, void *param);
 
+
 #define A2DP_TIMER_INIT connecting_timeout = esp_timer_get_time() +(CONFIG_A2DP_CONNECT_TIMEOUT_MS * 1000)
 #define IS_A2DP_TIMER_OVER esp_timer_get_time() >= connecting_timeout
 
@@ -106,12 +79,12 @@ static void bt_app_av_state_connecting(uint16_t event, void *param);
 #define BYTES_TO_FRAME(b) b/BYTES_PER_FRAME
 
 
-#define RESET_ALL_MIN_MAX RESET_MIN_MAX(req); RESET_MIN_MAX(rec); RESET_MIN_MAX(bt);RESET_MIN_MAX_DURATION(lock_bt_time);RESET_MIN_MAX(under); RESET_MIN_MAX_DURATION(lock_out_time)
+#define RESET_ALL_MIN_MAX RESET_MIN_MAX(req); RESET_MIN_MAX(rec); RESET_MIN_MAX(bt);RESET_MIN_MAX(under); RESET_MIN_MAX_DURATION(stream_buf); RESET_MIN_MAX_DURATION(lock_out_time)
 
+DECLARE_MIN_MAX(stream_buf);
 DECLARE_MIN_MAX(req);
 DECLARE_MIN_MAX(rec);
 DECLARE_MIN_MAX(bt);
-DECLARE_MIN_MAX_DURATION(lock_bt_time);
 DECLARE_MIN_MAX(under);
 DECLARE_MIN_MAX_DURATION(lock_out_time);
 
@@ -129,48 +102,6 @@ void *audio_calloc(size_t nmemb, size_t size) {
 		return calloc(nmemb, size);
 }
 
-struct codec *register_mpg(void) {
-	LOG_INFO("mpg unavailable");
-	return NULL;
-}
-
-#if !CONFIG_INCLUDE_FAAD
-struct codec *register_faad(void) {
-	LOG_INFO("aac unavailable");
-	return NULL;
-}
-#endif
-
-#if !CONFIG_INCLUDE_MAD
-struct codec *register_mad(void) {
-	LOG_INFO("mad unavailable");
-	return NULL;
-}
-#endif
-
-#if !CONFIG_INCLUDE_FLAC
-struct codec *register_flac(void) {
-	LOG_INFO("flac unavailable");
-	return NULL;
-}
-#endif
-
-#if !CONFIG_INCLUDE_VORBIS
-struct codec *register_vorbis(void) {
-	LOG_INFO("vorbis unavailable");
-	return NULL;
-}
-#endif
-
-#if !CONFIG_INCLUDE_ALAC
-struct codec *register_alac(void) {
-	LOG_INFO("alac unavailable");
-	return NULL;
-}
-#endif
-
-#define LOG_DEBUG_EVENT(e) LOG_DEBUG("evt: " STR(e))
-#define LOG_SDEBUG_EVENT(e) LOG_SDEBUG("evt: " STR(e))
 
 /* event for handler "bt_av_hdl_stack_up */
 enum {
@@ -239,36 +170,91 @@ static uint32_t s_pkt_cnt = 0;
 
 static TimerHandle_t s_tmr;
 
-void hal_bluetooth_init(log_level level)
+static struct {
+    struct arg_str *sink_name;
+    struct arg_int *control_delay;
+    struct arg_int *connect_timeout_delay;
+    struct arg_end *end;
+} squeezelite_args;
+
+void hal_bluetooth_init(const char * options)
 {
+	ESP_LOGD(TAG,"Initializing Bluetooth HAL");
+	//CONFIG_A2DP_SINK_NAME
+	//CONFIG_A2DP_CONTROL_DELAY_MS
+	//CONFIG_A2DP_CONNECT_TIMEOUT_MS
+
+	squeezelite_args.sink_name = arg_str1("n", "name", "<sink name>", "the name of the bluetooth to connect to");
+	squeezelite_args.control_delay = arg_int0("d", "delay", "<control delay>", "the delay between each pass at the A2DP control loop");
+	squeezelite_args.connect_timeout_delay = arg_int0("t","timeout", "<timeout>", "the timeout duration for connecting to the A2DP sink");
+	squeezelite_args.end = arg_end(2);
+
+
+	ESP_LOGD(TAG,"Copying parameters");
+	char * opts = strdup(options);
+	char **argv = malloc(sizeof(char**)*15);
+
+	size_t argv_size=15;
+
+	// change parms so ' appear as " for parsing the options
+	for (char* p = opts; (p = strchr(p, '\'')); ++p) *p = '"';
+	ESP_LOGD(TAG,"Splitting arg line: %s", opts);
+
+	argv_size = esp_console_split_argv(opts, argv, argv_size);
+	ESP_LOGD(TAG,"Parsing parameters");
+	int nerrors = arg_parse(argv_size , argv, (void **) &squeezelite_args);
+	if (nerrors != 0) {
+		ESP_LOGD(TAG,"Parsing Errors");
+		arg_print_errors(stdout, squeezelite_args.end, "BT");
+		arg_print_glossary_gnu(stdout, (void **) &squeezelite_args);
+		free(opts);
+		free(argv);
+		return;
+	}
+	if(squeezelite_args.sink_name->count == 0)
+	{
+		ESP_LOGD(TAG,"Using default sink name : %s",CONFIG_A2DP_SINK_NAME);
+		squeezelite_args.sink_name->sval[0] = CONFIG_A2DP_SINK_NAME;
+	}
+	if(squeezelite_args.connect_timeout_delay->count == 0)
+	{
+		ESP_LOGD(TAG,"Using default connect timeout");
+		squeezelite_args.connect_timeout_delay->ival[0]=CONFIG_A2DP_CONNECT_TIMEOUT_MS;
+	}
+	if(squeezelite_args.control_delay->count == 0)
+	{
+		ESP_LOGD(TAG,"Using default control delay");
+		squeezelite_args.control_delay->ival[0]=CONFIG_A2DP_CONTROL_DELAY_MS;
+	}
+	ESP_LOGD(TAG,"Freeing options");
+	free(argv);
+	free(opts);
 
 	/*
 	 * Bluetooth audio source init Start
 	 */
-	loglevel = level;
-	bt_set_log_level(level);
 	//running_test = false;
 	ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_BLE));
 
 	esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
 
 	if (esp_bt_controller_init(&bt_cfg) != ESP_OK) {
-		LOG_ERROR("%s initialize controller failed\n", __func__);
+		ESP_LOGE(TAG,"%s initialize controller failed\n", __func__);
 		return;
 	}
 
 	if (esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT) != ESP_OK) {
-		LOG_ERROR("%s enable controller failed\n", __func__);
+		ESP_LOGE(TAG,"%s enable controller failed\n", __func__);
 		return;
 	}
 
 	if (esp_bluedroid_init() != ESP_OK) {
-		LOG_ERROR("%s initialize bluedroid failed\n", __func__);
+		ESP_LOGE(TAG,"%s initialize bluedroid failed\n", __func__);
 		return;
 	}
 
 	if (esp_bluedroid_enable() != ESP_OK) {
-		LOG_ERROR("%s enable bluedroid failed\n", __func__);
+		ESP_LOGE(TAG,"%s enable bluedroid failed\n", __func__);
 		return;
 	}
    /* create application task */
@@ -295,46 +281,6 @@ void hal_bluetooth_init(log_level level)
 }
 static int32_t bt_app_a2d_data_cb(uint8_t *data, int32_t len)
 {
-#ifdef USE_BT_RING_BUFFER
-	int32_t avail_data=0,wanted_len=0, start_timer=0;
-
-	if (len < 0 || data == NULL ) {
-        return 0;
-    }
-
-
-	// This is how the BTC layer calculates the number of bytes to
-	// for us to send. (BTC_SBC_DEC_PCM_DATA_LEN * sizeof(OI_INT16) - availPcmBytes
-	wanted_len=len;
-	TIME_MEASUREMENT_START(start_timer);
-	SET_MIN_MAX(len,req);
-	LOCK_BT;
-	SET_MIN_MAX_SIZED(_buf_used(btbuf),bt,btbuf->size);
-	do {
-
-		avail_data=min(_buf_cont_read(btbuf),wanted_len);
-		if(avail_data>0){
-			memcpy(data,btbuf->readp,avail_data);
-			_buf_inc_readp(btbuf,avail_data);
-			wanted_len-=avail_data;
-			data+=avail_data;
-		}
-		else {
-			assert(wanted_len>0);
-			assert(avail_data==0);
-			SET_MIN_MAX(wanted_len, under);
-		}
-	} while (wanted_len > 0 && avail_data != 0);
-
-	UNLOCK_BT;
-	SET_MIN_MAX(TIME_MEASUREMENT_GET(start_timer),lock_bt_time);
-	SET_MIN_MAX((len-wanted_len), rec);
-	TIME_MEASUREMENT_START(start_timer);
-	output_bt_check_buffer();
-	SET_MIN_MAX(TIME_MEASUREMENT_GET(start_timer),lock_out_time);
-	return len-wanted_len;
-
-#else
 	int32_t avail_data=0,wanted_len=0, start_timer=0;
 
 	if (len < 0 || data == NULL ) {
@@ -350,7 +296,6 @@ static int32_t bt_app_a2d_data_cb(uint8_t *data, int32_t len)
 	LOCK;
 	SET_MIN_MAX_SIZED(_buf_used(outputbuf),bt,outputbuf->size);
 	do {
-
 		avail_data = _output_frames( wanted_len/BYTES_PER_FRAME )*BYTES_PER_FRAME; // Keep the transfer buffer full
 		wanted_len-=avail_data;
 	} while (wanted_len > 0 && avail_data != 0);
@@ -368,8 +313,6 @@ static int32_t bt_app_a2d_data_cb(uint8_t *data, int32_t len)
 	output_bt_check_buffer();
 
 	return len-wanted_len;
-
-#endif
 }
 static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
 {
@@ -389,48 +332,48 @@ void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
         {
             if (s_a2d_state == APP_AV_STATE_DISCOVERED)
             {
-            	LOG_INFO("Discovery completed.  Ready to start connecting to %s. ",s_peer_bdname);
+            	ESP_LOGI(TAG,"Discovery completed.  Ready to start connecting to %s. ",s_peer_bdname);
             	s_a2d_state = APP_AV_STATE_UNCONNECTED;
             }
             else
             {
                 // not discovered, continue to discover
-                LOG_INFO("Device discovery failed, continue to discover...");
+                ESP_LOGI(TAG,"Device discovery failed, continue to discover...");
                 esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 10, 0);
             }
         }
         else if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STARTED) {
-            LOG_INFO("Discovery started.");
+            ESP_LOGI(TAG,"Discovery started.");
         }
         else
         {
-        	LOG_DEBUG("This shouldn't happen.  Discovery has only 2 states (for now).");
+        	ESP_LOGD(TAG,"This shouldn't happen.  Discovery has only 2 states (for now).");
         }
         break;
     }
     case ESP_BT_GAP_RMT_SRVCS_EVT:
-    	LOG_DEBUG_EVENT(ESP_BT_GAP_RMT_SRVCS_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,ESP_BT_GAP_RMT_SRVCS_EVT);
     	break;
     case ESP_BT_GAP_RMT_SRVC_REC_EVT:
-    	LOG_DEBUG_EVENT(ESP_BT_GAP_RMT_SRVC_REC_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,ESP_BT_GAP_RMT_SRVC_REC_EVT);
         break;
     case ESP_BT_GAP_AUTH_CMPL_EVT: {
     	if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) {
-            LOG_INFO("authentication success: %s", param->auth_cmpl.device_name);
+            ESP_LOGI(TAG,"authentication success: %s", param->auth_cmpl.device_name);
             //esp_log_buffer_hex(param->auth_cmpl.bda, ESP_BD_ADDR_LEN);
         } else {
-            LOG_ERROR("authentication failed, status:%d", param->auth_cmpl.stat);
+            ESP_LOGE(TAG,"authentication failed, status:%d", param->auth_cmpl.stat);
         }
         break;
     }
     case ESP_BT_GAP_PIN_REQ_EVT: {
-    	LOG_INFO("ESP_BT_GAP_PIN_REQ_EVT min_16_digit:%d", param->pin_req.min_16_digit);
+    	ESP_LOGI(TAG,"ESP_BT_GAP_PIN_REQ_EVT min_16_digit:%d", param->pin_req.min_16_digit);
         if (param->pin_req.min_16_digit) {
-            LOG_INFO("Input pin code: 0000 0000 0000 0000");
+            ESP_LOGI(TAG,"Input pin code: 0000 0000 0000 0000");
             esp_bt_pin_code_t pin_code = {0};
             esp_bt_gap_pin_reply(param->pin_req.bda, true, 16, pin_code);
         } else {
-            LOG_INFO("Input pin code: 1234");
+            ESP_LOGI(TAG,"Input pin code: 1234");
             esp_bt_pin_code_t pin_code;
             pin_code[0] = '1';
             pin_code[1] = '2';
@@ -443,18 +386,18 @@ void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
 
 #if (CONFIG_BT_SSP_ENABLED == true)
     case ESP_BT_GAP_CFM_REQ_EVT:
-        LOG_INFO("ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %d", param->cfm_req.num_val);
+        ESP_LOGI(TAG,"ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %d", param->cfm_req.num_val);
         esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true);
         break;
     case ESP_BT_GAP_KEY_NOTIF_EVT:
-        LOG_INFO("ESP_BT_GAP_KEY_NOTIF_EVT passkey:%d", param->key_notif.passkey);
+        ESP_LOGI(TAG,"ESP_BT_GAP_KEY_NOTIF_EVT passkey:%d", param->key_notif.passkey);
         break;
-        LOG_INFO("ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!");
+        ESP_LOGI(TAG,"ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!");
         break;
 #endif
 
     default: {
-        LOG_INFO("event: %d", event);
+        ESP_LOGI(TAG,"event: %d", event);
         break;
     }
     }
@@ -468,13 +411,13 @@ static void a2d_app_heart_beat(void *arg)
 
 static void bt_app_av_sm_hdlr(uint16_t event, void *param)
 {
-    //LOG_DEBUG("%s state %s, evt 0x%x, output state: %d", __func__, APP_AV_STATE_DESC[s_a2d_state], event, output.state);
+    //ESP_LOGD(TAG,"%s state %s, evt 0x%x, output state: %d", __func__, APP_AV_STATE_DESC[s_a2d_state], event, output.state);
     switch (s_a2d_state) {
     case APP_AV_STATE_DISCOVERING:
-    	LOG_SDEBUG("state %s, evt 0x%x, output state: %s", APP_AV_STATE_DESC[s_a2d_state], event, get_output_state_desc(output.state));
+    	ESP_LOGV(TAG,"state %s, evt 0x%x, output state: %s", APP_AV_STATE_DESC[s_a2d_state], event, get_output_state_desc(output.state));
     	break;
     case APP_AV_STATE_DISCOVERED:
-    	LOG_SDEBUG("state %s, evt 0x%x, output state: %s", APP_AV_STATE_DESC[s_a2d_state], event, get_output_state_desc(output.state));
+    	ESP_LOGV(TAG,"state %s, evt 0x%x, output state: %s", APP_AV_STATE_DESC[s_a2d_state], event, get_output_state_desc(output.state));
         break;
     case APP_AV_STATE_UNCONNECTED:
         bt_app_av_state_unconnected(event, param);
@@ -489,7 +432,7 @@ static void bt_app_av_sm_hdlr(uint16_t event, void *param)
         bt_app_av_state_disconnecting(event, param);
         break;
     default:
-        LOG_ERROR("%s invalid state %d", __func__, s_a2d_state);
+        ESP_LOGE(TAG,"%s invalid state %d", __func__, s_a2d_state);
         break;
     }
 }
@@ -536,7 +479,7 @@ static bool get_name_from_eir(uint8_t *eir, uint8_t *bdname, uint8_t *bdname_len
 
     return false;
 }
-#define LOG_INFO_NO_LF(fmt, ...)   if (loglevel >= lINFO)  logprint(fmt, ##__VA_ARGS__)
+
 static void filter_inquiry_scan_result(esp_bt_gap_cb_param_t *param)
 {
     char bda_str[18];
@@ -547,27 +490,27 @@ static void filter_inquiry_scan_result(esp_bt_gap_cb_param_t *param)
     esp_bt_gap_dev_prop_t *p;
     memset(s_peer_bdname, 0x00,sizeof(s_peer_bdname));
 
-    LOG_INFO("\n=======================\nScanned device: %s", bda2str(param->disc_res.bda, bda_str, 18));
+    ESP_LOGI(TAG,"\n=======================\nScanned device: %s", bda2str(param->disc_res.bda, bda_str, 18));
     for (int i = 0; i < param->disc_res.num_prop; i++) {
         p = param->disc_res.prop + i;
         switch (p->type) {
         case ESP_BT_GAP_DEV_PROP_COD:
             cod = *(uint32_t *)(p->val);
-            LOG_INFO_NO_LF("\n-- Class of Device: 0x%x", cod);
+            ESP_LOGI(TAG,"-- Class of Device: 0x%x", cod);
             break;
         case ESP_BT_GAP_DEV_PROP_RSSI:
             rssi = *(int8_t *)(p->val);
-            LOG_INFO_NO_LF("\n-- RSSI: %d", rssi);
+            ESP_LOGI(TAG,"-- RSSI: %d", rssi);
             break;
         case ESP_BT_GAP_DEV_PROP_EIR:
             eir = (uint8_t *)(p->val);
-            LOG_INFO_NO_LF("\n-- EIR: %d", eir);
+            ESP_LOGI(TAG,"-- EIR: %u", *eir);
             break;
         case ESP_BT_GAP_DEV_PROP_BDNAME:
             nameLen = (p->len > ESP_BT_GAP_MAX_BDNAME_LEN) ? ESP_BT_GAP_MAX_BDNAME_LEN : (uint8_t)p->len;
             memcpy(s_peer_bdname, (uint8_t *)(p->val), nameLen);
             s_peer_bdname[nameLen] = '\0';
-            LOG_INFO_NO_LF("\n-- Name: %s", s_peer_bdname);
+            ESP_LOGI(TAG,"-- Name: %s", s_peer_bdname);
             break;
         default:
             break;
@@ -575,40 +518,40 @@ static void filter_inquiry_scan_result(esp_bt_gap_cb_param_t *param)
     }
     if (!esp_bt_gap_is_valid_cod(cod)){
     /* search for device with MAJOR service class as "rendering" in COD */
-    	LOG_INFO_NO_LF("\n--Invalid class of device. Skipping.\n");
+    	ESP_LOGI(TAG,"--Invalid class of device. Skipping.\n");
     	return;
     }
     else if (!(esp_bt_gap_get_cod_srvc(cod) & ESP_BT_COD_SRVC_RENDERING))
     {
-    	LOG_INFO_NO_LF("\n--Not a rendering device. Skipping.\n");
+    	ESP_LOGI(TAG,"--Not a rendering device. Skipping.\n");
     	return;
     }
 
 
     /* search for device named "ESP_SPEAKER" in its extended inqury response */
     if (eir) {
-    	LOG_INFO_NO_LF("\n--Getting details from eir.\n");
+    	ESP_LOGI(TAG,"--Getting details from eir.\n");
         get_name_from_eir(eir, s_peer_bdname, NULL);
-        LOG_INFO_NO_LF("\n--Device name is %s\n",s_peer_bdname);
+        ESP_LOGI(TAG,"--Device name is %s\n",s_peer_bdname);
     }
 
     if (strcmp((char *)s_peer_bdname, CONFIG_A2DP_SINK_NAME) == 0) {
-    	LOG_INFO_NO_LF("Found a target device! address %s, name %s", bda_str, s_peer_bdname);
-    	LOG_INFO_NO_LF("\n=======================\n");
+    	ESP_LOGI(TAG,"Found a target device! address %s, name %s", bda_str, s_peer_bdname);
+    	ESP_LOGI(TAG,"=======================\n");
         if(esp_bt_gap_cancel_discovery()!=ESP_ERR_INVALID_STATE)
         {
-        	LOG_INFO("Cancel device discovery ...");
+        	ESP_LOGI(TAG,"Cancel device discovery ...");
 			memcpy(s_peer_bda, param->disc_res.bda, ESP_BD_ADDR_LEN);
         	s_a2d_state = APP_AV_STATE_DISCOVERED;
         }
         else
         {
-        	LOG_ERROR("Cancel device discovery failed...");
+        	ESP_LOGE(TAG,"Cancel device discovery failed...");
         }
     }
     else
     {
-    	LOG_INFO("Not the device we are looking for. Continuing scan.");
+    	ESP_LOGI(TAG,"Not the device we are looking for. Continuing scan.");
     }
 }
 
@@ -618,11 +561,11 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
 
     switch (event) {
     case BT_APP_EVT_STACK_UP: {
-    	LOG_INFO("BT Stack going up.");
+    	ESP_LOGI(TAG,"BT Stack going up.");
         /* set up device name */
         char *dev_name = CONFIG_A2DP_DEV_NAME;
         esp_bt_dev_set_device_name(dev_name);
-        LOG_INFO("Preparing to connect to device: %s",CONFIG_A2DP_SINK_NAME);
+        ESP_LOGI(TAG,"Preparing to connect to device: %s",CONFIG_A2DP_SINK_NAME);
 
         /* register GAP callback function */
         esp_bt_gap_register_callback(bt_app_gap_cb);
@@ -636,7 +579,7 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
         esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
 
         /* start device discovery */
-        LOG_INFO("Starting device discovery...");
+        ESP_LOGI(TAG,"Starting device discovery...");
         s_a2d_state = APP_AV_STATE_DISCOVERING;
         esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 10, 0);
 
@@ -650,7 +593,7 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
         break;
     }
     default:
-        LOG_ERROR("%s unhandled evt %d", __func__, event);
+    	ESP_LOGE(TAG,"%s unhandled evt %d", __func__, event);
         break;
     }
 }
@@ -681,19 +624,13 @@ static void bt_app_av_media_proc(uint16_t event, void *param)
     esp_a2d_cb_param_t *a2d = NULL;
     LOCK;
     output_state out_state=output.state;
-    unsigned start_frames = output.start_frames;
     UNLOCK;
-#ifdef USE_BT_RING_BUFFER
-    LOCK_BT;
-    unsigned bt_buffer_used=_buf_used(btbuf);
-    UNLOCK_BT;
-#endif
     switch (s_media_state) {
     case APP_AV_MEDIA_STATE_IDLE: {
     	if (event == BT_APP_HEART_BEAT_EVT) {
-            if(out_state > OUTPUT_OFF)
+            if(out_state > OUTPUT_STOPPED)
             {
-            	LOG_INFO("Output state is %s, a2dp media ready and connected. Checking if A2DP is ready.", get_output_state_desc(out_state));
+            	ESP_LOGI(TAG,"Output state is %s, a2dp media ready and connected. Checking if A2DP is ready.", get_output_state_desc(out_state));
             	esp_a2d_media_ctrl(ESP_A2D_MEDIA_CTRL_CHECK_SRC_RDY);
             }
 
@@ -702,7 +639,7 @@ static void bt_app_av_media_proc(uint16_t event, void *param)
 			if (a2d->media_ctrl_stat.cmd == ESP_A2D_MEDIA_CTRL_CHECK_SRC_RDY &&
 					a2d->media_ctrl_stat.status == ESP_A2D_MEDIA_CTRL_ACK_SUCCESS
 					) {
-				LOG_INFO("a2dp media ready, waiting for media buffering ...");
+				ESP_LOGI(TAG,"a2dp media ready, waiting for media buffering ...");
 				s_media_state = APP_AV_MEDIA_STATE_BUFFERING;
 			}
         }
@@ -715,37 +652,25 @@ static void bt_app_av_media_proc(uint16_t event, void *param)
 				case OUTPUT_PAUSE_FRAMES :
 				case OUTPUT_SKIP_FRAMES:
 				case OUTPUT_START_AT:
-#ifndef USE_BT_RING_BUFFER
 				case OUTPUT_BUFFER:
-#endif
 	            	 // Buffer is ready, local buffer has some data, start playback!
-					LOG_INFO("Buffering complete, out state is %s, a2dp media ready and connected. Starting playback! ", get_output_state_desc(out_state));
+					ESP_LOGI(TAG,"Out state is %s, a2dp media ready and connected. Starting playback! ", get_output_state_desc(out_state));
 					s_media_state = APP_AV_MEDIA_STATE_STARTING;
 					esp_a2d_media_ctrl(ESP_A2D_MEDIA_CTRL_START);
-#ifdef USE_BT_RING_BUFFER
-					break;
-
-					case OUTPUT_BUFFER:
-
-					LOG_DEBUG("Buffering... BT Buffer: %d bytes. Start threshold: %u,  ",bt_buffer_used, start_frames*BYTES_PER_FRAME);
-#endif
 					break;
 				case OUTPUT_STOPPED:
 				case OUTPUT_OFF:
-					LOG_DEBUG("Output state is %s. Changing app status to ",get_output_state_desc(out_state));
+					ESP_LOGD(TAG,"Output state is %s. Changing app status to ",get_output_state_desc(out_state));
 	                s_media_state = APP_AV_MEDIA_STATE_STOPPING;
 	                esp_a2d_media_ctrl(ESP_A2D_MEDIA_CTRL_STOP);
-#ifdef USE_BT_RING_BUFFER
-	                output_bt_check_buffer();
-#endif
 	                break;
 				default:
-					LOG_ERROR("Unknown output status while waiting for buffering to complete %d",out_state);
+					ESP_LOGE(TAG,"Unknown output status while waiting for buffering to complete %d",out_state);
 					break;
 			}
           }
       	else{
-      		LOG_WARN("Received unknown event while in state APP_AV_MEDIA_STATE_BUFFERING");
+      		ESP_LOGW(TAG,"Received unknown event while in state APP_AV_MEDIA_STATE_BUFFERING");
       	}
 
           break;
@@ -757,11 +682,11 @@ static void bt_app_av_media_proc(uint16_t event, void *param)
             a2d = (esp_a2d_cb_param_t *)(param);
             if (a2d->media_ctrl_stat.cmd == ESP_A2D_MEDIA_CTRL_START &&
                     a2d->media_ctrl_stat.status == ESP_A2D_MEDIA_CTRL_ACK_SUCCESS) {
-                LOG_INFO("a2dp media started successfully.");
+            	ESP_LOGI(TAG,"a2dp media started successfully.");
                 s_media_state = APP_AV_MEDIA_STATE_STARTED;
             } else {
                 // not started succesfully, transfer to idle state
-                LOG_INFO("a2dp media start failed.");
+            	ESP_LOGI(TAG,"a2dp media start failed.");
                 s_media_state = APP_AV_MEDIA_STATE_IDLE;
             }
         }
@@ -770,35 +695,36 @@ static void bt_app_av_media_proc(uint16_t event, void *param)
     case APP_AV_MEDIA_STATE_STARTED: {
         if (event == BT_APP_HEART_BEAT_EVT) {
         	if(out_state <= OUTPUT_STOPPED) {
-                LOG_INFO("Output state is stopped. Stopping a2dp media ...");
+        		ESP_LOGI(TAG,"Output state is stopped. Stopping a2dp media ...");
                 s_media_state = APP_AV_MEDIA_STATE_STOPPING;
                 esp_a2d_media_ctrl(ESP_A2D_MEDIA_CTRL_STOP);
-#ifdef USE_BT_RING_BUFFER
-				output_bt_check_buffer();
-#endif
             }
         	else
         	{
+        		LOCK_S;
+        		SET_MIN_MAX_SIZED(_buf_used(streambuf),stream_buf,streambuf->size);
+        		UNLOCK_S;
         		static time_t lastTime=0;
         		if (lastTime <= gettime_ms() )
 				{
 					lastTime = gettime_ms() + 15000;
-					LOG_DEBUG( "              +==========+==========+================+=====+================+");
-					LOG_DEBUG( "              |      max |      min |        average | avg |          count |");
-					LOG_DEBUG( "              |  (bytes) |  (bytes) |        (bytes) | pct |                |");
-					LOG_DEBUG( "              +==========+==========+================+=====+================+");
-					LOG_DEBUG(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("available",bt));
-					LOG_DEBUG(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("requested",req));
-					LOG_DEBUG(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("received",rec));
-					LOG_DEBUG(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("underrun",under));
-					LOG_DEBUG( "              +==========+==========+================+=====+================+");
-					LOG_DEBUG("\n");
-					LOG_DEBUG("              ==========+==========+===========+===========+  ");
-					LOG_DEBUG("              max (us)  | min (us) |   avg(us) |  count    |  ");
-					LOG_DEBUG("              ==========+==========+===========+===========+  ");
-					LOG_DEBUG(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("BT Buf Lock",lock_bt_time));
-					LOG_DEBUG(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("Out Buf Lock",lock_out_time));
-					LOG_DEBUG("              ==========+==========+===========+===========+");
+					ESP_LOGD(TAG, "Statistics over %u secs. " , STATS_REPORT_DELAY_MS/1000);
+					ESP_LOGD(TAG, "              +==========+==========+================+=====+================+");
+					ESP_LOGD(TAG, "              |      max |      min |        average | avg |          count |");
+					ESP_LOGD(TAG, "              |  (bytes) |  (bytes) |        (bytes) | pct |                |");
+					ESP_LOGD(TAG, "              +==========+==========+================+=====+================+");
+					ESP_LOGD(TAG,LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("stream avl",stream_buf));
+					ESP_LOGD(TAG,LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("output avl",bt));
+					ESP_LOGD(TAG,LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("requested",req));
+					ESP_LOGD(TAG,LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("received",rec));
+					ESP_LOGD(TAG,LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("underrun",under));
+					ESP_LOGD(TAG, "              +==========+==========+================+=====+================+");
+					ESP_LOGD(TAG,"\n");
+					ESP_LOGD(TAG,"              ==========+==========+===========+===========+  ");
+					ESP_LOGD(TAG,"              max (us)  | min (us) |   avg(us) |  count    |  ");
+					ESP_LOGD(TAG,"              ==========+==========+===========+===========+  ");
+					ESP_LOGD(TAG,LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("Out Buf Lock",lock_out_time));
+					ESP_LOGD(TAG,"              ==========+==========+===========+===========+");
 					RESET_ALL_MIN_MAX;
 				}
 
@@ -807,12 +733,12 @@ static void bt_app_av_media_proc(uint16_t event, void *param)
         break;
     }
     case APP_AV_MEDIA_STATE_STOPPING: {
-    	LOG_DEBUG_EVENT(APP_AV_MEDIA_STATE_STOPPING);
+    	ESP_LOG_DEBUG_EVENT(TAG,APP_AV_MEDIA_STATE_STOPPING);
         if (event == ESP_A2D_MEDIA_CTRL_ACK_EVT) {
             a2d = (esp_a2d_cb_param_t *)(param);
             if (a2d->media_ctrl_stat.cmd == ESP_A2D_MEDIA_CTRL_STOP &&
                     a2d->media_ctrl_stat.status == ESP_A2D_MEDIA_CTRL_ACK_SUCCESS) {
-                LOG_INFO("a2dp media stopped successfully...");
+                ESP_LOGI(TAG,"a2dp media stopped successfully...");
                 //s_media_state = APP_AV_MEDIA_STATE_WAIT_DISCONNECT;
               //  if(CONFIG_A2DP_DISCONNECT_MS==0){
                 	// we're not going to disconnect.
@@ -824,7 +750,7 @@ static void bt_app_av_media_proc(uint16_t event, void *param)
 //                	s_media_state = APP_AV_MEDIA_STATE_WAIT_DISCONNECT;
 //                }
             } else {
-                LOG_INFO("a2dp media stopping...");
+                ESP_LOGI(TAG,"a2dp media stopping...");
                 esp_a2d_media_ctrl(ESP_A2D_MEDIA_CTRL_STOP);
             }
         }
@@ -848,7 +774,7 @@ static void bt_app_av_state_unconnected(uint16_t event, void *param)
 //	UNLOCK;
 	switch (event) {
     case ESP_A2D_CONNECTION_STATE_EVT:
-    	LOG_DEBUG_EVENT(ESP_A2D_CONNECTION_STATE_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_CONNECTION_STATE_EVT);
     	// this could happen if connection was established
     	// right after we timed out. Pass the call down to the connecting
     	// handler.
@@ -859,27 +785,27 @@ static void bt_app_av_state_unconnected(uint16_t event, void *param)
 
     	break;
     case ESP_A2D_AUDIO_STATE_EVT:
-    	LOG_DEBUG_EVENT(ESP_A2D_AUDIO_STATE_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_AUDIO_STATE_EVT);
 
     	break;
     case ESP_A2D_AUDIO_CFG_EVT:
-    	LOG_DEBUG_EVENT(ESP_A2D_AUDIO_CFG_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_AUDIO_CFG_EVT);
     	break;
     case ESP_A2D_MEDIA_CTRL_ACK_EVT:
-    	LOG_DEBUG_EVENT(ESP_A2D_MEDIA_CTRL_ACK_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_MEDIA_CTRL_ACK_EVT);
     	break;
     case BT_APP_HEART_BEAT_EVT: {
        // uint8_t *p = s_peer_bda;
-       // LOG_INFO("BT_APP_HEART_BEAT_EVT a2dp connecting to peer: %02x:%02x:%02x:%02x:%02x:%02x",p[0], p[1], p[2], p[3], p[4], p[5]);
+       // ESP_LOGI(TAG,"BT_APP_HEART_BEAT_EVT a2dp connecting to peer: %02x:%02x:%02x:%02x:%02x:%02x",p[0], p[1], p[2], p[3], p[4], p[5]);
         switch (esp_bluedroid_get_status()) {
 		case ESP_BLUEDROID_STATUS_UNINITIALIZED:
-			LOG_SDEBUG("BlueDroid Status is ESP_BLUEDROID_STATUS_UNINITIALIZED.");
+			ESP_LOGV(TAG,"BlueDroid Status is ESP_BLUEDROID_STATUS_UNINITIALIZED.");
 			break;
 		case ESP_BLUEDROID_STATUS_INITIALIZED:
-			LOG_SDEBUG("BlueDroid Status is ESP_BLUEDROID_STATUS_INITIALIZED.");
+			ESP_LOGV(TAG,"BlueDroid Status is ESP_BLUEDROID_STATUS_INITIALIZED.");
 			break;
 		case ESP_BLUEDROID_STATUS_ENABLED:
-			LOG_SDEBUG("BlueDroid Status is ESP_BLUEDROID_STATUS_ENABLED.");
+			ESP_LOGV(TAG,"BlueDroid Status is ESP_BLUEDROID_STATUS_ENABLED.");
 			break;
 		default:
 			break;
@@ -889,21 +815,21 @@ static void bt_app_av_state_unconnected(uint16_t event, void *param)
 			if(esp_a2d_source_connect(s_peer_bda)==ESP_OK) {
 				s_a2d_state = APP_AV_STATE_CONNECTING;
 				for(uint8_t l=0;art_a2dp_connecting[l][0]!='\0';l++){
-					LOG_INFO_NO_LF("%s",art_a2dp_connecting[l]);
+					ESP_LOGI(TAG,"%s",art_a2dp_connecting[l]);
 				}
-				LOG_INFO("********** A2DP CONNECTING TO %s", s_peer_bdname);
+				ESP_LOGI(TAG,"********** A2DP CONNECTING TO %s", s_peer_bdname);
 				A2DP_TIMER_INIT;
 			}
 			else {
 				// there was an issue connecting... continue to discover
-				LOG_ERROR("Attempt at connecting failed, restart at discover...");
+				ESP_LOGE(TAG,"Attempt at connecting failed, restart at discover...");
 				esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 10, 0);
 	//		}
         }
         break;
     }
     default:
-        LOG_ERROR("%s unhandled evt %d", __func__, event);
+    	ESP_LOGE(TAG,"%s unhandled evt %d", __func__, event);
         break;
     }
 }
@@ -919,36 +845,36 @@ static void bt_app_av_state_connecting(uint16_t event, void *param)
             s_a2d_state =  APP_AV_STATE_CONNECTED;
             s_media_state = APP_AV_MEDIA_STATE_IDLE;
 			for(uint8_t l=0;art_a2dp_connected[l][0]!='\0';l++){
-				LOG_INFO_NO_LF("%s",art_a2dp_connected[l]);
+				ESP_LOGI(TAG,"%s",art_a2dp_connected[l]);
 			}
-			LOG_DEBUG("Setting scan mode to ESP_BT_NON_CONNECTABLE, ESP_BT_NON_DISCOVERABLE");
+			ESP_LOGD(TAG,"Setting scan mode to ESP_BT_NON_CONNECTABLE, ESP_BT_NON_DISCOVERABLE");
             esp_bt_gap_set_scan_mode(ESP_BT_NON_CONNECTABLE, ESP_BT_NON_DISCOVERABLE);
-            LOG_DEBUG("Done setting scan mode. App state is now CONNECTED and media state IDLE.");
+            ESP_LOGD(TAG,"Done setting scan mode. App state is now CONNECTED and media state IDLE.");
         } else if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) {
             s_a2d_state =  APP_AV_STATE_UNCONNECTED;
         }
         break;
     }
     case ESP_A2D_AUDIO_STATE_EVT:
-    	LOG_DEBUG_EVENT(ESP_A2D_AUDIO_STATE_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_AUDIO_STATE_EVT);
     	break;
     case ESP_A2D_AUDIO_CFG_EVT:
-    	LOG_DEBUG_EVENT(ESP_A2D_AUDIO_CFG_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_AUDIO_CFG_EVT);
     	break;
     case ESP_A2D_MEDIA_CTRL_ACK_EVT:
-    	LOG_DEBUG_EVENT(ESP_A2D_MEDIA_CTRL_ACK_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_MEDIA_CTRL_ACK_EVT);
     	break;
     case BT_APP_HEART_BEAT_EVT:
     	if (IS_A2DP_TIMER_OVER)
     	{
             s_a2d_state = APP_AV_STATE_UNCONNECTED;
-            LOG_ERROR("A2DP Connect time out!  Setting state to Unconnected. ");
+            ESP_LOGE(TAG,"A2DP Connect time out!  Setting state to Unconnected. ");
             A2DP_TIMER_INIT;
         }
-    	LOG_SDEBUG("BT_APP_HEART_BEAT_EVT");
+    	ESP_LOGV(TAG,"BT_APP_HEART_BEAT_EVT");
         break;
     default:
-        LOG_ERROR("%s unhandled evt %d", __func__, event);
+        ESP_LOGE(TAG,"%s unhandled evt %d", __func__, event);
         break;
     }
 }
@@ -961,14 +887,14 @@ static void bt_app_av_state_connected(uint16_t event, void *param)
     case ESP_A2D_CONNECTION_STATE_EVT: {
     	a2d = (esp_a2d_cb_param_t *)(param);
         if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) {
-            LOG_INFO("a2dp disconnected");
+            ESP_LOGI(TAG,"a2dp disconnected");
             s_a2d_state = APP_AV_STATE_UNCONNECTED;
             esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
         }
         break;
     }
     case ESP_A2D_AUDIO_STATE_EVT: {
-    	LOG_DEBUG_EVENT(ESP_A2D_AUDIO_STATE_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_AUDIO_STATE_EVT);
         a2d = (esp_a2d_cb_param_t *)(param);
         if (ESP_A2D_AUDIO_STATE_STARTED == a2d->audio_stat.state) {
             s_pkt_cnt = 0;
@@ -977,20 +903,20 @@ static void bt_app_av_state_connected(uint16_t event, void *param)
     }
     case ESP_A2D_AUDIO_CFG_EVT:
         // not suppposed to occur for A2DP source
-    	LOG_DEBUG_EVENT(ESP_A2D_AUDIO_CFG_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_AUDIO_CFG_EVT);
         break;
     case ESP_A2D_MEDIA_CTRL_ACK_EVT:{
-        	LOG_SDEBUG_EVENT(ESP_A2D_MEDIA_CTRL_ACK_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_MEDIA_CTRL_ACK_EVT);
             bt_app_av_media_proc(event, param);
             break;
         }
     case BT_APP_HEART_BEAT_EVT: {
-    	LOG_SDEBUG_EVENT(BT_APP_HEART_BEAT_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,BT_APP_HEART_BEAT_EVT);
         bt_app_av_media_proc(event, param);
         break;
     }
     default:
-        LOG_ERROR("%s unhandled evt %d", __func__, event);
+        ESP_LOGE(TAG,"%s unhandled evt %d", __func__, event);
         break;
     }
 }
@@ -1000,29 +926,29 @@ static void bt_app_av_state_disconnecting(uint16_t event, void *param)
     esp_a2d_cb_param_t *a2d = NULL;
     switch (event) {
     case ESP_A2D_CONNECTION_STATE_EVT: {
-    	LOG_DEBUG_EVENT(ESP_A2D_CONNECTION_STATE_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_CONNECTION_STATE_EVT);
         a2d = (esp_a2d_cb_param_t *)(param);
         if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) {
-            LOG_INFO("a2dp disconnected");
+            ESP_LOGI(TAG,"a2dp disconnected");
             s_a2d_state =  APP_AV_STATE_UNCONNECTED;
             esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
         }
         break;
     }
     case ESP_A2D_AUDIO_STATE_EVT:
-    	LOG_DEBUG_EVENT(ESP_A2D_AUDIO_STATE_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_AUDIO_STATE_EVT);
     	break;
     case ESP_A2D_AUDIO_CFG_EVT:
-    	LOG_DEBUG_EVENT(ESP_A2D_AUDIO_CFG_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_AUDIO_CFG_EVT);
     	break;
     case ESP_A2D_MEDIA_CTRL_ACK_EVT:
-    	LOG_DEBUG_EVENT(ESP_A2D_MEDIA_CTRL_ACK_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,ESP_A2D_MEDIA_CTRL_ACK_EVT);
     	break;
     case BT_APP_HEART_BEAT_EVT:
-    	LOG_DEBUG_EVENT(BT_APP_HEART_BEAT_EVT);
+    	ESP_LOG_DEBUG_EVENT(TAG,BT_APP_HEART_BEAT_EVT);
     	break;
     default:
-        LOG_ERROR("%s unhandled evt %d", __func__, event);
+        ESP_LOGE(TAG,"%s unhandled evt %d", __func__, event);
         break;
     }
 }

+ 165 - 0
components/platform_esp32/platform_esp32.h

@@ -0,0 +1,165 @@
+#pragma once
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "bt_app_core.h"
+#include "perf_trace.h"
+#include "esp_pthread.h"
+#ifndef QUOTE
+#define QUOTE(name) #name
+#define STR(macro)  QUOTE(macro)
+#endif
+extern void run_command(char * line);
+extern bool wait_for_wifi();
+
+//typedef struct {
+//	char opt_slimproto_logging[11];
+//	char opt_stream_logging[11];
+//	char opt_decode_logging[11];
+//	char opt_output_logging[11];
+//	char opt_player_name[11];
+//	char opt_output_rates[21];
+//	char opt_buffer[11];
+//} str_squeezelite_options ;
+extern void console_start();
+extern pthread_cond_t wifi_connect_suspend_cond;
+extern pthread_t wifi_connect_suspend_mutex;
+//static const char * art_wifi[]={
+//		"\n",
+//		"o          `O ooOoOOo OOooOoO ooOoOOo\n",
+//		"O           o    O    o          O   \n",
+//		"o           O    o    O          o   \n",
+//		"O           O    O    oOooO      O   \n",
+//		"o     o     o    o    O          o   \n",
+//		"O     O     O    O    o          O   \n",
+//		"`o   O o   O'    O    o          O   \n",
+//		" `OoO' `OoO'  ooOOoOo O'      ooOOoOo\n",
+//		"\n",
+//		""
+//};
+//static const char * art_wifi_connecting[]={
+//		" .oOOOo.",
+//		".O     o                                        o               \n",
+//		"o                                           O                   \n",
+//		"o                                          oOo                  \n",
+//		"o         .oOo. 'OoOo. 'OoOo. .oOo. .oOo    o   O  'OoOo. .oOoO \n",
+//		"O         O   o  o   O  o   O OooO' O       O   o   o   O o   O \n",
+//		"`o     .o o   O  O   o  O   o O     o       o   O   O   o O   o \n",
+//		" `OoooO'  `OoO'  o   O  o   O `OoO' `OoO'   `oO o'  o   O `OoOo \n",
+//		"                                                              O \n",
+//		"                                                           OoO' \n",
+//		"\n",
+//		""
+//};
+//static const char * art_wifi_connected[]={
+//		" .oOOOo.                                                   o       oO\n",
+//		".O     o                                                  O        OO\n",
+//		"o                                           O             o        oO\n",
+//		"o                                          oOo            o        Oo\n",
+//		"o         .oOo. 'OoOo. 'OoOo. .oOo. .oOo    o   .oOo. .oOoO        oO\n",
+//		"O         O   o  o   O  o   O OooO' O       O   OooO' o   O          \n",
+//		"`o     .o o   O  O   o  O   o O     o       o   O     O   o        Oo\n",
+//		" `OoooO'  `OoO'  o   O  o   O `OoO' `OoO'   `oO `OoO' `OoO'o       oO\n",
+//		"\n",
+//		""
+//};
+#define ESP_LOG_DEBUG_EVENT(tag,e) ESP_LOGD(tag,"evt: " QUOTE(e))
+typedef struct {
+	char * optName;
+	char * cmdLinePrefix;
+	char * description;
+	char * defaultValue;
+	char * relatedcommand;
+} optListStruct;
+optListStruct * getOptionByName(char * option);
+//static optListStruct optList[] = {
+//	{
+//		.optName= "log_slimproto",
+//		.cmdLinePrefix="-d slimproto=",
+//		.description="Slimproto Logging Level info|debug|sdebug",
+//		.defaultValue=(CONFIG_LOGGING_SLIMPROTO),
+//		.relatedcommand="squeezelite"
+//	},
+//	{
+//		.optName="log_stream",
+//		.cmdLinePrefix="-d stream=",
+//		.description="Stream Logging Level info|debug|sdebug",
+//		.defaultValue=(CONFIG_LOGGING_STREAM),
+//		.relatedcommand="squeezelite"
+//	},
+//	{
+//		.optName="log_decode",
+//		.cmdLinePrefix="-d decode=",
+//		.description="Decode Logging Level info|debug|sdebug",
+//		.defaultValue=(CONFIG_LOGGING_DECODE),
+//		.relatedcommand="squeezelite"
+//	},
+//	{
+//		.optName="log_output",
+//		.cmdLinePrefix="-d output=",
+//		.description="Output Logging Level info|debug|sdebug",
+//		.defaultValue=(CONFIG_LOGGING_OUTPUT),
+//		.relatedcommand="squeezelite"
+//	},
+//	{
+//		.optName="output_rates",
+//		.cmdLinePrefix="-r ",
+//		.description="Supported rates",
+//		.defaultValue=(CONFIG_OUTPUT_RATES),
+//		.relatedcommand="squeezelite"
+//	},
+//	{
+//		.optName="output_dev",
+//		.cmdLinePrefix="-O",
+//		.description="Output device to use. BT for Bluetooth, DAC for i2s DAC.",
+//		.defaultValue=(CONFIG_A2DP_SINK_NAME),
+//		.relatedcommand=""
+//	},
+//	{
+//		.optName="a2dp_sink_name",
+//		.cmdLinePrefix="",
+//		.description="Bluetooth sink name to connect to.",
+//		.defaultValue=(CONFIG_A2DP_SINK_NAME),
+//		.relatedcommand=""
+//	},
+//	{
+//		.optName="a2dp_dev_name",
+//		.cmdLinePrefix="",
+//		.description="A2DP Device name to use when connecting to audio sink.",
+//		.defaultValue=(CONFIG_A2DP_DEV_NAME),
+//		.relatedcommand=""
+//	},
+//	{
+//		.optName="a2dp_cntrldelay",
+//		.cmdLinePrefix="",
+//		.description="Delay (ms) for each pass of the A2DP control loop.",
+//		.defaultValue=STR(CONFIG_A2DP_CONTROL_DELAY_MS),
+//		.relatedcommand=""
+//	},
+//	{
+//		.optName="a2dp_timeout",
+//		.cmdLinePrefix="",
+//		.description="Delay (ms) for A2DP timeout on connect.",
+//		.defaultValue=STR(CONFIG_A2DP_CONNECT_TIMEOUT_MS),
+//		.relatedcommand=""
+//	},
+//	{
+//		.optName="wifi_ssid",
+//		.cmdLinePrefix="",
+//		.description="WiFi access point name to connect to.",
+//		.defaultValue=	(CONFIG_WIFI_SSID),
+//		.relatedcommand=""
+//	},
+//	{
+//		.optName="wifi_password",
+//		.cmdLinePrefix= "",
+//		.description="WiFi access point password.",
+//		.defaultValue=(CONFIG_WIFI_PASSWORD),
+//		.relatedcommand=""
+//	},
+//	{}
+//};
+
+#ifdef __cplusplus
+}
+#endif

+ 14 - 13
main/Kconfig.projbuild

@@ -132,13 +132,14 @@ menu "Squeezelite-ESP32"
 			default ""
 		    default "BT" if BTAUDIO
 		    default "DAC" if DACAUDIO
+		    
 		config OUTPUT_RATES
 			string "Output rates"
 			default "48000,44100"
 			help
-				<rates>[:<delay>]	Sample rates supported, allows output to be off when squeezelite is started; rates = <maxrate>|<minrate>-<maxrate>|<rate1>,<rate2>,<rate3>; delay = optional delay switching rates in ms  
-    	if DACAUDIO
-		    config I2S_NUM         
+				<rates>[:<delay>]	Sample rates supported, allows output to be off when squeezelite is started; rates = <maxrate>|<minrate>-<maxrate>|<rate1>,<rate2>,<rate3>; delay = optional delay switching rates in ms
+		menu "DAC I2S settings"  
+	    	config I2S_NUM         
 		        int "I2S channel (0 or 1). "
 		        default 0
 		        help
@@ -174,8 +175,8 @@ menu "Squeezelite-ESP32"
 			    default 16 if I2S_BITS_PER_CHANNEL_16
 			    default 24 if I2S_BITS_PER_CHANNEL_24
 			    default 8 if I2S_BITS_PER_CHANNEL_8
-		endif # DACAUDIO
-		if BTAUDIO
+		endmenu
+		menu "A2DP settings"
 		    config A2DP_SINK_NAME
 		        string "Name of Bluetooth A2DP device"
 		        default "SMSL BT4.2"
@@ -196,14 +197,14 @@ menu "Squeezelite-ESP32"
 		        default 1000
 		        help
 		            Increasing this value will give more chance for less stable connections to be established.	   
-            config A2DP_DISCONNECT_MS
-            	int "Time in ms before disconnecting from A2DP audio sink. Set to 0 for no disconnect."
-            	default 10000
-            	help
-            		Controls how long to wait before disconnecting from the A2DP audio sink after playback is stopped
-            		Longer delay will ensure better responsiveness at the expense of locking the audio sink for a longer period. 
-            		A shorter period may cause the player to disconnect between tracks change.
-		endif # BTAUDIO   
+	        config A2DP_DISCONNECT_MS
+	        	int "Time in ms before disconnecting from A2DP audio sink. Set to 0 for no disconnect."
+	        	default 10000
+	        	help
+	        		Controls how long to wait before disconnecting from the A2DP audio sink after playback is stopped
+	        		Longer delay will ensure better responsiveness at the expense of locking the audio sink for a longer period. 
+	        		A shorter period may cause the player to disconnect between tracks change.
+		endmenu
 	endmenu
 
 endmenu

+ 2 - 1
main/component.mk

@@ -7,7 +7,8 @@ CFLAGS += -O3 -DPOSIX -DLINKALL -DLOOPBACK -DNO_FAAD -DEMBEDDED -DTREMOR_ONLY -D
 	-I$(COMPONENT_PATH)/../components/codecs/inc/mad 		\
 	-I$(COMPONENT_PATH)/../components/codecs/inc/alac		\
 	-I$(COMPONENT_PATH)/../components/codecs/inc/helix-aac	\
-	-I$(COMPONENT_PATH)/../components/codecs/inc/vorbis 
+	-I$(COMPONENT_PATH)/../components/codecs/inc/vorbis \
+	-I$(COMPONENT_PATH)/../components/platform_esp32 
 	
 LDFLAGS += -s
 

+ 0 - 240
main/esp_app_main.c

@@ -1,240 +0,0 @@
-/* Scan Example
-
-   This example code is in the Public Domain (or CC0 licensed, at your option.)
-
-   Unless required by applicable law or agreed to in writing, this
-   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-   CONDITIONS OF ANY KIND, either express or implied.
-*/
-
-/*
-    This example shows how to use the All Channel Scan or Fast Scan to connect
-    to a Wi-Fi network.
-
-    In the Fast Scan mode, the scan will stop as soon as the first network matching
-    the SSID is found. In this mode, an application can set threshold for the
-    authentication mode and the Signal strength. Networks that do not meet the
-    threshold requirements will be ignored.
-
-    In the All Channel Scan mode, the scan will end only after all the channels
-    are scanned, and connection will start with the best network. The networks
-    can be sorted based on Authentication Mode or Signal Strength. The priority
-    for the Authentication mode is:  WPA2 > WPA > WEP > Open
-*/
-#include "squeezelite.h"
-#include "freertos/FreeRTOS.h"
-#include "freertos/event_groups.h"
-#include "esp_wifi.h"
-#include "esp_log.h"
-#include "esp_event.h"
-#include "nvs_flash.h"
-#include "sys/socket.h"
-#include "string.h"
-thread_cond_type wifi_connect_suspend_cond;
-mutex_type wifi_connect_suspend_mutex;
-char * art_wifi[]={
-		"\n",
-		"o          `O ooOoOOo OOooOoO ooOoOOo\n",
-		"O           o    O    o          O   \n",
-		"o           O    o    O          o   \n",
-		"O           O    O    oOooO      O   \n",
-		"o     o     o    o    O          o   \n",
-		"O     O     O    O    o          O   \n",
-		"`o   O o   O'    O    o          O   \n",
-		" `OoO' `OoO'  ooOOoOo O'      ooOOoOo\n",
-		"\n",
-		""
-};
-char * art_wifi_connecting[]={
-		" .oOOOo.",
-		".O     o                                        o               \n",
-		"o                                           O                   \n",
-		"o                                          oOo                  \n",
-		"o         .oOo. 'OoOo. 'OoOo. .oOo. .oOo    o   O  'OoOo. .oOoO \n",
-		"O         O   o  o   O  o   O OooO' O       O   o   o   O o   O \n",
-		"`o     .o o   O  O   o  O   o O     o       o   O   O   o O   o \n",
-		" `OoooO'  `OoO'  o   O  o   O `OoO' `OoO'   `oO o'  o   O `OoOo \n",
-		"                                                              O \n",
-		"                                                           OoO' \n",
-		"\n",
-		""
-};
-char * art_wifi_connected[]={
-		" .oOOOo.                                                   o       oO\n",
-		".O     o                                                  O        OO\n",
-		"o                                           O             o        oO\n",
-		"o                                          oOo            o        Oo\n",
-		"o         .oOo. 'OoOo. 'OoOo. .oOo. .oOo    o   .oOo. .oOoO        oO\n",
-		"O         O   o  o   O  o   O OooO' O       O   OooO' o   O          \n",
-		"`o     .o o   O  O   o  O   o O     o       o   O     O   o        Oo\n",
-		" `OoooO'  `OoO'  o   O  o   O `OoO' `OoO'   `oO `OoO' `OoO'o       oO\n",
-		"\n",
-		""
-};
-
-/*Set the SSID and Password via "make menuconfig"*/
-#define DEFAULT_SSID CONFIG_WIFI_SSID
-#define DEFAULT_PWD CONFIG_WIFI_PASSWORD
-
-#if CONFIG_WIFI_ALL_CHANNEL_SCAN
-#define DEFAULT_SCAN_METHOD WIFI_ALL_CHANNEL_SCAN
-#elif CONFIG_WIFI_FAST_SCAN
-#define DEFAULT_SCAN_METHOD WIFI_FAST_SCAN
-#else
-#define DEFAULT_SCAN_METHOD WIFI_FAST_SCAN
-#endif /*CONFIG_SCAN_METHOD*/
-
-#if CONFIG_WIFI_CONNECT_AP_BY_SIGNAL
-#define DEFAULT_SORT_METHOD WIFI_CONNECT_AP_BY_SIGNAL
-#elif CONFIG_WIFI_CONNECT_AP_BY_SECURITY
-#define DEFAULT_SORT_METHOD WIFI_CONNECT_AP_BY_SECURITY
-#else
-#define DEFAULT_SORT_METHOD WIFI_CONNECT_AP_BY_SIGNAL
-#endif /*CONFIG_SORT_METHOD*/
-
-#if CONFIG_FAST_SCAN_THRESHOLD
-#define DEFAULT_RSSI CONFIG_FAST_SCAN_MINIMUM_SIGNAL
-#if CONFIG_EXAMPLE_OPEN
-#define DEFAULT_AUTHMODE WIFI_AUTH_OPEN
-#elif CONFIG_EXAMPLE_WEP
-#define DEFAULT_AUTHMODE WIFI_AUTH_WEP
-#elif CONFIG_EXAMPLE_WPA
-#define DEFAULT_AUTHMODE WIFI_AUTH_WPA_PSK
-#elif CONFIG_EXAMPLE_WPA2
-#define DEFAULT_AUTHMODE WIFI_AUTH_WPA2_PSK
-#else
-#define DEFAULT_AUTHMODE WIFI_AUTH_OPEN
-#endif
-#else
-#define DEFAULT_RSSI -127
-#define DEFAULT_AUTHMODE WIFI_AUTH_OPEN
-#endif /*CONFIG_FAST_SCAN_THRESHOLD*/
-
-static const char *TAG = "scan";
-
-static void event_handler(void* arg, esp_event_base_t event_base, 
-                                int32_t event_id, void* event_data)
-{
-    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
-        esp_wifi_connect();
-    } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
-        esp_wifi_connect();
-    } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
-        ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
-        ESP_LOGI(TAG, "got ip: %s.", ip4addr_ntoa(&event->ip_info.ip));
-        logprint("Signaling wifi connected. Locking.\n");
-    	mutex_lock(wifi_connect_suspend_mutex);
-    	logprint("Signaling wifi connected. Broadcasting.\n");
-		mutex_broadcast_cond(wifi_connect_suspend_cond);
-    	logprint("Signaling wifi connected. Unlocking.\n");
-		mutex_unlock(wifi_connect_suspend_mutex);
-    }
-}
-
-
-/* Initialize Wi-Fi as sta and set scan method */
-static void wifi_scan(void)
-{
-	for(uint8_t l=0;art_wifi[l][0]!='\0';l++){
-		logprint("%s",art_wifi[l]);
-	}
-	for(uint8_t l=0;art_wifi_connecting[l][0]!='\0';l++){
-		logprint("%s",art_wifi_connecting[l]);
-		}
-    tcpip_adapter_init();
-    ESP_ERROR_CHECK(esp_event_loop_create_default());
-
-    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
-    ESP_ERROR_CHECK(esp_wifi_init(&cfg));
-
-    ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
-    ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL));
-
-    wifi_config_t wifi_config = {
-        .sta = {
-            .ssid = DEFAULT_SSID,
-            .password = DEFAULT_PWD,
-            .scan_method = DEFAULT_SCAN_METHOD,
-            .sort_method = DEFAULT_SORT_METHOD,
-            .threshold.rssi = DEFAULT_RSSI,
-            .threshold.authmode = DEFAULT_AUTHMODE,
-        },
-    };
-    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
-    ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
-    ESP_ERROR_CHECK(esp_wifi_start());
-}
-
-int main(int argc, char**argv);
-
-
-#define DO_EXPAND(VAL)  VAL ## 1
-#define EXPAND(VAL)     DO_EXPAND(VAL)
-void app_main()
-{
-	int i; 
-	char **argv, *_argv[] = {
-		"squeezelite-esp32",
-		"-C",
-		"1",
-		"-o",
-		CONFIG_OUTPUT_NAME,
-		"-n",
-		"ESP32",
-		"-r",
-		"OUTPUT_RATES",
-		"-d",
-		"slimproto=" CONFIG_LOGGING_SLIMPROTO,
-		"-d",
-		"stream=" CONFIG_LOGGING_STREAM,
-		"-d",
-		"decode=" CONFIG_LOGGING_DECODE,
-		"-d",
-		"output=" CONFIG_LOGGING_OUTPUT,
-		"-b",
-		"500:2000"
-
-	};
-
-
-	// can't do strtok on FLASH strings
-	argv = malloc(sizeof(_argv));
-	for (i = 0; i < sizeof(_argv)/sizeof(char*); i++) {
-		argv[i] = strdup(_argv[i]);
-	}
-
-
-    // Initialize NVS
-    esp_err_t ret = nvs_flash_init();
-    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
-        ESP_ERROR_CHECK(nvs_flash_erase());
-        ret = nvs_flash_init();
-    }
-    ESP_ERROR_CHECK( ret );
-
-	mutex_create_p(wifi_connect_suspend_mutex);
-	mutex_cond_init(wifi_connect_suspend_cond);
-
-	logprint("Starting WiFi.\n");
-	wifi_scan();
-	logprint("Waiting for WiFi to connect. Locking Mutex.\n");
-	mutex_lock(wifi_connect_suspend_mutex);
-	logprint("Waiting for WiFi to connect. cond_wait.\n");
-	pthread_cond_wait(&wifi_connect_suspend_cond,&wifi_connect_suspend_mutex);
-	logprint("Waiting for WiFi to connect. Unlocking Mutex.\n");
-	mutex_unlock(wifi_connect_suspend_mutex);
-	for(uint8_t l=0;art_wifi[l][0]!='\0';l++){
-		logprint("%s",art_wifi[l]);
-	}
-	for(uint8_t l=0;art_wifi_connected[l][0]!='\0';l++){
-		logprint("%s",art_wifi_connected[l]);
-		}
-	logprint("%s %s:%d Calling main with parameters: " , logtime(), __FUNCTION__, __LINE__);
-
-	for (i = 0; i < sizeof(_argv)/sizeof(char*); i++) {
-		logprint("%s " , _argv[i]);
-	}
-	logprint("\n");
-
-	main(sizeof(_argv)/sizeof(char*), argv);
-}

+ 14 - 10
main/main.c

@@ -374,7 +374,7 @@ int main(int argc, char **argv) {
 		} else {
 			fprintf(stderr, "\nOption error: -%s\n\n", opt);
 			usage(argv[0]);
-			exit(1);
+			local_exit(1);
 		}
 
 		switch (opt[0]) {
@@ -425,7 +425,7 @@ int main(int argc, char **argv) {
 				} else {
 					fprintf(stderr, "\nDebug settings error: -d %s\n\n", optarg);
 					usage(argv[0]);
-					exit(1);
+					local_exit(1);
 				}
 			}
 			break;
@@ -668,10 +668,12 @@ int main(int argc, char **argv) {
 #endif
 		case 't':
 			license();
-			exit(0);
+			local_exit(0);
+			break; // mute compiler warning
 		case '?':
 			usage(argv[0]);
-			exit(0);
+			local_exit(0);
+			break; // mute compiler warning
 		default:
 			fprintf(stderr, "Arg error: %s\n", argv[optind]);
 			break;
@@ -682,7 +684,7 @@ int main(int argc, char **argv) {
 	if (optind < argc) {
 		fprintf(stderr, "\nError: command line argument error\n\n");
 		usage(argv[0]);
-		exit(1);
+		local_exit(1);
 	}
 
 	signal(SIGINT, sighandler);
@@ -748,11 +750,13 @@ int main(int argc, char **argv) {
 #endif
 
 	stream_init(log_stream, stream_buf_size);
-
-#if CONFIG_BTAUDIO
+#ifdef EMBEDDED
+if(strstr(output_device,"BT")!=NULL || strstr(output_device,"bt")!=NULL) {
 	output_init_bt(log_output, output_device, output_buf_size, output_params, rates, rate_delay, idle);
-#elif CONFIG_DACAUDIO
+}
+else if(strstr(output_device,"DAC")!=NULL || strstr(output_device,"dac")!=NULL){
 	output_init_dac(log_output, output_device, output_buf_size, output_params, rates, rate_delay, idle);
+}
 #else
 	if (!strcmp(output_device, "-")) {
 		output_init_stdout(log_output, output_buf_size, output_params, rates, rate_delay);
@@ -793,7 +797,7 @@ int main(int argc, char **argv) {
 
 	if (name && namefile) {
 		fprintf(stderr, "-n and -N option should not be used at same time\n");
-		exit(1);
+		local_exit(1);
 	}
 
 	slimproto(log_slimproto, server, mac, name, namefile, modelname, maxSampleRate);
@@ -837,5 +841,5 @@ int main(int argc, char **argv) {
 	free_ssl_symbols();
 #endif	
 
-	exit(0);
+	local_exit(0);
 }

+ 3 - 3
main/output.c

@@ -352,13 +352,13 @@ void output_init_common(log_level level, const char *device, unsigned output_buf
 	buf_init(outputbuf, output_buf_size);
 	if (!outputbuf->buf) {
 		LOG_ERROR("unable to malloc output buffer");
-		exit(0);
+		local_exit(0);
 	}
 
 	silencebuf = malloc(MAX_SILENCE_FRAMES * BYTES_PER_FRAME);
 	if (!silencebuf) {
 		LOG_ERROR("unable to malloc silence buffer");
-		exit(0);
+		local_exit(0);
 	}
 	memset(silencebuf, 0, MAX_SILENCE_FRAMES * BYTES_PER_FRAME);
 
@@ -389,7 +389,7 @@ void output_init_common(log_level level, const char *device, unsigned output_buf
 	else {
 		if (!test_open(output.device, output.supported_rates, user_rates)) {
 			LOG_ERROR("unable to open output device: %s", output.device);
-			exit(0);
+			local_exit(0);
 		}
 	}
 

+ 3 - 3
main/output_bt.c

@@ -33,7 +33,7 @@ uint8_t * btout;
 #define FRAME_BLOCK MAX_SILENCE_FRAMES
 extern u8_t *silencebuf;
 
-void hal_bluetooth_init(log_level);
+extern void hal_bluetooth_init(const char * options);
 
 static int _write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR,
 								s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr);
@@ -134,11 +134,11 @@ void output_init_bt(log_level level, char *device, unsigned output_buf_size, cha
 	if (!rates[0]) {
 		rates[0] = 44100;
 	}
-	hal_bluetooth_init(loglevel);
+	hal_bluetooth_init(device);
 /*
  * Bluetooth audio source init Start
  */
-	device = CONFIG_OUTPUT_NAME;
+//	device = CONFIG_OUTPUT_NAME;
 	output_init_common(level, device, output_buf_size, rates, idle);
 #ifdef USE_BT_RING_BUFFER
 	LOG_DEBUG("Allocating local BT transfer buffer of %u bytes.",bt_buffer_size);

+ 41 - 29
main/output_dac.c

@@ -1,4 +1,3 @@
-
 #include "squeezelite.h"
 #include "driver/i2s.h"
 #include "perf_trace.h"
@@ -52,7 +51,7 @@ extern struct buffer *outputbuf;
 extern u8_t *silencebuf;
 static struct buffer _dac_buffer_structure;
 struct buffer *dacbuffer=&_dac_buffer_structure;
-
+u8_t *tfr_buffer;
 static i2s_config_t i2s_config;
 #if REPACK && BYTES_PER_FRAMES == 4
 #error "REPACK is not compatible with BYTES_PER_FRAME=4"
@@ -120,6 +119,10 @@ void output_init_dac(log_level level, char *device, unsigned output_buf_size, ch
 		rates[0] = 44100;
 	}
 	running=true;
+
+	// todo: move this to a hardware abstraction layer
+	//hal_dac_init(device);
+
 	// get common output configuration details
 	output_init_common(level, device, output_buf_size, rates, idle);
 
@@ -153,10 +156,11 @@ void output_init_dac(log_level level, char *device, unsigned output_buf_size, ch
 
 	dac_buffer_size = 10*FRAME_BLOCK*get_bytes_per_frame(output.format);
 	LOG_DEBUG("Allocating local DAC transfer buffer of %u bytes.",dac_buffer_size);
+
 	buf_init(dacbuffer,dac_buffer_size );
 	if (!dacbuffer->buf) {
 		LOG_ERROR("unable to malloc i2s buffer");
-		exit(0);
+		local_exit(0);
 	}
 
 PTHREAD_SET_NAME("output_dac");
@@ -167,7 +171,7 @@ PTHREAD_SET_NAME("output_dac");
 #ifdef PTHREAD_STACK_MIN
 	pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN + OUTPUT_THREAD_STACK_SIZE);
 #endif
-	pthread_create(&thread, &attr, output_thread, NULL);
+	pthread_create(&thread, &attr, output_thread_dac, NULL);
 	pthread_attr_destroy(&attr);
 #endif
 #if WIN
@@ -249,7 +253,7 @@ static int _dac_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32
 /****************************************************************************************
  * Main output thread
  */
-static void *output_thread() {
+static void *output_thread_dac() {
 	frames_t frames=0;
 	frames_t available_frames_space=0;
 	size_t bytes_to_send_i2s=0, // Contiguous buffer which can be addressed
@@ -280,27 +284,22 @@ static void *output_thread() {
 			continue;
 		}
 		LOG_SDEBUG("Current buffer free: %10d, cont read: %10d",_buf_space(dacbuffer),_buf_cont_read(dacbuffer));
-		available_frames_space = BYTES_TO_FRAME(min(_buf_space(dacbuffer), _buf_cont_write(dacbuffer)));
+		available_frames_space = min(BYTES_TO_FRAME(min(_buf_space(dacbuffer), _buf_cont_write(dacbuffer))),FRAME_BLOCK);
 		frames = _output_frames( available_frames_space ); // Keep the transfer buffer full
 		UNLOCK;
 		LOG_SDEBUG("Current buffer free: %10d, cont read: %10d",_buf_space(dacbuffer),_buf_cont_read(dacbuffer));
 		SET_MIN_MAX( TIME_MEASUREMENT_GET(timer_start),buffering);
 		SET_MIN_MAX( available_frames_space,req);
 		SET_MIN_MAX(frames,rec);
-		if(frames>0){
-				//LOG_DEBUG("Frames available : %u.",frames);
-		}
-		else
-		{
-			//LOG_DEBUG("No frame available");
-			usleep(10000);
-		}
 
-		SET_MIN_MAX(_buf_used(dacbuffer),loci2sbuf);
+
+		SET_MIN_MAX_SIZED(_buf_used(dacbuffer),loci2sbuf,dacbuffer->size);
 		bytes_to_send_i2s = _buf_cont_read(dacbuffer);
 		SET_MIN_MAX(bytes_to_send_i2s,i2savailable);
-		if (bytes_to_send_i2s>0  )
+		int pass=0;
+		while (bytes_to_send_i2s>0 && pass++ < 1 )
 		{
+			// now pass twice
 			TIME_MEASUREMENT_START(timer_start);
 			if(!isI2SStarted)
 			{
@@ -332,11 +331,19 @@ static void *output_thread() {
 			output.updated = gettime_ms();
 			output.frames_played_dmp = output.frames_played;
 			SET_MIN_MAX( TIME_MEASUREMENT_GET(timer_start),i2s_time);
-
+			bytes_to_send_i2s = _buf_cont_read(dacbuffer);
 		}
+//		if(frames>0){
+//				//LOG_DEBUG("Frames available : %u.",frames);
+//		}
+//		else
+//		{
+//			//LOG_DEBUG("No frame available");
+//			usleep(10000);
+//		}
 		SET_MIN_MAX(bytes_to_send_i2s-i2s_bytes_written,over);
-		SET_MIN_MAX(_buf_used(outputbuf),o);
-		SET_MIN_MAX(_buf_used(streambuf),s);
+		SET_MIN_MAX_SIZED(_buf_used(outputbuf),o,outputbuf->size);
+		SET_MIN_MAX_SIZED(_buf_used(streambuf),s,streambuf->size);
 
 		/*
 		 * Statistics reporting
@@ -352,24 +359,29 @@ static void *output_thread() {
 		TIMED_SECTION_START_MS(STATS_PERIOD_MS);
 
 		LOG_INFO( "count:%d, current sample rate: %d, bytes per frame: %d, avg cycle duration (ms): %d",count,output.current_sample_rate, out_bytes_per_frame,STATS_PERIOD_MS/count);
-		LOG_INFO( "              ----------+----------+-----------+  +----------+----------+----------------+");
-		LOG_INFO( "                    max |      min |    current|  |      max |      min |        current |");
-		LOG_INFO( "                   (ms) |     (ms) |       (ms)|  |  (bytes) |  (bytes) |        (bytes) |");
-		LOG_INFO( "              ----------+----------+-----------+  +----------+----------+----------------+");
+		LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD1);
+		LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD2);
+		LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD3);
+		LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD4);
 		LOG_INFO(LINE_MIN_MAX_FORMAT_STREAM, LINE_MIN_MAX_STREAM("stream",s));
 		LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("output",o));
-		LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("i2swrite",i2savailable));
 		LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("local free",loci2sbuf));
+		LOG_INFO(LINE_MIN_MAX_FORMAT_FOOTER);
+		LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("i2swrite",i2savailable));
 		LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("requested",req));
 		LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("received",rec));
 		LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("overflow",over));
-		LOG_INFO("              ----------+----------+-----------+  +----------+----------+----------------+");
+		LOG_INFO(LINE_MIN_MAX_FORMAT_FOOTER);
 		LOG_INFO("");
-		LOG_INFO("              max (us)  | min (us) |current(us)|  ");
-		LOG_INFO("              ----------+----------+-----------+  ");
+		LOG_INFO("              ----------+----------+-----------+-----------+  ");
+		LOG_INFO("              max (us)  | min (us) |   avg(us) |  count    |  ");
+		LOG_INFO("              ----------+----------+-----------+-----------+  ");
 		LOG_INFO(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("Buffering(us)",buffering));
 		LOG_INFO(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("i2s tfr(us)",i2s_time));
-		LOG_INFO("              ----------+----------+-----------+  ");
+		LOG_INFO("              ----------+----------+-----------+-----------+");
+
+
+
 		RESET_ALL_MIN_MAX;
 		count=0;
 		TIMED_SECTION_END;
@@ -377,7 +389,7 @@ static void *output_thread() {
 		 * End Statistics reporting
 		 */
 //		wait_for_frames(BYTES_TO_FRAME(i2s_bytes_written),75);
-
+	}
 	return 0;
 }
 

+ 0 - 14
main/perf_trace.c

@@ -1,14 +0,0 @@
-#include "squeezelite.h"
-#include "perf_trace.h"
-/*************************************
- * Some performance analysis bits
- */
-
-//perf_stats * stats[]={
-//		{ .min=LONG_MAX, .max=LONG_MIN, .current=0, .name="output", .fmt=BUFFER_TYPE },
-//		{ .min=LONG_MAX, .max=LONG_MIN, .current=0, .name="stream", .fmt=BUFFER_TYPE },
-//		{ .min=LONG_MAX, .max=LONG_MIN, .current=0, .name="i2sbuffer", .fmt=BUFFER_TYPE },
-//		{ .min=LONG_MAX, .max=LONG_MIN, .current=0, .name="i2s_write", .fmt=DURATION_TYPE },
-//		{ .min=LONG_MAX, .max=LONG_MIN, .current=0, .name="output_fill", .fmt=DURATION_TYPE }
-//};
-

+ 10 - 10
main/squeezelite.h

@@ -342,9 +342,14 @@ typedef int64_t   s64_t;
 #define mutex_cond_init(c) pthread_cond_init(&c, NULL)
 #define thread_cond_type pthread_cond_t
 #define thread_type pthread_t
-
+#endif
+#ifdef EMBEDDED
+#define local_exit(r) {static int ret=r; pthread_exit(&ret);}
+#else
+#define local_exit(r) exit(r)
 #endif
 
+
 #if WIN
 
 #include <winsock2.h>
@@ -658,10 +663,8 @@ typedef enum { OUTPUT_OFF = -1, OUTPUT_STOPPED = 0, OUTPUT_BUFFER, OUTPUT_RUNNIN
 #if DSD
 typedef enum { PCM, DOP, DSD_U8, DSD_U16_LE, DSD_U32_LE, DSD_U16_BE, DSD_U32_BE, DOP_S24_LE, DOP_S24_3LE } dsd_format;
 typedef enum { S32_LE, S24_LE, S24_3LE, S16_LE, U8, U16_LE, U16_BE, U32_LE, U32_BE } output_format;
-#elif CONFIG_DACAUDIO
-typedef enum { S32_LE, S24_LE, S24_3LE, S16_LE, S24_BE, S24_3BE, S16_BE, S8_BE } output_format;
 #else
-typedef enum { S32_LE, S24_LE, S24_3LE, S16_LE } output_format;
+typedef enum { S32_LE, S24_LE, S24_3LE, S16_LE, S24_BE, S24_3BE, S16_BE, S8_BE } output_format;
 #endif
 extern uint8_t get_bytes_per_frame(output_format fmt);
 
@@ -757,23 +760,20 @@ void _pa_open(void);
 #endif
 
 // output_dac.c
-#if CONFIG_DACAUDIO
+
 void set_volume_dac(unsigned left, unsigned right);
 bool test_open(const char *device, unsigned rates[], bool userdef_rates);
 void output_init_dac(log_level level, char *device, unsigned output_buf_size, char *params, unsigned rates[], unsigned rate_delay, unsigned idle);
 void output_close_dac(void);
-void hal_bluetooth_init(log_level loglevel);
-#endif
+void hal_dac_init(const char * options);
 
 //output_bt.c
-#if  CONFIG_BTAUDIO
 void set_volume_bt(unsigned left, unsigned right);
 bool test_open(const char *device, unsigned rates[], bool userdef_rates);
 void output_init_bt(log_level level, char *device, unsigned output_buf_size, char *params, unsigned rates[], unsigned rate_delay, unsigned idle);
 void output_close_bt(void);
-void hal_bluetooth_init(log_level loglevel);
+extern void hal_bluetooth_init(const char * options);
 void output_bt_check_buffer();
-#endif
 
 
 // output_stdout.c

+ 1 - 1
main/stream.c

@@ -373,7 +373,7 @@ void stream_init(log_level level, unsigned stream_buf_size) {
 	buf_init(streambuf, stream_buf_size);
 	if (streambuf->buf == NULL) {
 		LOG_ERROR("unable to malloc buffer");
-		exit(0);
+		local_exit(0);
 	}
 	
 #if USE_SSL

+ 21 - 2
main/utils.c

@@ -578,7 +578,6 @@ uint8_t get_bytes_per_frame(output_format fmt)
 		case S16_LE:
 			bpf=2*2;
 			break;
-#if CONFIG_DACAUDIO
 		case S24_BE:
 			bpf=3*2;
 			break;
@@ -591,7 +590,6 @@ uint8_t get_bytes_per_frame(output_format fmt)
 		case S8_BE:
 			bpf=2*2;
 			break;
-#endif
 #if DSD
 		case U8:
 			bpf=1*2;
@@ -623,3 +621,24 @@ void wait_for_frames(size_t frames, uint8_t pct)
 {
 	usleep((1000* frames/output.current_sample_rate*pct/100) );
 }
+char * get_output_state_desc(output_state state){
+	switch (state) {
+	case OUTPUT_OFF:
+		return STR(OUTPUT_OFF);
+	case OUTPUT_STOPPED:
+		return STR(OUTPUT_STOPPED);
+	case OUTPUT_BUFFER:
+		return STR(OUTPUT_BUFFER);
+	case OUTPUT_RUNNING:
+		return STR(OUTPUT_RUNNING);
+	case OUTPUT_PAUSE_FRAMES:
+		return STR(OUTPUT_PAUSE_FRAMES);
+	case OUTPUT_SKIP_FRAMES:
+		return STR(OUTPUT_SKIP_FRAMES);
+	case OUTPUT_START_AT:
+		return STR(OUTPUT_START_AT);
+	default:
+		return "OUTPUT_UNKNOWN_STATE";
+	}
+	return "";
+}

+ 3 - 1
partitions.csv

@@ -2,4 +2,6 @@
 # Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild
 nvs,      data, nvs,     0x9000,  0x6000,
 phy_init, data, phy,     0xf000,  0x1000,
-factory,  app,  factory, 0x10000, 2000000,
+factory,  app,  factory, 0x10000, 2M,
+storage,  data, fat,     ,        819200, 
+coredump, data, coredump,,        64K

+ 776 - 0
sdkconfig

@@ -0,0 +1,776 @@
+#
+# Automatically generated file. DO NOT EDIT.
+# Espressif IoT Development Framework (ESP-IDF) Project Configuration
+#
+CONFIG_IDF_TARGET_ESP32=y
+CONFIG_IDF_TARGET="esp32"
+
+#
+# SDK tool configuration
+#
+CONFIG_SDK_TOOLPREFIX="xtensa-esp32-elf-"
+CONFIG_SDK_PYTHON="python"
+CONFIG_SDK_MAKE_WARN_UNDEFINED_VARIABLES=y
+CONFIG_APP_COMPILE_TIME_DATE=y
+# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set
+# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set
+# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set
+# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set
+CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y
+# CONFIG_BOOTLOADER_LOG_LEVEL_INFO is not set
+# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set
+# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set
+CONFIG_BOOTLOADER_LOG_LEVEL=2
+CONFIG_BOOTLOADER_SPI_WP_PIN=7
+CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y
+# CONFIG_BOOTLOADER_FACTORY_RESET is not set
+# CONFIG_BOOTLOADER_APP_TEST is not set
+CONFIG_BOOTLOADER_WDT_ENABLE=y
+# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set
+CONFIG_BOOTLOADER_WDT_TIME_MS=9000
+# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set
+# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set
+# CONFIG_SECURE_BOOT_ENABLED is not set
+# CONFIG_SECURE_FLASH_ENC_ENABLED is not set
+CONFIG_ESPTOOLPY_PORT="COM4"
+# CONFIG_ESPTOOLPY_BAUD_115200B is not set
+# CONFIG_ESPTOOLPY_BAUD_230400B is not set
+# CONFIG_ESPTOOLPY_BAUD_921600B is not set
+CONFIG_ESPTOOLPY_BAUD_2MB=y
+# CONFIG_ESPTOOLPY_BAUD_OTHER is not set
+CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200
+CONFIG_ESPTOOLPY_BAUD=2000000
+CONFIG_ESPTOOLPY_COMPRESSED=y
+CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
+# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set
+# CONFIG_ESPTOOLPY_FLASHMODE_DIO is not set
+# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set
+CONFIG_ESPTOOLPY_FLASHMODE="dio"
+CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
+# CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set
+# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set
+# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set
+CONFIG_ESPTOOLPY_FLASHFREQ="80m"
+# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set
+# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set
+CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
+# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set
+# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set
+CONFIG_ESPTOOLPY_FLASHSIZE="4MB"
+CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y
+CONFIG_ESPTOOLPY_BEFORE_RESET=y
+# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set
+CONFIG_ESPTOOLPY_BEFORE="default_reset"
+CONFIG_ESPTOOLPY_AFTER_RESET=y
+# CONFIG_ESPTOOLPY_AFTER_NORESET is not set
+CONFIG_ESPTOOLPY_AFTER="hard_reset"
+# CONFIG_ESPTOOLPY_MONITOR_BAUD_9600B is not set
+# CONFIG_ESPTOOLPY_MONITOR_BAUD_57600B is not set
+CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y
+# CONFIG_ESPTOOLPY_MONITOR_BAUD_230400B is not set
+# CONFIG_ESPTOOLPY_MONITOR_BAUD_921600B is not set
+# CONFIG_ESPTOOLPY_MONITOR_BAUD_2MB is not set
+# CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER is not set
+CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER_VAL=115200
+CONFIG_ESPTOOLPY_MONITOR_BAUD=115200
+CONFIG_LOGGING_SLIMPROTO="debug"
+CONFIG_LOGGING_STREAM="debug"
+CONFIG_LOGGING_DECODE="debug"
+CONFIG_LOGGING_OUTPUT="debug"
+CONFIG_WIFI_SSID="Abyssin"
+CONFIG_WIFI_PASSWORD="san92121diego"
+CONFIG_WIFI_FAST_SCAN=y
+# CONFIG_WIFI_ALL_CHANNEL_SCAN is not set
+CONFIG_WIFI_CONNECT_AP_BY_SIGNAL=y
+# CONFIG_WIFI_CONNECT_AP_BY_SECURITY is not set
+CONFIG_FAST_SCAN_THRESHOLD=y
+CONFIG_FAST_SCAN_MINIMUM_SIGNAL=-127
+CONFIG_EXAMPLE_OPEN=y
+# CONFIG_EXAMPLE_WEP is not set
+# CONFIG_EXAMPLE_WPA is not set
+# CONFIG_EXAMPLE_WPA2 is not set
+CONFIG_INCLUDE_FLAC=y
+CONFIG_INCLUDE_FAAD=y
+CONFIG_INCLUDE_VORBIS=y
+CONFIG_INCLUDE_ALAC=y
+# CONFIG_DACAUDIO is not set
+CONFIG_BTAUDIO=y
+CONFIG_OUTPUT_NAME=""
+CONFIG_OUTPUT_RATES="48000,44100"
+CONFIG_I2S_NUM=0
+CONFIG_I2S_BCK_IO=26
+CONFIG_I2S_WS_IO=25
+CONFIG_I2S_DO_IO=22
+# CONFIG_I2S_BITS_PER_CHANNEL_24 is not set
+CONFIG_I2S_BITS_PER_CHANNEL_16=y
+# CONFIG_I2S_BITS_PER_CHANNEL_8 is not set
+CONFIG_I2S_BITS_PER_CHANNEL=16
+CONFIG_A2DP_SINK_NAME="SMSL BT4.2"
+CONFIG_A2DP_DEV_NAME="Squeezelite"
+CONFIG_A2DP_CONTROL_DELAY_MS=500
+CONFIG_A2DP_CONNECT_TIMEOUT_MS=1000
+CONFIG_A2DP_DISCONNECT_MS=10000
+# CONFIG_PARTITION_TABLE_SINGLE_APP is not set
+# CONFIG_PARTITION_TABLE_TWO_OTA is not set
+CONFIG_PARTITION_TABLE_CUSTOM=y
+CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
+CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
+CONFIG_PARTITION_TABLE_OFFSET=0x8000
+CONFIG_PARTITION_TABLE_MD5=y
+# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set
+CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y
+CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y
+# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set
+# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set
+# CONFIG_COMPILER_CXX_EXCEPTIONS is not set
+CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y
+# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set
+# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set
+# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set
+# CONFIG_COMPILER_STACK_CHECK is not set
+# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set
+# CONFIG_COMPILER_DISABLE_GCC8_WARNINGS is not set
+# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set
+CONFIG_ESP32_APPTRACE_DEST_NONE=y
+# CONFIG_ESP32_APPTRACE_ENABLE is not set
+CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y
+CONFIG_BT_ENABLED=y
+# CONFIG_BTDM_CTRL_MODE_BLE_ONLY is not set
+CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=y
+# CONFIG_BTDM_CTRL_MODE_BTDM is not set
+CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN=2
+CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN=0
+# CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_HCI is not set
+CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_PCM=y
+CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=1
+CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=0
+CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=2
+CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0
+CONFIG_BTDM_CTRL_PINNED_TO_CORE_0=y
+# CONFIG_BTDM_CTRL_PINNED_TO_CORE_1 is not set
+CONFIG_BTDM_CTRL_PINNED_TO_CORE=0
+CONFIG_BTDM_CTRL_HCI_MODE_VHCI=y
+# CONFIG_BTDM_CTRL_HCI_MODE_UART_H4 is not set
+CONFIG_BTDM_MODEM_SLEEP=y
+CONFIG_BTDM_MODEM_SLEEP_MODE_ORIG=y
+# CONFIG_BTDM_MODEM_SLEEP_MODE_EVED is not set
+CONFIG_BTDM_LPCLK_SEL_MAIN_XTAL=y
+CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1
+CONFIG_BT_BLUEDROID_ENABLED=y
+CONFIG_BT_BLUEDROID_PINNED_TO_CORE_0=y
+# CONFIG_BT_BLUEDROID_PINNED_TO_CORE_1 is not set
+CONFIG_BT_BLUEDROID_PINNED_TO_CORE=0
+CONFIG_BT_BTC_TASK_STACK_SIZE=3072
+CONFIG_BT_BTU_TASK_STACK_SIZE=4096
+# CONFIG_BT_BLUEDROID_MEM_DEBUG is not set
+CONFIG_BT_CLASSIC_ENABLED=y
+CONFIG_BT_A2DP_ENABLE=y
+CONFIG_BT_A2DP_SINK_TASK_STACK_SIZE=2048
+CONFIG_BT_A2DP_SOURCE_TASK_STACK_SIZE=2048
+# CONFIG_BT_SPP_ENABLED is not set
+# CONFIG_BT_HFP_ENABLE is not set
+CONFIG_BT_SSP_ENABLED=y
+CONFIG_BT_STACK_NO_LOG=y
+CONFIG_BT_ACL_CONNECTIONS=4
+CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST=y
+CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY=y
+# CONFIG_BT_BLE_HOST_QUEUE_CONG_CHECK is not set
+CONFIG_BT_SMP_ENABLE=y
+CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30
+CONFIG_BT_RESERVE_DRAM=0xdb5c
+# CONFIG_ADC_FORCE_XPD_FSM is not set
+CONFIG_ADC_DISABLE_DAC=y
+# CONFIG_SPI_MASTER_IN_IRAM is not set
+CONFIG_SPI_MASTER_ISR_IN_IRAM=y
+# CONFIG_SPI_SLAVE_IN_IRAM is not set
+CONFIG_SPI_SLAVE_ISR_IN_IRAM=y
+# CONFIG_EFUSE_CUSTOM_TABLE is not set
+# CONFIG_EFUSE_VIRTUAL is not set
+# CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set
+CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y
+# CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set
+CONFIG_EFUSE_MAX_BLK_LEN=192
+# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set
+# CONFIG_ESP32_DEFAULT_CPU_FREQ_160 is not set
+CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y
+CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240
+CONFIG_ESP32_SPIRAM_SUPPORT=y
+CONFIG_SPIRAM_BOOT_INIT=y
+# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set
+# CONFIG_SPIRAM_USE_MEMMAP is not set
+# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set
+CONFIG_SPIRAM_USE_MALLOC=y
+CONFIG_SPIRAM_TYPE_AUTO=y
+# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set
+# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set
+CONFIG_SPIRAM_SIZE=-1
+CONFIG_SPIRAM_SPEED_40M=y
+# CONFIG_SPIRAM_SPEED_80M is not set
+CONFIG_SPIRAM_MEMTEST=y
+CONFIG_SPIRAM_CACHE_WORKAROUND=y
+CONFIG_SPIRAM_BANKSWITCH_ENABLE=y
+CONFIG_SPIRAM_BANKSWITCH_RESERVE=8
+CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=2048
+# CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP is not set
+CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768
+# CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY is not set
+# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set
+CONFIG_D0WD_PSRAM_CLK_IO=17
+CONFIG_D0WD_PSRAM_CS_IO=16
+CONFIG_D2WD_PSRAM_CLK_IO=9
+CONFIG_D2WD_PSRAM_CS_IO=10
+CONFIG_PICO_PSRAM_CS_IO=10
+# CONFIG_ESP32_MEMMAP_TRACEMEM is not set
+# CONFIG_ESP32_MEMMAP_TRACEMEM_TWOBANKS is not set
+# CONFIG_ESP32_TRAX is not set
+CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0
+# CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set
+CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y
+CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4
+# CONFIG_ESP32_ULP_COPROC_ENABLED is not set
+CONFIG_ESP32_ULP_COPROC_RESERVE_MEM=0
+# CONFIG_ESP32_PANIC_PRINT_HALT is not set
+CONFIG_ESP32_PANIC_PRINT_REBOOT=y
+# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set
+# CONFIG_ESP32_PANIC_GDBSTUB is not set
+CONFIG_ESP32_DEBUG_OCDAWARE=y
+CONFIG_ESP32_DEBUG_STUBS_ENABLE=y
+CONFIG_ESP32_BROWNOUT_DET=y
+CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y
+# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_1 is not set
+# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_2 is not set
+# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_3 is not set
+# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_4 is not set
+# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_5 is not set
+# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_6 is not set
+# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set
+CONFIG_ESP32_BROWNOUT_DET_LVL=0
+CONFIG_ESP32_REDUCE_PHY_TX_POWER=y
+CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y
+# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set
+# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set
+# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set
+CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y
+# CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS is not set
+# CONFIG_ESP32_RTC_CLK_SRC_EXT_OSC is not set
+# CONFIG_ESP32_RTC_CLK_SRC_INT_8MD256 is not set
+CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024
+CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000
+CONFIG_ESP32_XTAL_FREQ_40=y
+# CONFIG_ESP32_XTAL_FREQ_26 is not set
+# CONFIG_ESP32_XTAL_FREQ_AUTO is not set
+CONFIG_ESP32_XTAL_FREQ=40
+# CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set
+# CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set
+# CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set
+# CONFIG_PM_ENABLE is not set
+CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y
+CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y
+CONFIG_ADC_CAL_LUT_ENABLE=y
+# CONFIG_ESP_TIMER_PROFILING is not set
+CONFIG_ESP_ERR_TO_NAME_LOOKUP=y
+CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32
+CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304
+CONFIG_ESP_MAIN_TASK_STACK_SIZE=10240
+CONFIG_ESP_IPC_TASK_STACK_SIZE=1024
+CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584
+CONFIG_ESP_CONSOLE_UART_DEFAULT=y
+# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set
+# CONFIG_ESP_CONSOLE_UART_NONE is not set
+CONFIG_ESP_CONSOLE_UART_NUM=0
+CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200
+CONFIG_ESP_INT_WDT=y
+CONFIG_ESP_INT_WDT_TIMEOUT_MS=800
+CONFIG_ESP_INT_WDT_CHECK_CPU1=y
+CONFIG_ESP_TASK_WDT=y
+# CONFIG_ESP_TASK_WDT_PANIC is not set
+CONFIG_ESP_TASK_WDT_TIMEOUT_S=5
+CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y
+CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y
+# CONFIG_ESP_EVENT_LOOP_PROFILING is not set
+CONFIG_ESP_EVENT_POST_FROM_ISR=y
+CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y
+CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y
+# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set
+CONFIG_HTTPD_MAX_REQ_HDR_LEN=512
+CONFIG_HTTPD_MAX_URI_LEN=512
+CONFIG_HTTPD_ERR_RESP_NO_DELAY=y
+CONFIG_HTTPD_PURGE_BUF_LEN=32
+# CONFIG_HTTPD_LOG_PURGE_DATA is not set
+# CONFIG_OTA_ALLOW_HTTP is not set
+CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y
+# CONFIG_ESP32_WIFI_SW_COEXIST_PREFERENCE_WIFI is not set
+CONFIG_ESP32_WIFI_SW_COEXIST_PREFERENCE_BT=y
+# CONFIG_ESP32_WIFI_SW_COEXIST_PREFERENCE_BALANCE is not set
+CONFIG_ESP32_WIFI_SW_COEXIST_PREFERENCE_VALUE=1
+CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10
+CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=64
+CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y
+CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=0
+CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM=16
+# CONFIG_ESP32_WIFI_CSI_ENABLED is not set
+# CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED is not set
+# CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED is not set
+CONFIG_ESP32_WIFI_NVS_ENABLED=y
+CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y
+# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set
+CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752
+CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32
+# CONFIG_ESP32_WIFI_DEBUG_LOG_ENABLE is not set
+CONFIG_ESP32_WIFI_IRAM_OPT=y
+CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y
+# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set
+CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20
+CONFIG_ESP32_PHY_MAX_TX_POWER=20
+# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set
+CONFIG_ESP32_ENABLE_COREDUMP_TO_UART=y
+# CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE is not set
+CONFIG_ESP32_ENABLE_COREDUMP=y
+CONFIG_ESP32_CORE_DUMP_MAX_TASKS_NUM=64
+CONFIG_ESP32_CORE_DUMP_UART_DELAY=0
+CONFIG_ETH_DMA_RX_BUF_NUM=10
+CONFIG_ETH_DMA_TX_BUF_NUM=10
+CONFIG_ETH_EMAC_L2_TO_L3_RX_BUF_MODE=y
+CONFIG_ETH_CHECK_LINK_STATUS_PERIOD_MS=2000
+CONFIG_ETH_EMAC_TASK_PRIORITY=20
+CONFIG_ETH_EMAC_TASK_STACK_SIZE=3072
+# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set
+CONFIG_FATFS_CODEPAGE_437=y
+# CONFIG_FATFS_CODEPAGE_720 is not set
+# CONFIG_FATFS_CODEPAGE_737 is not set
+# CONFIG_FATFS_CODEPAGE_771 is not set
+# CONFIG_FATFS_CODEPAGE_775 is not set
+# CONFIG_FATFS_CODEPAGE_850 is not set
+# CONFIG_FATFS_CODEPAGE_852 is not set
+# CONFIG_FATFS_CODEPAGE_855 is not set
+# CONFIG_FATFS_CODEPAGE_857 is not set
+# CONFIG_FATFS_CODEPAGE_860 is not set
+# CONFIG_FATFS_CODEPAGE_861 is not set
+# CONFIG_FATFS_CODEPAGE_862 is not set
+# CONFIG_FATFS_CODEPAGE_863 is not set
+# CONFIG_FATFS_CODEPAGE_864 is not set
+# CONFIG_FATFS_CODEPAGE_865 is not set
+# CONFIG_FATFS_CODEPAGE_866 is not set
+# CONFIG_FATFS_CODEPAGE_869 is not set
+# CONFIG_FATFS_CODEPAGE_932 is not set
+# CONFIG_FATFS_CODEPAGE_936 is not set
+# CONFIG_FATFS_CODEPAGE_949 is not set
+# CONFIG_FATFS_CODEPAGE_950 is not set
+CONFIG_FATFS_CODEPAGE=437
+CONFIG_FATFS_LFN_NONE=y
+# CONFIG_FATFS_LFN_HEAP is not set
+# CONFIG_FATFS_LFN_STACK is not set
+CONFIG_FATFS_FS_LOCK=0
+CONFIG_FATFS_TIMEOUT_MS=10000
+CONFIG_FATFS_PER_FILE_CACHE=y
+CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y
+CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=150
+CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200
+CONFIG_FMB_QUEUE_LENGTH=20
+CONFIG_FMB_SERIAL_TASK_STACK_SIZE=2048
+CONFIG_FMB_SERIAL_BUF_SIZE=256
+CONFIG_FMB_SERIAL_TASK_PRIO=10
+# CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT is not set
+CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20
+CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20
+CONFIG_FMB_CONTROLLER_STACK_SIZE=4096
+CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20
+CONFIG_FMB_TIMER_PORT_ENABLED=y
+CONFIG_FMB_TIMER_GROUP=0
+CONFIG_FMB_TIMER_INDEX=0
+# CONFIG_FREERTOS_UNICORE is not set
+CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF
+CONFIG_FREERTOS_CORETIMER_0=y
+# CONFIG_FREERTOS_CORETIMER_1 is not set
+CONFIG_FREERTOS_HZ=100
+CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y
+# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set
+# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set
+CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y
+# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set
+CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y
+CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1
+CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y
+# CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set
+# CONFIG_FREERTOS_ASSERT_DISABLE is not set
+CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536
+CONFIG_FREERTOS_ISR_STACKSIZE=1536
+# CONFIG_FREERTOS_LEGACY_HOOKS is not set
+CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16
+CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y
+# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set
+CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1
+CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048
+CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10
+CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0
+# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set
+# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set
+# CONFIG_FREERTOS_DEBUG_INTERNALS is not set
+CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y
+# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set
+CONFIG_HEAP_POISONING_DISABLED=y
+# CONFIG_HEAP_POISONING_LIGHT is not set
+# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set
+CONFIG_HEAP_TRACING_OFF=y
+# CONFIG_HEAP_TRACING_STANDALONE is not set
+# CONFIG_HEAP_TRACING_TOHOST is not set
+# CONFIG_HEAP_TRACING is not set
+CONFIG_LIBSODIUM_USE_MBEDTLS_SHA=y
+# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set
+# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set
+# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set
+CONFIG_LOG_DEFAULT_LEVEL_INFO=y
+# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set
+# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set
+CONFIG_LOG_DEFAULT_LEVEL=3
+CONFIG_LOG_COLORS=y
+# CONFIG_LWIP_L2_TO_L3_COPY is not set
+# CONFIG_LWIP_IRAM_OPTIMIZATION is not set
+CONFIG_LWIP_MAX_SOCKETS=10
+# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set
+CONFIG_LWIP_SO_REUSE=y
+CONFIG_LWIP_SO_REUSE_RXTOALL=y
+# CONFIG_LWIP_SO_RCVBUF is not set
+CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1
+# CONFIG_LWIP_IP_FRAG is not set
+# CONFIG_LWIP_IP_REASSEMBLY is not set
+# CONFIG_LWIP_STATS is not set
+# CONFIG_LWIP_ETHARP_TRUST_IP_MAC is not set
+CONFIG_LWIP_ESP_GRATUITOUS_ARP=y
+CONFIG_LWIP_GARP_TMR_INTERVAL=60
+CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32
+CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y
+# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set
+CONFIG_LWIP_DHCPS_LEASE_UNIT=60
+CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8
+# CONFIG_LWIP_AUTOIP is not set
+CONFIG_LWIP_NETIF_LOOPBACK=y
+CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8
+CONFIG_LWIP_MAX_ACTIVE_TCP=16
+CONFIG_LWIP_MAX_LISTENING_TCP=16
+CONFIG_LWIP_TCP_MAXRTX=12
+CONFIG_LWIP_TCP_SYNMAXRTX=6
+CONFIG_LWIP_TCP_MSS=1440
+CONFIG_LWIP_TCP_MSL=60000
+CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744
+CONFIG_LWIP_TCP_WND_DEFAULT=5744
+CONFIG_LWIP_TCP_RECVMBOX_SIZE=6
+CONFIG_LWIP_TCP_QUEUE_OOSEQ=y
+# CONFIG_LWIP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set
+CONFIG_LWIP_TCP_OVERSIZE_MSS=y
+# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set
+# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set
+CONFIG_LWIP_MAX_UDP_PCBS=16
+CONFIG_LWIP_UDP_RECVMBOX_SIZE=6
+CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072
+CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y
+# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set
+# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set
+CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF
+# CONFIG_LWIP_PPP_SUPPORT is not set
+# CONFIG_LWIP_MULTICAST_PING is not set
+# CONFIG_LWIP_BROADCAST_PING is not set
+CONFIG_LWIP_MAX_RAW_PCBS=16
+CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y
+# CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC is not set
+# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set
+# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set
+CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=16384
+# CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN is not set
+# CONFIG_MBEDTLS_DEBUG is not set
+CONFIG_MBEDTLS_HARDWARE_AES=y
+# CONFIG_MBEDTLS_HARDWARE_MPI is not set
+# CONFIG_MBEDTLS_HARDWARE_SHA is not set
+CONFIG_MBEDTLS_HAVE_TIME=y
+# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set
+CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y
+# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set
+# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set
+# CONFIG_MBEDTLS_TLS_DISABLED is not set
+CONFIG_MBEDTLS_TLS_SERVER=y
+CONFIG_MBEDTLS_TLS_CLIENT=y
+CONFIG_MBEDTLS_TLS_ENABLED=y
+# CONFIG_MBEDTLS_PSK_MODES is not set
+CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y
+CONFIG_MBEDTLS_SSL_RENEGOTIATION=y
+# CONFIG_MBEDTLS_SSL_PROTO_SSL3 is not set
+CONFIG_MBEDTLS_SSL_PROTO_TLS1=y
+CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y
+CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y
+# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set
+CONFIG_MBEDTLS_SSL_ALPN=y
+CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y
+CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y
+CONFIG_MBEDTLS_AES_C=y
+# CONFIG_MBEDTLS_CAMELLIA_C is not set
+# CONFIG_MBEDTLS_DES_C is not set
+CONFIG_MBEDTLS_RC4_DISABLED=y
+# CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT is not set
+# CONFIG_MBEDTLS_RC4_ENABLED is not set
+# CONFIG_MBEDTLS_BLOWFISH_C is not set
+# CONFIG_MBEDTLS_XTEA_C is not set
+CONFIG_MBEDTLS_CCM_C=y
+CONFIG_MBEDTLS_GCM_C=y
+# CONFIG_MBEDTLS_RIPEMD160_C is not set
+CONFIG_MBEDTLS_PEM_PARSE_C=y
+CONFIG_MBEDTLS_PEM_WRITE_C=y
+CONFIG_MBEDTLS_X509_CRL_PARSE_C=y
+CONFIG_MBEDTLS_X509_CSR_PARSE_C=y
+CONFIG_MBEDTLS_ECP_C=y
+CONFIG_MBEDTLS_ECDH_C=y
+CONFIG_MBEDTLS_ECDSA_C=y
+CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y
+CONFIG_MBEDTLS_ECP_NIST_OPTIM=y
+CONFIG_MDNS_MAX_SERVICES=10
+CONFIG_MQTT_PROTOCOL_311=y
+CONFIG_MQTT_TRANSPORT_SSL=y
+CONFIG_MQTT_TRANSPORT_WEBSOCKET=y
+CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y
+# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set
+# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set
+# CONFIG_MQTT_CUSTOM_OUTBOX is not set
+CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y
+# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set
+# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set
+# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set
+# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set
+CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y
+# CONFIG_NEWLIB_NANO_FORMAT is not set
+# CONFIG_OPENSSL_DEBUG is not set
+CONFIG_OPENSSL_ASSERT_DO_NOTHING=y
+# CONFIG_OPENSSL_ASSERT_EXIT is not set
+CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5
+CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072
+CONFIG_ESP32_PTHREAD_STACK_MIN=768
+# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY is not set
+# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0 is not set
+CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1=y
+CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=1
+CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread"
+# CONFIG_SPI_FLASH_VERIFY_WRITE is not set
+# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set
+CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y
+CONFIG_SPIFFS_MAX_PARTITIONS=3
+CONFIG_SPIFFS_CACHE=y
+CONFIG_SPIFFS_CACHE_WR=y
+# CONFIG_SPIFFS_CACHE_STATS is not set
+CONFIG_SPIFFS_PAGE_CHECK=y
+CONFIG_SPIFFS_GC_MAX_RUNS=10
+# CONFIG_SPIFFS_GC_STATS is not set
+CONFIG_SPIFFS_PAGE_SIZE=256
+CONFIG_SPIFFS_OBJ_NAME_LEN=32
+CONFIG_SPIFFS_USE_MAGIC=y
+CONFIG_SPIFFS_USE_MAGIC_LENGTH=y
+CONFIG_SPIFFS_META_LENGTH=4
+CONFIG_SPIFFS_USE_MTIME=y
+# CONFIG_SPIFFS_DBG is not set
+# CONFIG_SPIFFS_API_DBG is not set
+# CONFIG_SPIFFS_GC_DBG is not set
+# CONFIG_SPIFFS_CACHE_DBG is not set
+# CONFIG_SPIFFS_CHECK_DBG is not set
+# CONFIG_SPIFFS_TEST_VISUALISATION is not set
+CONFIG_NETIF_IP_LOST_TIMER_INTERVAL=120
+CONFIG_TCPIP_LWIP=y
+CONFIG_UNITY_ENABLE_FLOAT=y
+CONFIG_UNITY_ENABLE_DOUBLE=y
+# CONFIG_UNITY_ENABLE_COLOR is not set
+CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
+# CONFIG_UNITY_ENABLE_FIXTURE is not set
+CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y
+CONFIG_SUPPORT_TERMIOS=y
+CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1
+CONFIG_SEMIHOSTFS_HOST_PATH_MAX_LEN=128
+# CONFIG_WL_SECTOR_SIZE_512 is not set
+CONFIG_WL_SECTOR_SIZE_4096=y
+CONFIG_WL_SECTOR_SIZE=4096
+# CONFIG_LEGACY_INCLUDE_COMMON_HEADERS is not set
+
+# Deprecated options for backward compatibility
+CONFIG_TOOLPREFIX="xtensa-esp32-elf-"
+CONFIG_PYTHON="python"
+CONFIG_MAKE_WARN_UNDEFINED_VARIABLES=y
+# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set
+# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set
+CONFIG_LOG_BOOTLOADER_LEVEL_WARN=y
+# CONFIG_LOG_BOOTLOADER_LEVEL_INFO is not set
+# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set
+# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set
+CONFIG_LOG_BOOTLOADER_LEVEL=2
+# CONFIG_APP_ROLLBACK_ENABLE is not set
+# CONFIG_FLASH_ENCRYPTION_ENABLED is not set
+CONFIG_FLASHMODE_QIO=y
+# CONFIG_FLASHMODE_QOUT is not set
+# CONFIG_FLASHMODE_DIO is not set
+# CONFIG_FLASHMODE_DOUT is not set
+# CONFIG_MONITOR_BAUD_9600B is not set
+# CONFIG_MONITOR_BAUD_57600B is not set
+CONFIG_MONITOR_BAUD_115200B=y
+# CONFIG_MONITOR_BAUD_230400B is not set
+# CONFIG_MONITOR_BAUD_921600B is not set
+# CONFIG_MONITOR_BAUD_2MB is not set
+# CONFIG_MONITOR_BAUD_OTHER is not set
+CONFIG_MONITOR_BAUD_OTHER_VAL=115200
+CONFIG_MONITOR_BAUD=115200
+# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set
+CONFIG_OPTIMIZATION_LEVEL_RELEASE=y
+CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y
+# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set
+# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set
+# CONFIG_CXX_EXCEPTIONS is not set
+CONFIG_STACK_CHECK_NONE=y
+# CONFIG_STACK_CHECK_NORM is not set
+# CONFIG_STACK_CHECK_STRONG is not set
+# CONFIG_STACK_CHECK_ALL is not set
+# CONFIG_STACK_CHECK is not set
+# CONFIG_WARN_WRITE_STRINGS is not set
+# CONFIG_DISABLE_GCC8_WARNINGS is not set
+# CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY is not set
+CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=y
+# CONFIG_BTDM_CONTROLLER_MODE_BTDM is not set
+CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN=2
+CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN=0
+CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=0
+CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=2
+CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=0
+CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0
+CONFIG_BTDM_CONTROLLER_HCI_MODE_VHCI=y
+# CONFIG_BTDM_CONTROLLER_HCI_MODE_UART_H4 is not set
+CONFIG_BTDM_CONTROLLER_MODEM_SLEEP=y
+CONFIG_BLUEDROID_ENABLED=y
+CONFIG_BLUEDROID_PINNED_TO_CORE_0=y
+# CONFIG_BLUEDROID_PINNED_TO_CORE_1 is not set
+CONFIG_BLUEDROID_PINNED_TO_CORE=0
+CONFIG_BTC_TASK_STACK_SIZE=3072
+CONFIG_BTU_TASK_STACK_SIZE=4096
+# CONFIG_BLUEDROID_MEM_DEBUG is not set
+CONFIG_CLASSIC_BT_ENABLED=y
+CONFIG_A2DP_ENABLE=y
+CONFIG_A2DP_SINK_TASK_STACK_SIZE=2048
+CONFIG_A2DP_SOURCE_TASK_STACK_SIZE=2048
+# CONFIG_HFP_ENABLE is not set
+# CONFIG_BLE_HOST_QUEUE_CONGESTION_CHECK is not set
+CONFIG_SMP_ENABLE=y
+CONFIG_BLE_ESTABLISH_LINK_CONNECTION_TIMEOUT=30
+CONFIG_ADC2_DISABLE_DAC=y
+CONFIG_SPIRAM_SUPPORT=y
+# CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST is not set
+# CONFIG_MEMMAP_TRACEMEM is not set
+# CONFIG_MEMMAP_TRACEMEM_TWOBANKS is not set
+CONFIG_TRACEMEM_RESERVE_DRAM=0x0
+# CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set
+CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y
+CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4
+# CONFIG_ULP_COPROC_ENABLED is not set
+CONFIG_ULP_COPROC_RESERVE_MEM=0
+CONFIG_BROWNOUT_DET=y
+CONFIG_BROWNOUT_DET_LVL_SEL_0=y
+# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set
+# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set
+# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set
+# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set
+# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set
+# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set
+# CONFIG_BROWNOUT_DET_LVL_SEL_7 is not set
+CONFIG_BROWNOUT_DET_LVL=0
+CONFIG_REDUCE_PHY_TX_POWER=y
+CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y
+# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set
+# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC is not set
+# CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 is not set
+# CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set
+# CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set
+CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32
+CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304
+CONFIG_MAIN_TASK_STACK_SIZE=10240
+CONFIG_IPC_TASK_STACK_SIZE=1024
+CONFIG_TIMER_TASK_STACK_SIZE=3584
+CONFIG_CONSOLE_UART_DEFAULT=y
+# CONFIG_CONSOLE_UART_CUSTOM is not set
+# CONFIG_CONSOLE_UART_NONE is not set
+CONFIG_CONSOLE_UART_NUM=0
+CONFIG_CONSOLE_UART_BAUDRATE=115200
+CONFIG_INT_WDT=y
+CONFIG_INT_WDT_TIMEOUT_MS=800
+CONFIG_INT_WDT_CHECK_CPU1=y
+CONFIG_TASK_WDT=y
+# CONFIG_TASK_WDT_PANIC is not set
+CONFIG_TASK_WDT_TIMEOUT_S=5
+CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y
+CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y
+# CONFIG_EVENT_LOOP_PROFILING is not set
+CONFIG_POST_EVENTS_FROM_ISR=y
+CONFIG_POST_EVENTS_FROM_IRAM_ISR=y
+CONFIG_SW_COEXIST_ENABLE=y
+# CONFIG_SW_COEXIST_PREFERENCE_WIFI is not set
+CONFIG_SW_COEXIST_PREFERENCE_BT=y
+# CONFIG_SW_COEXIST_PREFERENCE_BALANCE is not set
+CONFIG_SW_COEXIST_PREFERENCE_VALUE=1
+CONFIG_DMA_RX_BUF_NUM=10
+CONFIG_DMA_TX_BUF_NUM=10
+CONFIG_EMAC_L2_TO_L3_RX_BUF_MODE=y
+CONFIG_EMAC_CHECK_LINK_PERIOD_MS=2000
+CONFIG_EMAC_TASK_PRIORITY=20
+CONFIG_EMAC_TASK_STACK_SIZE=3072
+CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=150
+CONFIG_MB_MASTER_DELAY_MS_CONVERT=200
+CONFIG_MB_QUEUE_LENGTH=20
+CONFIG_MB_SERIAL_TASK_STACK_SIZE=2048
+CONFIG_MB_SERIAL_BUF_SIZE=256
+CONFIG_MB_SERIAL_TASK_PRIO=10
+# CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT is not set
+CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20
+CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20
+CONFIG_MB_CONTROLLER_STACK_SIZE=4096
+CONFIG_MB_EVENT_QUEUE_TIMEOUT=20
+CONFIG_MB_TIMER_PORT_ENABLED=y
+CONFIG_MB_TIMER_GROUP=0
+CONFIG_MB_TIMER_INDEX=0
+CONFIG_SUPPORT_STATIC_ALLOCATION=y
+# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set
+CONFIG_TIMER_TASK_PRIORITY=1
+CONFIG_TIMER_TASK_STACK_DEPTH=2048
+CONFIG_TIMER_QUEUE_LENGTH=10
+# CONFIG_L2_TO_L3_COPY is not set
+# CONFIG_USE_ONLY_LWIP_SELECT is not set
+CONFIG_ESP_GRATUITOUS_ARP=y
+CONFIG_GARP_TMR_INTERVAL=60
+CONFIG_TCPIP_RECVMBOX_SIZE=32
+CONFIG_TCP_MAXRTX=12
+CONFIG_TCP_SYNMAXRTX=6
+CONFIG_TCP_MSS=1440
+CONFIG_TCP_MSL=60000
+CONFIG_TCP_SND_BUF_DEFAULT=5744
+CONFIG_TCP_WND_DEFAULT=5744
+CONFIG_TCP_RECVMBOX_SIZE=6
+CONFIG_TCP_QUEUE_OOSEQ=y
+# CONFIG_ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set
+CONFIG_TCP_OVERSIZE_MSS=y
+# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set
+# CONFIG_TCP_OVERSIZE_DISABLE is not set
+CONFIG_UDP_RECVMBOX_SIZE=6
+CONFIG_TCPIP_TASK_STACK_SIZE=3072
+CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y
+# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set
+# CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set
+CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF
+# CONFIG_PPP_SUPPORT is not set
+CONFIG_PTHREAD_STACK_MIN=768
+CONFIG_IP_LOST_TIMER_INTERVAL=120
+# End of deprecated options

+ 15 - 2
sdkconfig.defaults

@@ -31,7 +31,9 @@ CONFIG_SPIRAM_BANKSWITCH_RESERVE=8
 CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768
 CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=2048
 CONFIG_PICO_PSRAM_CS_IO=10
-CONFIG_MAIN_TASK_STACK_SIZE=8000
+#todo:check if this should be changed SLE118 - increased size to troubleshoot an issue CONFIG_MAIN_TASK_STACK_SIZE=8000
+CONFIG_MAIN_TASK_STACK_SIZE=10240
+
 CONFIG_PARTITION_TABLE_CUSTOM=y
 CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
 CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
@@ -58,4 +60,15 @@ CONFIG_I2S_DO_IO=22
 CONFIG_I2S_BITS_PER_CHANNEL_16=y
 CONFIG_I2S_BITS_PER_CHANNEL=16
 CONFIG_DACAUDIO=y
-CONFIG_OUTPUT_NAME="DAC"
+CONFIG_OUTPUT_NAME="DAC"
+CONFIG_ESPTOOLPY_FLASHMODE_DIO=y
+CONFIG_ESPTOOLPY_FLASHMODE="dio"
+CONFIG_ESPTOOLPY_FLASHFREQ_40M=y
+CONFIG_ESPTOOLPY_FLASHFREQ="40m"
+CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
+CONFIG_ESPTOOLPY_FLASHSIZE="4MB"
+CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y
+
+# This is needed in order for some critical modules to load in IRAM
+# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set
+CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y