]> granicus.if.org Git - esp-idf/commitdiff
Merge branch 'feature/toolchain-update' into 'master'
authorIvan Grokhotkov <ivan@espressif.com>
Wed, 13 Sep 2017 10:05:09 +0000 (18:05 +0800)
committerIvan Grokhotkov <ivan@espressif.com>
Wed, 13 Sep 2017 10:05:09 +0000 (18:05 +0800)
Toolchain update

See merge request !1204

57 files changed:
.gitlab-ci.yml
components/app_trace/app_trace.c
components/app_trace/component.mk
components/app_trace/gcov/gcov_rtio.c [new file with mode: 0644]
components/app_trace/host_file_io.c [new file with mode: 0644]
components/app_trace/include/esp_app_trace.h
components/bt/bluedroid/api/esp_gap_ble_api.c
components/bt/bluedroid/api/include/esp_gap_ble_api.h
components/bt/bluedroid/btc/core/btc_ble_storage.c
components/bt/bluedroid/btc/core/btc_config.c
components/bt/bluedroid/btc/core/btc_dm.c
components/bt/bluedroid/btc/core/btc_storage.c
components/bt/bluedroid/btc/include/btc_ble_storage.h
components/bt/bluedroid/btc/include/btc_config.h
components/bt/bluedroid/btc/include/btc_dm.h
components/bt/bluedroid/btc/include/btc_storage.h
components/bt/bluedroid/btc/profile/std/gap/btc_gap_ble.c
components/bt/bluedroid/btc/profile/std/include/btc_gap_ble.h
components/bt/bluedroid/btif/bta_dm_co.c
components/bt/bluedroid/hci/hci_layer.c
components/bt/bluedroid/hci/include/hci_layer.h
components/bt/bluedroid/stack/btm/btm_ble_gap.c
components/bt/bluedroid/stack/gatt/gatt_utils.c
components/bt/include/bt.h
components/bt/lib
components/driver/include/driver/uart.h
components/driver/uart.c
components/esp32/ld/esp32.common.ld
components/esp32/ld/esp32.rom.ld
components/esp32/ld/esp32.spiram.rom-functions-dram.ld [new file with mode: 0644]
components/esp32/ld/esp32.spiram.rom-functions-iram.ld [new file with mode: 0644]
components/freertos/FreeRTOS-openocd.c
components/freertos/include/freertos/FreeRTOSConfig.h
components/freertos/tasks.c
components/freertos/test/test_tasks_snapshot.c [new file with mode: 0644]
components/lwip/apps/dhcpserver.c
components/lwip/include/lwip/apps/dhcpserver.h
components/lwip/include/lwip/apps/dhcpserver_options.h [new file with mode: 0644]
components/nvs_flash/src/nvs_api.cpp
components/nvs_flash/test_nvs_host/test_nvs.cpp
components/spiffs/component.mk
components/tcpip_adapter/tcpip_adapter_lwip.c
docs/api-guides/build-system.rst
docs/api-reference/peripherals/spi_master.rst
docs/get-started/index.rst
docs/kconfiglib.py
docs/sphinx-known-warnings.txt [new file with mode: 0644]
examples/bluetooth/gatt_security_server/main/example_ble_sec_gatts_demo.c
examples/bluetooth/gatt_server/main/gatts_demo.c
examples/system/gcov/Makefile [new file with mode: 0644]
examples/system/gcov/README.md [new file with mode: 0644]
examples/system/gcov/main/Kconfig.projbuild [new file with mode: 0644]
examples/system/gcov/main/component.mk [new file with mode: 0644]
examples/system/gcov/main/gcov_example.c [new file with mode: 0644]
examples/system/gcov/main/gcov_example_func.c [new file with mode: 0644]
examples/system/gcov/sdkconfig.defaults [new file with mode: 0644]
make/project.mk

index a480e580b300da5cef2e02a29ba843aa8bb69283..4989fa7ebbb357834507ff3ddebb60f538a52ac2 100644 (file)
@@ -175,16 +175,31 @@ build_docs:
   tags:
     - build_docs
   artifacts:
+    when: always
     paths:
+      - docs/doxygen-warning-log.txt
+      - docs/sphinx-warning-log.txt
       - docs/_build/html
     expire_in: 1 mos
   script:
     - cd docs
     - doxygen
-    # If not building master branch, and there are Doxygen warnings, print them and bail out
-    - test -n $IS_PRIVATE && test $(cat doxygen-warning-log.txt | wc -l) -eq 0 || ( echo "Doxygen pass had some warnings:" && cat doxygen-warning-log.txt && false )
+    # If there are Doxygen warnings, print them and bail out
+    - test $(cat doxygen-warning-log.txt | wc -l) -eq 0 || ( echo "Doxygen pass had some warnings:" && cat doxygen-warning-log.txt && false )
     - make gh-linkcheck
     - make html
+    # If there are Sphinx warnings, print them and bail out
+    # Ignore warnings (sphinx-known-warnings.txt) already reported in:
+    # https://github.com/sphinx-doc/sphinx/issues/2683
+    # https://github.com/sphinx-doc/sphinx/issues/4041
+    # If a new warning has to be added, then it should be documented as above
+    # Note: this check is not clever enough to ignore the same warning
+    #       but reported for different line of documentation. 
+    #       If s warning stays the same and the line number has changed,
+    #       then update 'sphinx-known-warnings.txt' to reflect the new lines numbers.
+    - DIFF_FORMAT="--changed-group-format=%<%> --unchanged-group-format="
+    - LOG_DIFF=$(diff $DIFF_FORMAT sphinx-known-warnings.txt sphinx-warning-log.txt)
+    - test -z "$LOG_DIFF" || ( echo "Sphinx pass had some new warnings:" && echo "$LOG_DIFF" && false )
 
 test_nvs_on_host:
   stage: test
index 679686a39a6b98469f202277656acc689d6fb44f..293f210e2b3e626e77f844290000e97df38900d7 100644 (file)
@@ -254,6 +254,10 @@ static volatile uint8_t *s_trax_blocks[] = {
 #define ESP_APPTRACE_USR_DATA_LEN_MAX           (ESP_APPTRACE_TRAX_BLOCK_SIZE - sizeof(esp_tracedata_hdr_t))
 #endif
 
+#define ESP_APPTRACE_HW_TRAX                    0
+#define ESP_APPTRACE_HW_MAX                     1
+#define ESP_APPTRACE_HW(_i_)                    (&s_trace_hw[_i_])
+
 /** Trace data header. Every user data chunk is prepended with this header.
  * User allocates block with esp_apptrace_buffer_get and then fills it with data,
  * in multithreading environment it can happen that tasks gets buffer and then gets interrupted,
@@ -326,8 +330,33 @@ static esp_apptrace_buffer_t    s_trace_buf;
 static esp_apptrace_lock_t s_log_lock = {.irq_stat = 0, .portmux = portMUX_INITIALIZER_UNLOCKED};
 #endif
 
+typedef struct {
+    uint8_t *(*get_up_buffer)(uint32_t, esp_apptrace_tmo_t *);
+    esp_err_t (*put_up_buffer)(uint8_t *, esp_apptrace_tmo_t *);
+    esp_err_t (*flush_up_buffer)(uint32_t, esp_apptrace_tmo_t *);
+    uint8_t *(*get_down_buffer)(uint32_t *, esp_apptrace_tmo_t *);
+    esp_err_t (*put_down_buffer)(uint8_t *, esp_apptrace_tmo_t *);
+    bool (*host_is_connected)(void);
+} esp_apptrace_hw_t;
+
 static uint32_t esp_apptrace_trax_down_buffer_write_nolock(uint8_t *data, uint32_t size);
 static esp_err_t esp_apptrace_trax_flush(uint32_t min_sz, esp_apptrace_tmo_t *tmo);
+static uint8_t *esp_apptrace_trax_get_buffer(uint32_t size, esp_apptrace_tmo_t *tmo);
+static esp_err_t esp_apptrace_trax_put_buffer(uint8_t *ptr, esp_apptrace_tmo_t *tmo);
+static bool esp_apptrace_trax_host_is_connected(void);
+static uint8_t *esp_apptrace_trax_down_buffer_get(uint32_t *size, esp_apptrace_tmo_t *tmo);
+static esp_err_t esp_apptrace_trax_down_buffer_put(uint8_t *ptr, esp_apptrace_tmo_t *tmo);
+
+static esp_apptrace_hw_t s_trace_hw[ESP_APPTRACE_HW_MAX] = {
+    {
+        .get_up_buffer = esp_apptrace_trax_get_buffer,
+        .put_up_buffer = esp_apptrace_trax_put_buffer,
+        .flush_up_buffer = esp_apptrace_trax_flush,
+        .get_down_buffer = esp_apptrace_trax_down_buffer_get,
+        .put_down_buffer = esp_apptrace_trax_down_buffer_put,
+        .host_is_connected = esp_apptrace_trax_host_is_connected
+    }
+};
 
 static inline int esp_apptrace_log_lock()
 {
@@ -586,7 +615,7 @@ static uint8_t *esp_apptrace_trax_down_buffer_get(uint32_t *size, esp_apptrace_t
     return ptr;
 }
 
-static inline esp_err_t esp_apptrace_trax_down_buffer_put(uint8_t *ptr, esp_apptrace_tmo_t *tmo)
+static esp_err_t esp_apptrace_trax_down_buffer_put(uint8_t *ptr, esp_apptrace_tmo_t *tmo)
 {
     /* nothing todo */
     return ESP_OK;
@@ -597,8 +626,8 @@ static uint32_t esp_apptrace_trax_down_buffer_write_nolock(uint8_t *data, uint32
     uint32_t total_sz = 0;
 
     while (total_sz < size) {
-        // ESP_APPTRACE_LOGE("esp_apptrace_trax_down_buffer_write_nolock WRS %d-%d-%d %d", s_trace_buf.rb_down.wr, s_trace_buf.rb_down.rd,
-        //     s_trace_buf.rb_down.cur_size, size);
+        ESP_APPTRACE_LOGD("esp_apptrace_trax_down_buffer_write_nolock WRS %d-%d-%d %d", s_trace_buf.rb_down.wr, s_trace_buf.rb_down.rd,
+            s_trace_buf.rb_down.cur_size, size);
         uint32_t wr_sz = esp_apptrace_rb_write_size_get(&s_trace_buf.rb_down);
         if (wr_sz == 0) {
             break;
@@ -607,15 +636,15 @@ static uint32_t esp_apptrace_trax_down_buffer_write_nolock(uint8_t *data, uint32
         if (wr_sz > size - total_sz) {
             wr_sz = size - total_sz;
         }
-        // ESP_APPTRACE_LOGE("esp_apptrace_trax_down_buffer_write_nolock wr %d", wr_sz);
+        ESP_APPTRACE_LOGD("esp_apptrace_trax_down_buffer_write_nolock wr %d", wr_sz);
         uint8_t *ptr = esp_apptrace_rb_produce(&s_trace_buf.rb_down, wr_sz);
         if (!ptr) {
             assert(false && "Failed to produce bytes to down buffer!");
         }
-        // ESP_APPTRACE_LOGE("esp_apptrace_trax_down_buffer_write_nolock wr %d to 0x%x from 0x%x", wr_sz, ptr, data + total_sz + wr_sz);
+        ESP_APPTRACE_LOGD("esp_apptrace_trax_down_buffer_write_nolock wr %d to 0x%x from 0x%x", wr_sz, ptr, data + total_sz + wr_sz);
         memcpy(ptr, data + total_sz, wr_sz);
         total_sz += wr_sz;
-        // ESP_APPTRACE_LOGE("esp_apptrace_trax_down_buffer_write_nolock wr %d/%d", wr_sz, total_sz);
+        ESP_APPTRACE_LOGD("esp_apptrace_trax_down_buffer_write_nolock wr %d/%d", wr_sz, total_sz);
     }
     return total_sz;
 }
@@ -795,6 +824,11 @@ static esp_err_t esp_apptrace_trax_flush(uint32_t min_sz, esp_apptrace_tmo_t *tm
     return res;
 }
 
+static bool esp_apptrace_trax_host_is_connected(void)
+{
+    return eri_read(ESP_APPTRACE_TRAX_CTRL_REG) & ESP_APPTRACE_TRAX_HOST_CONNECT ? true : false;
+}
+
 static esp_err_t esp_apptrace_trax_dest_init()
 {
     for (int i = 0; i < ESP_APPTRACE_TRAX_BLOCKS_NUM; i++) {
@@ -867,14 +901,11 @@ esp_err_t esp_apptrace_read(esp_apptrace_dest_t dest, void *buf, uint32_t *size,
 {
     int res = ESP_OK;
     esp_apptrace_tmo_t tmo;
-    //TODO: use ptr to HW transport iface struct
-    uint8_t *(*apptrace_get_down_buffer)(uint32_t *, esp_apptrace_tmo_t *);
-    esp_err_t (*apptrace_put_down_buffer)(uint8_t *, esp_apptrace_tmo_t *);
+    esp_apptrace_hw_t *hw = NULL;
 
     if (dest == ESP_APPTRACE_DEST_TRAX) {
 #if CONFIG_ESP32_APPTRACE_DEST_TRAX
-        apptrace_get_down_buffer = esp_apptrace_trax_down_buffer_get;
-        apptrace_put_down_buffer = esp_apptrace_trax_down_buffer_put;
+        hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
 #else
         ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
         return ESP_ERR_NOT_SUPPORTED;
@@ -888,12 +919,14 @@ esp_err_t esp_apptrace_read(esp_apptrace_dest_t dest, void *buf, uint32_t *size,
     esp_apptrace_tmo_init(&tmo, user_tmo);
     uint32_t act_sz = *size;
     *size = 0;
-    uint8_t * ptr = apptrace_get_down_buffer(&act_sz, &tmo);
+    uint8_t * ptr = hw->get_down_buffer(&act_sz, &tmo);
     if (ptr && act_sz > 0) {
         ESP_APPTRACE_LOGD("Read %d bytes from host", act_sz);
         memcpy(buf, ptr, act_sz);
-        res = apptrace_put_down_buffer(ptr, &tmo);
+        res = hw->put_down_buffer(ptr, &tmo);
         *size = act_sz;
+    } else {
+        res = ESP_ERR_TIMEOUT;
     }
 
     return res;
@@ -902,12 +935,11 @@ esp_err_t esp_apptrace_read(esp_apptrace_dest_t dest, void *buf, uint32_t *size,
 uint8_t *esp_apptrace_down_buffer_get(esp_apptrace_dest_t dest, uint32_t *size, uint32_t user_tmo)
 {
     esp_apptrace_tmo_t tmo;
-    //TODO: use ptr to HW transport iface struct
-    uint8_t *(*apptrace_get_down_buffer)(uint32_t *, esp_apptrace_tmo_t *);
+    esp_apptrace_hw_t *hw = NULL;
 
     if (dest == ESP_APPTRACE_DEST_TRAX) {
 #if CONFIG_ESP32_APPTRACE_DEST_TRAX
-        apptrace_get_down_buffer = esp_apptrace_trax_down_buffer_get;
+        hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
 #else
         ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
         return NULL;
@@ -919,18 +951,17 @@ uint8_t *esp_apptrace_down_buffer_get(esp_apptrace_dest_t dest, uint32_t *size,
 
     // ESP_APPTRACE_LOGE("esp_apptrace_down_buffer_get %d", *size);
     esp_apptrace_tmo_init(&tmo, user_tmo);
-    return apptrace_get_down_buffer(size, &tmo);
+    return hw->get_down_buffer(size, &tmo);
 }
 
 esp_err_t esp_apptrace_down_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, uint32_t user_tmo)
 {
     esp_apptrace_tmo_t tmo;
-    //TODO: use ptr to HW transport iface struct
-    esp_err_t (*apptrace_put_down_buffer)(uint8_t *, esp_apptrace_tmo_t *);
+    esp_apptrace_hw_t *hw = NULL;
 
     if (dest == ESP_APPTRACE_DEST_TRAX) {
 #if CONFIG_ESP32_APPTRACE_DEST_TRAX
-        apptrace_put_down_buffer = esp_apptrace_trax_down_buffer_put;
+        hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
 #else
         ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
         return ESP_ERR_NOT_SUPPORTED;
@@ -941,21 +972,18 @@ esp_err_t esp_apptrace_down_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, u
     }
 
     esp_apptrace_tmo_init(&tmo, user_tmo);
-    return apptrace_put_down_buffer(ptr, &tmo);
+    return hw->put_down_buffer(ptr, &tmo);
 }
 
 esp_err_t esp_apptrace_write(esp_apptrace_dest_t dest, const void *data, uint32_t size, uint32_t user_tmo)
 {
     uint8_t *ptr = NULL;
     esp_apptrace_tmo_t tmo;
-    //TODO: use ptr to HW transport iface struct
-    uint8_t *(*apptrace_get_buffer)(uint32_t, esp_apptrace_tmo_t *);
-    esp_err_t (*apptrace_put_buffer)(uint8_t *, esp_apptrace_tmo_t *);
+    esp_apptrace_hw_t *hw = NULL;
 
     if (dest == ESP_APPTRACE_DEST_TRAX) {
 #if CONFIG_ESP32_APPTRACE_DEST_TRAX
-        apptrace_get_buffer = esp_apptrace_trax_get_buffer;
-        apptrace_put_buffer = esp_apptrace_trax_put_buffer;
+        hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
 #else
         ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
         return ESP_ERR_NOT_SUPPORTED;
@@ -966,7 +994,7 @@ esp_err_t esp_apptrace_write(esp_apptrace_dest_t dest, const void *data, uint32_
     }
 
     esp_apptrace_tmo_init(&tmo, user_tmo);
-    ptr = apptrace_get_buffer(size, &tmo);
+    ptr = hw->get_up_buffer(size, &tmo);
     if (ptr == NULL) {
         return ESP_ERR_NO_MEM;
     }
@@ -976,7 +1004,7 @@ esp_err_t esp_apptrace_write(esp_apptrace_dest_t dest, const void *data, uint32_
     memcpy(ptr, data, size);
 
     // now indicate that this buffer is ready to be sent off to host
-    return apptrace_put_buffer(ptr, &tmo);
+    return hw->put_up_buffer(ptr, &tmo);
 }
 
 int esp_apptrace_vprintf_to(esp_apptrace_dest_t dest, uint32_t user_tmo, const char *fmt, va_list ap)
@@ -984,14 +1012,11 @@ int esp_apptrace_vprintf_to(esp_apptrace_dest_t dest, uint32_t user_tmo, const c
     uint16_t nargs = 0;
     uint8_t *pout, *p = (uint8_t *)fmt;
     esp_apptrace_tmo_t tmo;
-    //TODO: use ptr to HW transport iface struct
-    uint8_t *(*apptrace_get_buffer)(uint32_t, esp_apptrace_tmo_t *);
-    esp_err_t (*apptrace_put_buffer)(uint8_t *, esp_apptrace_tmo_t *);
+    esp_apptrace_hw_t *hw = NULL;
 
     if (dest == ESP_APPTRACE_DEST_TRAX) {
 #if CONFIG_ESP32_APPTRACE_DEST_TRAX
-        apptrace_get_buffer = esp_apptrace_trax_get_buffer;
-        apptrace_put_buffer = esp_apptrace_trax_put_buffer;
+        hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
 #else
         ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
         return ESP_ERR_NOT_SUPPORTED;
@@ -1014,7 +1039,7 @@ int esp_apptrace_vprintf_to(esp_apptrace_dest_t dest, uint32_t user_tmo, const c
         ESP_APPTRACE_LOGE("Failed to store all printf args!");
     }
 
-    pout = apptrace_get_buffer(1 + sizeof(char *) + nargs * sizeof(uint32_t), &tmo);
+    pout = hw->get_up_buffer(1 + sizeof(char *) + nargs * sizeof(uint32_t), &tmo);
     if (pout == NULL) {
         ESP_APPTRACE_LOGE("Failed to get buffer!");
         return -1;
@@ -1031,7 +1056,7 @@ int esp_apptrace_vprintf_to(esp_apptrace_dest_t dest, uint32_t user_tmo, const c
         ESP_APPTRACE_LOGD("arg %x", arg);
     }
 
-    int ret = apptrace_put_buffer(p, &tmo);
+    int ret = hw->put_up_buffer(p, &tmo);
     if (ret != ESP_OK) {
         ESP_APPTRACE_LOGE("Failed to put printf buf (%d)!", ret);
         return -1;
@@ -1048,12 +1073,11 @@ int esp_apptrace_vprintf(const char *fmt, va_list ap)
 uint8_t *esp_apptrace_buffer_get(esp_apptrace_dest_t dest, uint32_t size, uint32_t user_tmo)
 {
     esp_apptrace_tmo_t tmo;
-    //TODO: use ptr to HW transport iface struct
-    uint8_t *(*apptrace_get_buffer)(uint32_t, esp_apptrace_tmo_t *);
+    esp_apptrace_hw_t *hw = NULL;
 
     if (dest == ESP_APPTRACE_DEST_TRAX) {
 #if CONFIG_ESP32_APPTRACE_DEST_TRAX
-        apptrace_get_buffer = esp_apptrace_trax_get_buffer;
+        hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
 #else
         ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
         return NULL;
@@ -1064,18 +1088,17 @@ uint8_t *esp_apptrace_buffer_get(esp_apptrace_dest_t dest, uint32_t size, uint32
     }
 
     esp_apptrace_tmo_init(&tmo, user_tmo);
-    return apptrace_get_buffer(size, &tmo);
+    return hw->get_up_buffer(size, &tmo);
 }
 
 esp_err_t esp_apptrace_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, uint32_t user_tmo)
 {
     esp_apptrace_tmo_t tmo;
-    //TODO: use ptr to HW transport iface struct
-    esp_err_t (*apptrace_put_buffer)(uint8_t *, esp_apptrace_tmo_t *);
+    esp_apptrace_hw_t *hw = NULL;
 
     if (dest == ESP_APPTRACE_DEST_TRAX) {
 #if CONFIG_ESP32_APPTRACE_DEST_TRAX
-        apptrace_put_buffer = esp_apptrace_trax_put_buffer;
+        hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
 #else
         ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
         return ESP_ERR_NOT_SUPPORTED;
@@ -1086,18 +1109,17 @@ esp_err_t esp_apptrace_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, uint32
     }
 
     esp_apptrace_tmo_init(&tmo, user_tmo);
-    return apptrace_put_buffer(ptr, &tmo);
+    return hw->put_up_buffer(ptr, &tmo);
 }
 
 esp_err_t esp_apptrace_flush_nolock(esp_apptrace_dest_t dest, uint32_t min_sz, uint32_t usr_tmo)
 {
     esp_apptrace_tmo_t tmo;
-    //TODO: use ptr to HW transport iface struct
-    esp_err_t (*apptrace_flush)(uint32_t, esp_apptrace_tmo_t *);
+    esp_apptrace_hw_t *hw = NULL;
 
     if (dest == ESP_APPTRACE_DEST_TRAX) {
 #if CONFIG_ESP32_APPTRACE_DEST_TRAX
-        apptrace_flush = esp_apptrace_trax_flush;
+        hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
 #else
         ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
         return ESP_ERR_NOT_SUPPORTED;
@@ -1108,7 +1130,7 @@ esp_err_t esp_apptrace_flush_nolock(esp_apptrace_dest_t dest, uint32_t min_sz, u
     }
 
     esp_apptrace_tmo_init(&tmo, usr_tmo);
-    return apptrace_flush(min_sz, &tmo);
+    return hw->flush_up_buffer(min_sz, &tmo);
 }
 
 esp_err_t esp_apptrace_flush(esp_apptrace_dest_t dest, uint32_t usr_tmo)
@@ -1134,4 +1156,23 @@ esp_err_t esp_apptrace_flush(esp_apptrace_dest_t dest, uint32_t usr_tmo)
 
     return res;
 }
+
+bool esp_apptrace_host_is_connected(esp_apptrace_dest_t dest)
+{
+    esp_apptrace_hw_t *hw = NULL;
+
+    if (dest == ESP_APPTRACE_DEST_TRAX) {
+#if CONFIG_ESP32_APPTRACE_DEST_TRAX
+        hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
+#else
+        ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
+        return ESP_ERR_NOT_SUPPORTED;
+#endif
+    } else {
+        ESP_APPTRACE_LOGE("Trace destinations other then TRAX are not supported yet!");
+        return ESP_ERR_NOT_SUPPORTED;
+    }
+    return hw->host_is_connected();
+}
+
 #endif
index 235f19831d2fb7fc346c4dae43bd6e2bc49ea20f..b53e27d307ee0ac9bb3271d03b031a45fdc1e97f 100644 (file)
@@ -4,12 +4,14 @@
 
 COMPONENT_SRCDIRS := .
 
-COMPONENT_ADD_INCLUDEDIRS := include
+COMPONENT_ADD_INCLUDEDIRS = include
 
-COMPONENT_ADD_LDFLAGS := -lapp_trace 
+COMPONENT_ADD_LDFLAGS = -lapp_trace
+
+# do not produce gcov info for this module, it is used as transport for gcov
+CFLAGS := $(subst --coverage,,$(CFLAGS))
 
 ifdef CONFIG_SYSVIEW_ENABLE
-#COMPONENT_EXTRA_INCLUDES := freertos
 
 COMPONENT_ADD_INCLUDEDIRS += \
        sys_view/Config \
@@ -17,8 +19,11 @@ COMPONENT_ADD_INCLUDEDIRS += \
        sys_view/Sample/OS
 
 COMPONENT_SRCDIRS += \
+       gcov \
        sys_view/SEGGER \
        sys_view/Sample/OS \
        sys_view/Sample/Config \
        sys_view/esp32
+else
+COMPONENT_SRCDIRS += gcov
 endif
diff --git a/components/app_trace/gcov/gcov_rtio.c b/components/app_trace/gcov/gcov_rtio.c
new file mode 100644 (file)
index 0000000..c03bd6b
--- /dev/null
@@ -0,0 +1,93 @@
+// Copyright 2017 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// This module implements runtime file I/O API for GCOV.
+
+#include "esp_task_wdt.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "soc/cpu.h"
+#include "soc/timer_group_struct.h"
+#include "soc/timer_group_reg.h"
+#include "esp_app_trace.h"
+
+#if CONFIG_ESP32_APPTRACE_ENABLE
+
+#define LOG_LOCAL_LEVEL CONFIG_LOG_DEFAULT_LEVEL
+#include "esp_log.h"
+const static char *TAG = "esp_gcov_rtio";
+
+static void (*s_gcov_exit)(void);
+static uint8_t s_gcov_down_buf[256];
+
+void esp_gcov_dump()
+{
+#if CONFIG_FREERTOS_UNICORE == 0
+    esp_cpu_stall(!xPortGetCoreID());
+#endif
+
+    while (!esp_apptrace_host_is_connected(ESP_APPTRACE_DEST_TRAX)) {
+        // to avoid complains that task watchdog got triggered for other tasks
+        TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE;
+        TIMERG0.wdt_feed=1;
+        TIMERG0.wdt_wprotect=0;
+        // to avoid reboot on INT_WDT
+        TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE;
+        TIMERG1.wdt_feed=1;
+        TIMERG1.wdt_wprotect=0;
+    }
+
+    if (s_gcov_exit) {
+        s_gcov_exit();
+    }
+
+    int ret = esp_apptrace_fstop(ESP_APPTRACE_DEST_TRAX);
+    if (ret != ESP_OK) {
+        ESP_LOGE(TAG, "Failed to send files transfer stop cmd (%d)!\n", ret);
+    }
+}
+
+int gcov_rtio_atexit(void (*function)(void))
+{
+    s_gcov_exit = function;
+    esp_apptrace_down_buffer_config(s_gcov_down_buf, sizeof(s_gcov_down_buf));
+    return 0;
+}
+
+void *gcov_rtio_fopen(const char *path, const char *mode)
+{
+    return esp_apptrace_fopen(ESP_APPTRACE_DEST_TRAX, path, mode);
+}
+
+int gcov_rtio_fclose(void *stream)
+{
+    return esp_apptrace_fclose(ESP_APPTRACE_DEST_TRAX, stream);
+}
+
+size_t gcov_rtio_fwrite(const void *ptr, size_t size, size_t nmemb, void *stream)
+{
+    return esp_apptrace_fwrite(ESP_APPTRACE_DEST_TRAX, ptr, size, nmemb, stream);
+}
+
+int gcov_rtio_fseek(void *stream, long offset, int whence)
+{
+    return esp_apptrace_fseek(ESP_APPTRACE_DEST_TRAX, stream, offset, whence);
+}
+
+long gcov_rtio_ftell(void *stream)
+{
+    return esp_apptrace_ftell(ESP_APPTRACE_DEST_TRAX, stream);
+}
+
+#endif
diff --git a/components/app_trace/host_file_io.c b/components/app_trace/host_file_io.c
new file mode 100644 (file)
index 0000000..d16144a
--- /dev/null
@@ -0,0 +1,340 @@
+// Copyright 2017 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Hot It Works
+// ************
+//
+// This module implements host file I/O protocol on top of apptrace module.
+// The protocol is enough simple. It sends command with arguments to the host and receives response from it.
+// Responses contains return values of respective file I/O API. This value is returned to the caller.
+// Commands has the following format:
+//   * Header. See esp_apptrace_fcmd_hdr_t.
+//   * Operation arguments. See file operation helper structures below.
+
+#include <string.h>
+#include "esp_app_trace.h"
+
+#if CONFIG_ESP32_APPTRACE_ENABLE
+
+#define LOG_LOCAL_LEVEL CONFIG_LOG_DEFAULT_LEVEL
+#include "esp_log.h"
+const static char *TAG = "esp_host_file_io";
+
+#define ESP_APPTRACE_FILE_CMD_FOPEN     0x0
+#define ESP_APPTRACE_FILE_CMD_FCLOSE    0x1
+#define ESP_APPTRACE_FILE_CMD_FWRITE    0x2
+#define ESP_APPTRACE_FILE_CMD_FREAD     0x3
+#define ESP_APPTRACE_FILE_CMD_FSEEK     0x4
+#define ESP_APPTRACE_FILE_CMD_FTELL     0x5
+#define ESP_APPTRACE_FILE_CMD_STOP      0x6 // indicates that there is no files to transfer
+
+/** File operation header */
+typedef struct {
+    uint8_t   cmd; ///< Command ID
+} esp_apptrace_fcmd_hdr_t;
+
+/** Helper structure for fopen */
+typedef struct {
+    const char *path;
+    uint16_t path_len;
+    const char *mode;
+    uint16_t mode_len;
+} esp_apptrace_fopen_args_t;
+
+/** Helper structure for fclose */
+typedef struct {
+    void *file;
+} esp_apptrace_fclose_args_t;
+
+/** Helper structure for fwrite */
+typedef struct {
+    void *  buf;
+    size_t  size;
+    void *  file;
+} esp_apptrace_fwrite_args_t;
+
+/** Helper structure for fread */
+typedef struct {
+    size_t  size;
+    void *  file;
+} esp_apptrace_fread_args_t;
+
+/** Helper structure for fseek */
+typedef struct {
+    long    offset;
+    int     whence;
+    void *  file;
+} esp_apptrace_fseek_args_t;
+
+/** Helper structure for ftell */
+typedef struct {
+    void *file;
+} esp_apptrace_ftell_args_t;
+
+static esp_err_t esp_apptrace_file_cmd_send(esp_apptrace_dest_t dest, uint8_t cmd, void (*prep_args)(uint8_t *, void *), void *args, uint32_t args_len)
+{
+    esp_err_t ret;
+    esp_apptrace_fcmd_hdr_t *hdr;
+
+    uint8_t *ptr = esp_apptrace_buffer_get(dest, sizeof(*hdr) + args_len, ESP_APPTRACE_TMO_INFINITE); //TODO: finite tmo
+    if (ptr == NULL) {
+        return ESP_ERR_NO_MEM;
+    }
+
+    hdr = (esp_apptrace_fcmd_hdr_t *)ptr;
+    hdr->cmd = cmd;
+    if (prep_args) {
+        prep_args(ptr + sizeof(hdr->cmd), args);
+    }
+
+    // now indicate that this buffer is ready to be sent off to host
+    ret = esp_apptrace_buffer_put(dest, ptr, ESP_APPTRACE_TMO_INFINITE);//TODO: finite tmo
+    if (ret != ESP_OK) {
+        ESP_LOGE(TAG, "Failed to put apptrace buffer (%d)!", ret);
+        return ret;
+    }
+
+    ret = esp_apptrace_flush(dest, ESP_APPTRACE_TMO_INFINITE);//TODO: finite tmo
+    if (ret != ESP_OK) {
+        ESP_LOGE(TAG, "Failed to flush apptrace buffer (%d)!", ret);
+        return ret;
+    }
+
+    return ESP_OK;
+}
+
+static esp_err_t esp_apptrace_file_rsp_recv(esp_apptrace_dest_t dest, uint8_t *buf, uint32_t buf_len)
+{
+    uint32_t tot_rd = 0;
+    while (tot_rd < buf_len) {
+        uint32_t rd_size = buf_len - tot_rd;
+        esp_err_t ret = esp_apptrace_read(dest, buf, &rd_size, ESP_APPTRACE_TMO_INFINITE); //TODO: finite tmo
+        if (ret != ESP_OK) {
+            ESP_LOGE(TAG, "Failed to read response (%d)!", ret);
+            return ret;
+        }
+        tot_rd += rd_size;
+    }
+
+    return ESP_OK;
+}
+
+static void esp_apptrace_fopen_args_prepare(uint8_t *buf, void *priv)
+{
+    esp_apptrace_fopen_args_t *args = priv;
+
+    memcpy(buf, args->path, args->path_len);
+    memcpy(buf + args->path_len, args->mode, args->mode_len);
+}
+
+void *esp_apptrace_fopen(esp_apptrace_dest_t dest, const char *path, const char *mode)
+{
+    esp_apptrace_fopen_args_t cmd_args;
+
+    cmd_args.path = path;
+    cmd_args.path_len = strlen(path) + 1;
+    cmd_args.mode = mode;
+    cmd_args.mode_len = strlen(mode) + 1;
+
+    esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FOPEN, esp_apptrace_fopen_args_prepare,
+                        &cmd_args, cmd_args.path_len+cmd_args.mode_len);
+    if (ret != ESP_OK) {
+        ESP_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
+        return NULL;
+    }
+
+    // now read the answer
+    uint8_t resp[sizeof(void *)];
+    ret = esp_apptrace_file_rsp_recv(dest, resp, sizeof(resp));
+    if (ret != ESP_OK) {
+        ESP_LOGE(TAG, "Failed to read response (%d)!", ret);
+        return NULL;
+    }
+
+    return *((void **)resp);
+}
+
+static void esp_apptrace_fclose_args_prepare(uint8_t *buf, void *priv)
+{
+    esp_apptrace_fclose_args_t *args = priv;
+
+    memcpy(buf, &args->file, sizeof(args->file));
+}
+
+int esp_apptrace_fclose(esp_apptrace_dest_t dest, void *stream)
+{
+    esp_apptrace_fclose_args_t cmd_args;
+
+    cmd_args.file = stream;
+    esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FCLOSE, esp_apptrace_fclose_args_prepare,
+                        &cmd_args, sizeof(cmd_args));
+    if (ret != ESP_OK) {
+        ESP_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
+        return EOF;
+    }
+
+    // now read the answer
+    uint8_t resp[sizeof(int)];
+    ret = esp_apptrace_file_rsp_recv(dest, resp, sizeof(resp));
+    if (ret != ESP_OK) {
+        ESP_LOGE(TAG, "Failed to read response (%d)!", ret);
+        return EOF;
+    }
+
+    return *((int *)resp);
+}
+
+static void esp_apptrace_fwrite_args_prepare(uint8_t *buf, void *priv)
+{
+    esp_apptrace_fwrite_args_t *args = priv;
+
+    memcpy(buf, &args->file, sizeof(args->file));
+    memcpy(buf + sizeof(args->file), args->buf, args->size);
+}
+
+size_t esp_apptrace_fwrite(esp_apptrace_dest_t dest, const void *ptr, size_t size, size_t nmemb, void *stream)
+{
+    esp_apptrace_fwrite_args_t cmd_args;
+
+    cmd_args.buf = (void *)ptr;
+    cmd_args.size = size * nmemb;
+    cmd_args.file = stream;
+    esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FWRITE, esp_apptrace_fwrite_args_prepare,
+                        &cmd_args, sizeof(cmd_args.file)+cmd_args.size);
+    if (ret != ESP_OK) {
+        ESP_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
+        return 0;
+    }
+
+    // now read the answer
+    uint8_t resp[sizeof(size_t)];
+    ret = esp_apptrace_file_rsp_recv(dest, resp, sizeof(resp));
+    if (ret != ESP_OK) {
+        ESP_LOGE(TAG, "Failed to read response (%d)!", ret);
+        return 0;
+    }
+
+    return *((size_t *)resp);
+}
+
+static void esp_apptrace_fread_args_prepare(uint8_t *buf, void *priv)
+{
+    esp_apptrace_fread_args_t *args = priv;
+
+    memcpy(buf, &args->file, sizeof(args->file));
+    memcpy(buf + sizeof(args->file), &args->size, sizeof(args->size));
+}
+
+size_t esp_apptrace_fread(esp_apptrace_dest_t dest, void *ptr, size_t size, size_t nmemb, void *stream)
+{
+    esp_apptrace_fread_args_t cmd_args;
+
+    cmd_args.size = size * nmemb;
+    cmd_args.file = stream;
+    esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FREAD, esp_apptrace_fread_args_prepare,
+                        &cmd_args, sizeof(cmd_args));
+    if (ret != ESP_OK) {
+        ESP_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
+        return 0;
+    }
+
+    // now read the answer
+    uint8_t resp[sizeof(size_t)];
+    ret = esp_apptrace_file_rsp_recv(dest, resp, sizeof(resp));
+    if (ret != ESP_OK) {
+        ESP_LOGE(TAG, "Failed to read response (%d)!", ret);
+        return 0;
+    }
+    if (*((size_t *)resp) > 0) {
+        ret = esp_apptrace_file_rsp_recv(dest, ptr, *((size_t *)resp));
+        if (ret != ESP_OK) {
+            ESP_LOGE(TAG, "Failed to read file data (%d)!", ret);
+            return 0;
+        }
+    }
+    return *((size_t *)resp);
+}
+
+static void esp_apptrace_fseek_args_prepare(uint8_t *buf, void *priv)
+{
+    esp_apptrace_fseek_args_t *args = priv;
+
+    memcpy(buf, &args->file, sizeof(args->file));
+}
+
+int esp_apptrace_fseek(esp_apptrace_dest_t dest, void *stream, long offset, int whence)
+{
+    esp_apptrace_fseek_args_t cmd_args;
+
+    cmd_args.file = stream;
+    cmd_args.offset = offset;
+    cmd_args.whence = whence;
+    esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FSEEK, esp_apptrace_fseek_args_prepare,
+                        &cmd_args, sizeof(cmd_args));
+    if (ret != ESP_OK) {
+        ESP_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
+        return -1;
+    }
+
+    // now read the answer
+    uint8_t resp[sizeof(int)];
+    ret = esp_apptrace_file_rsp_recv(dest, resp, sizeof(resp));
+    if (ret != ESP_OK) {
+        ESP_LOGE(TAG, "Failed to read response (%d)!", ret);
+        return -1;
+    }
+
+    return *((int *)resp);
+}
+
+static void esp_apptrace_ftell_args_prepare(uint8_t *buf, void *priv)
+{
+    esp_apptrace_ftell_args_t *args = priv;
+
+    memcpy(buf, &args->file, sizeof(args->file));
+}
+
+int esp_apptrace_ftell(esp_apptrace_dest_t dest, void *stream)
+{
+    esp_apptrace_ftell_args_t cmd_args;
+
+    cmd_args.file = stream;
+    esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FTELL, esp_apptrace_ftell_args_prepare,
+                        &cmd_args, sizeof(cmd_args));
+    if (ret != ESP_OK) {
+        ESP_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
+        return -1;
+    }
+
+    // now read the answer
+    uint8_t resp[sizeof(int)];
+    ret = esp_apptrace_file_rsp_recv(dest, resp, sizeof(resp));
+    if (ret != ESP_OK) {
+        ESP_LOGE(TAG, "Failed to read response (%d)!", ret);
+        return -1;
+    }
+
+    return *((int *)resp);
+}
+
+int esp_apptrace_fstop(esp_apptrace_dest_t dest)
+{
+    esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_STOP, NULL, NULL, 0);
+    if (ret != ESP_OK) {
+        ESP_LOGE(TAG, "Failed to send files transfer stop cmd (%d)!", ret);
+    }
+    return ret;
+}
+
+#endif
index aa35ea6a54f7f8392dfb5ada27a5d22bd4c66958..dbac4f475e37e9f67c1c39f0d813cc19ec9c3b16 100644 (file)
@@ -161,4 +161,105 @@ uint8_t *esp_apptrace_down_buffer_get(esp_apptrace_dest_t dest, uint32_t *size,
  */
 esp_err_t esp_apptrace_down_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, uint32_t tmo);
 
+/**
+ * @brief Checks whether host is connected.
+ *
+ * @param dest Indicates HW interface to use.
+ *
+ * @return true if host is connected, otherwise false
+ */
+bool esp_apptrace_host_is_connected(esp_apptrace_dest_t dest);
+
+/**
+ * @brief Opens file on host.
+ *               This function has the same semantic as 'fopen' except for the first argument.
+ *
+ * @param dest Indicates HW interface to use.
+ * @param path Path to file.
+ * @param mode Mode string. See fopen for details.
+ *
+ * @return non zero file handle on success, otherwise 0
+ */
+void *esp_apptrace_fopen(esp_apptrace_dest_t dest, const char *path, const char *mode);
+
+/**
+ * @brief Closes file on host.
+ *               This function has the same semantic as 'fclose' except for the first argument.
+ *
+ * @param dest   Indicates HW interface to use.
+ * @param stream File handle returned by esp_apptrace_fopen.
+ *
+ * @return Zero on success, otherwise non-zero. See fclose for details.
+ */
+int esp_apptrace_fclose(esp_apptrace_dest_t dest, void *stream);
+
+/**
+ * @brief Writes to file on host.
+ *               This function has the same semantic as 'fwrite' except for the first argument.
+ *
+ * @param dest   Indicates HW interface to use.
+ * @param ptr   Address of data to write.
+ * @param size          Size of an item.
+ * @param nmemb  Number of items to write.
+ * @param stream File handle returned by esp_apptrace_fopen.
+ *
+ * @return Number of written items. See fwrite for details.
+ */
+size_t esp_apptrace_fwrite(esp_apptrace_dest_t dest, const void *ptr, size_t size, size_t nmemb, void *stream);
+
+/**
+ * @brief Read file on host.
+ *               This function has the same semantic as 'fread' except for the first argument.
+ *
+ * @param dest   Indicates HW interface to use.
+ * @param ptr   Address to store read data.
+ * @param size          Size of an item.
+ * @param nmemb  Number of items to read.
+ * @param stream File handle returned by esp_apptrace_fopen.
+ *
+ * @return Number of read items. See fread for details.
+ */
+size_t esp_apptrace_fread(esp_apptrace_dest_t dest, void *ptr, size_t size, size_t nmemb, void *stream);
+
+/**
+ * @brief Set position indicator in file on host.
+ *               This function has the same semantic as 'fseek' except for the first argument.
+ *
+ * @param dest   Indicates HW interface to use.
+ * @param stream File handle returned by esp_apptrace_fopen.
+ * @param offset Offset. See fseek for details.
+ * @param whence Position in file. See fseek for details.
+ *
+ * @return Zero on success, otherwise non-zero. See fseek for details.
+ */
+int esp_apptrace_fseek(esp_apptrace_dest_t dest, void *stream, long offset, int whence);
+
+/**
+ * @brief Get current position indicator for file on host.
+ *               This function has the same semantic as 'ftell' except for the first argument.
+ *
+ * @param dest   Indicates HW interface to use.
+ * @param stream File handle returned by esp_apptrace_fopen.
+ *
+ * @return Current position in file. See ftell for details.
+ */
+int esp_apptrace_ftell(esp_apptrace_dest_t dest, void *stream);
+
+/**
+ * @brief Indicates to the host that all file operations are completed.
+ *               This function should be called after all file operations are finished and 
+ *               indicate to the host that it can perform cleanup operations (close open files etc.).
+ *
+ * @param dest   Indicates HW interface to use.
+ *
+ * @return ESP_OK on success, otherwise see esp_err_t
+ */
+int esp_apptrace_fstop(esp_apptrace_dest_t dest);
+
+/**
+ * @brief Triggers gcov info dump.
+ *               This function waits for the host to connect to target before dumping data.
+ */
+void esp_gcov_dump(void);
+
 #endif
index 521f748b1ad85832f86a8d09ad13637ccfc3da21..6b4ba68018231ff92afb9f14aa01117a48fecd6b 100644 (file)
@@ -20,6 +20,7 @@
 #include "bt_trace.h"
 #include "btc_manage.h"
 #include "btc_gap_ble.h"
+#include "btc_ble_storage.h"
 
 
 esp_err_t esp_ble_gap_register_callback(esp_gap_ble_cb_t callback)
@@ -364,26 +365,32 @@ esp_err_t esp_ble_remove_bond_device(esp_bd_addr_t bd_addr)
             == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
 }
 
-esp_err_t esp_ble_clear_bond_device_list(void)
+int esp_ble_get_bond_device_num(void)
 {
-    btc_msg_t msg;
-    msg.sig = BTC_SIG_API_CALL;
-    msg.pid = BTC_PID_GAP_BLE;
-    msg.act = BTC_GAP_BLE_CLEAR_BOND_DEV_EVT;
+    ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
 
-    return (btc_transfer_context(&msg, NULL, 0, NULL)
-            == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+    return btc_storage_get_num_ble_bond_devices();
 }
 
-esp_err_t esp_ble_get_bond_device_list(void)
+esp_err_t esp_ble_get_bond_device_list(int *dev_num, esp_ble_bond_dev_t *dev_list)
 {
-    btc_msg_t msg;
-    msg.sig = BTC_SIG_API_CALL;
-    msg.pid = BTC_PID_GAP_BLE;
-    msg.act = BTC_GAP_BLE_GET_BOND_DEV_EVT;
+    int ret;
+    int dev_num_total;
 
-    return (btc_transfer_context(&msg, NULL, 0, NULL)
-            == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+    if (dev_num == NULL || dev_list == NULL) {
+        return ESP_ERR_INVALID_ARG;
+    }
+
+    ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+
+    dev_num_total = btc_storage_get_num_ble_bond_devices();
+    if (*dev_num > dev_num_total) {
+        *dev_num = dev_num_total;
+    }
+
+    ret = btc_storage_get_bonded_ble_devices_list(dev_list, *dev_num);
+
+    return (ret == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
 }
 
 esp_err_t esp_ble_gap_disconnect(esp_bd_addr_t remote_device)
index a7cafcd35ee5d7a2f2e220d531203f0fd5885233..942a5499fcc6f70b1dc972013ab17ac3d71ecffa 100644 (file)
@@ -95,8 +95,6 @@ typedef enum {
     ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT,                /*!< When set pkt lenght complete, the event comes */
     ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT,             /*!< When  Enable/disable privacy on the local device complete, the event comes */
     ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT,               /*!< When remove the bond device complete, the event comes */
-    ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT,                /*!< When clear the bond device clear complete, the event comes */
-    ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT,                  /*!< When get the bond device list complete, the event comes */
     ESP_GAP_BLE_EVT_MAX,
 } esp_gap_ble_cb_event_t;
 
@@ -577,20 +575,6 @@ typedef union {
         esp_bt_status_t status;                     /*!< Indicate the remove bond device operation success status */
         esp_bd_addr_t bd_addr;                      /*!< The device address which has been remove from the bond list */
     }remove_bond_dev_cmpl;                          /*!< Event parameter of ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT */
-    /**
-     * @brief ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT
-     */
-    struct ble_clear_bond_dev_cmpl_evt_param {
-        esp_bt_status_t status;                     /*!< Indicate the clear bond device operation success status */
-    }clear_bond_dev_cmpl;                           /*!< Event parameter of ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT */
-    /**
-     * @brief ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT
-     */
-    struct ble_get_bond_dev_cmpl_evt_param {
-        esp_bt_status_t status;                     /*!< Indicate the get bond device operation success status */
-        uint8_t dev_num;                            /*!< Indicate the get number device in the bond list */
-        esp_ble_bond_dev_t *bond_dev;               /*!< the pointer to the bond device Structure */
-    }get_bond_dev_cmpl;                             /*!< Event parameter of ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT */
 } esp_ble_gap_cb_param_t;
 
 /**
@@ -879,24 +863,30 @@ esp_err_t esp_ble_confirm_reply(esp_bd_addr_t bd_addr, bool accept);
 esp_err_t esp_ble_remove_bond_device(esp_bd_addr_t bd_addr);
 
 /**
-* @brief           Removes all of the device from the security database list of
-*                  peer device. It manages unpairing event while connected.
+* @brief           Get the device number from the security database list of peer device.
+*                  It will return the device bonded number immediately.
 *
-* @return            - ESP_OK : success
-*                       - other  : failed
+* @return          - >= 0 : bonded devices number.
+*                  - < 0  : failed
 *
 */
-esp_err_t esp_ble_clear_bond_device_list(void);
+int esp_ble_get_bond_device_num(void);
+
 
 /**
 * @brief           Get the device from the security database list of peer device.
-*                  It will return the device bonded information from the ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT event.
+*                  It will return the device bonded information immediately.
+* @param[inout]    dev_num: Indicate the dev_list array(buffer) size as input.
+*                           If dev_num is large enough, it means the actual number as output.
+*                           Suggest that dev_num value equal to esp_ble_get_bond_device_num().
 *
-* @return            - ESP_OK : success
-*                       - other  : failed
+* @param[out]      dev_list: an array(buffer) of `esp_ble_bond_dev_t` type. Use for storing the bonded devices address.
+*                            The dev_list should be allocated by who call this API. 
+* @return          - ESP_OK : success
+*                  - other  : failed
 *
 */
-esp_err_t esp_ble_get_bond_device_list(void);
+esp_err_t esp_ble_get_bond_device_list(int *dev_num, esp_ble_bond_dev_t *dev_list);
 
 /**
 * @brief           This function is to disconnect the physical connection of the peer device
index c10aa1e4e4273ba66c82034e31de3e5c7a767316..538e9783599d40a357fb254bf7d5249ef667897c 100644 (file)
 
 #if (SMP_INCLUDED == TRUE)
 
-btc_dm_pairing_cb_t pairing_cb;
-btc_dm_local_key_cb_t ble_local_key_cb;
-btc_bonded_devices_t bonded_devices;
-
-
-/*******************************************************************************
-**
-** Function         btc_storage_load_bonded_devices
-**
-** Description      btc storage API - Loads all the bonded devices from NVRAM
-**                  and adds to the BTA.
-**                  Additionally, this API also invokes the adaper_properties_cb
-**                  and remote_device_properties_cb for each of the bonded devices.
-**
-** Returns          BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise
-**
-*******************************************************************************/
-bt_status_t btc_storage_load_bonded_ble_devices(void)
-{
-    bt_status_t status;
-    status = btc_in_fetch_bonded_ble_devices(1);
-    LOG_DEBUG("Storage load rslt %d\n", status);
-    return status;
-}
-
-bt_status_t btc_in_fetch_bonded_ble_devices(int add)
+static void _btc_storage_save(void)
 {
-    bt_status_t status = BT_STATUS_FAIL;
-    int device_type = 0;
-    for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end();
-            iter = btc_config_section_next(iter)) {
-        const char *name = btc_config_section_name(iter);
-        if (!string_is_bdaddr(name) ||
-            !btc_config_get_int(name, BTC_LE_DEV_TYPE, &device_type) ||
-            ((device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) {
-            continue;
-        }
-        LOG_DEBUG("%s, name = %s", __func__, name);
-        if (btc_in_fetch_bonded_ble_device(name, add, &bonded_devices) != BT_STATUS_SUCCESS) {
-            LOG_DEBUG("Remote device:%s, no link key or ble key found", name);
-        } else {
-            status = BT_STATUS_SUCCESS;
-        }
-    }
+    const btc_config_section_iter_t *iter = btc_config_section_begin();
 
-    return status;
-}
+    while (iter != btc_config_section_end()) {
+        //store the next iter, if remove section, then will not loss the point
 
-bt_status_t btc_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev)
-{
-    bt_bdaddr_t bd_addr;
-    int device_type = 0;
-    char buffer[sizeof(tBTM_LE_KEY_VALUE)] = {0};
-    for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end();
-            iter = btc_config_section_next(iter)) {
-        const char *name = btc_config_section_name(iter);
-        if (!string_is_bdaddr(name) ||
-            !btc_config_get_int(name, BTC_LE_DEV_TYPE, &device_type) ||
-            ((device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) {
+        const char *section = btc_config_section_name(iter);
+        if (!string_is_bdaddr(section)) {
+            iter = btc_config_section_next(iter);
             continue;
         }
 
-        string_to_bdaddr(name, &bd_addr);
-        memcpy(bond_dev->bd_addr, bd_addr.address, sizeof(bt_bdaddr_t));
-        //resolve the peer device long term key
-        if (btc_storage_get_ble_bonding_key(&bd_addr, BTM_LE_KEY_PENC, buffer, sizeof(tBTM_LE_PENC_KEYS))
-            == BT_STATUS_SUCCESS) {
-            bond_dev->bond_key.key_mask |= ESP_BLE_ENC_KEY_MASK;
-            memcpy(&bond_dev->bond_key.penc_key, buffer, sizeof(tBTM_LE_PENC_KEYS));
-        }
-        //resolve the peer device csrk
-        if (btc_storage_get_ble_bonding_key(&bd_addr, BTM_LE_KEY_PCSRK, buffer, sizeof(tBTM_LE_PCSRK_KEYS))
-            == BT_STATUS_SUCCESS) {
-            bond_dev->bond_key.key_mask |= ESP_BLE_CSR_KEY_MASK;
-            memcpy(&bond_dev->bond_key.pcsrk_key, buffer, sizeof(tBTM_LE_PCSRK_KEYS));
-        }
-        //resolve the peer device irk
-        if (btc_storage_get_ble_bonding_key(&bd_addr, BTM_LE_KEY_PID, buffer, sizeof(tBTM_LE_PID_KEYS))
-            == BT_STATUS_SUCCESS) {
-            bond_dev->bond_key.key_mask |= ESP_BLE_ID_KEY_MASK;
-            memcpy(&bond_dev->bond_key.pid_key, buffer, sizeof(tBTM_LE_PID_KEYS));
+        if (!btc_config_exist(section, BTC_BLE_STORAGE_DEV_TYPE_STR) && 
+                !btc_config_exist(section, BTC_BLE_STORAGE_ADDR_TYPE_STR) &&
+                !btc_config_exist(section, BTC_BLE_STORAGE_LINK_KEY_STR) &&
+                !btc_config_exist(section, BTC_BLE_STORAGE_LE_KEY_PENC_STR) &&
+                !btc_config_exist(section, BTC_BLE_STORAGE_LE_KEY_PID_STR) &&
+                !btc_config_exist(section, BTC_BLE_STORAGE_LE_KEY_PCSRK_STR) &&
+                !btc_config_exist(section, BTC_BLE_STORAGE_LE_KEY_LENC_STR) &&
+                !btc_config_exist(section, BTC_BLE_STORAGE_LE_KEY_LCSRK_STR)) {
+            iter = btc_config_section_next(iter);
+            btc_config_remove_section(section);
+            continue;
         }
-        //serch for the next bond device
-        bond_dev++;
-    }
-
-    return BT_STATUS_SUCCESS;
-}
-
-void btc_dm_remove_ble_bonding_keys(void)
-{
-    bt_bdaddr_t bd_addr;
-    LOG_DEBUG("%s\n",__func__);
-
-    bdcpy(bd_addr.address, pairing_cb.bd_addr);
-    btc_storage_remove_ble_bonding_keys(&bd_addr);
-}
-
-void btc_save_ble_bonding_keys(void)
-{
-    bt_bdaddr_t bd_addr;
-
-    bdcpy(bd_addr.address, pairing_cb.bd_addr);
-    bdstr_t bdstr;
-    bdaddr_to_string(&bd_addr, bdstr, sizeof(bdstr));
-    btc_config_set_int(bdstr, BTC_LE_DEV_TYPE, BT_DEVICE_TYPE_BLE);
-    LOG_DEBUG("%s, penc = %d, pid = %d", __func__, pairing_cb.ble.is_penc_key_rcvd, pairing_cb.ble.is_pid_key_rcvd);
-    if (pairing_cb.ble.is_penc_key_rcvd) {
-        btc_storage_add_ble_bonding_key(&bd_addr,
-                                        (char *) &pairing_cb.ble.penc_key,
-                                        BTM_LE_KEY_PENC,
-                                        sizeof(tBTM_LE_PENC_KEYS));
-    }
-
-    if (pairing_cb.ble.is_pid_key_rcvd) {
-        btc_storage_add_ble_bonding_key(&bd_addr,
-                                        (char *) &pairing_cb.ble.pid_key,
-                                        BTM_LE_KEY_PID,
-                                        sizeof(tBTM_LE_PID_KEYS));
-    }
-
-
-    if (pairing_cb.ble.is_pcsrk_key_rcvd) {
-        btc_storage_add_ble_bonding_key(&bd_addr,
-                                        (char *) &pairing_cb.ble.pcsrk_key,
-                                        BTM_LE_KEY_PCSRK,
-                                        sizeof(tBTM_LE_PCSRK_KEYS));
-    }
-
-
-    if (pairing_cb.ble.is_lenc_key_rcvd) {
-        btc_storage_add_ble_bonding_key(&bd_addr,
-                                        (char *) &pairing_cb.ble.lenc_key,
-                                        BTM_LE_KEY_LENC,
-                                        sizeof(tBTM_LE_LENC_KEYS));
-    }
 
-    if (pairing_cb.ble.is_lcsrk_key_rcvd) {
-        btc_storage_add_ble_bonding_key(&bd_addr,
-                                        (char *) &pairing_cb.ble.lcsrk_key,
-                                        BTM_LE_KEY_LCSRK,
-                                        sizeof(tBTM_LE_LCSRK_KEYS));
+        iter = btc_config_section_next(iter);
     }
 
-    if (pairing_cb.ble.is_lidk_key_rcvd) {
-        btc_storage_add_ble_bonding_key(&bd_addr,
-                                        NULL,
-                                        BTM_LE_KEY_LID,
-                                        0);
-    }
+    btc_config_flush();
 }
 
-static void btc_read_le_key(const uint8_t key_type, const size_t key_len, bt_bdaddr_t bd_addr,
-                 const uint8_t addr_type, const bool add_key, bool *device_added, bool *key_found)
+void btc_storage_save(void)
 {
-    assert(device_added);
-    assert(key_found);
-
-    char buffer[100];
-    memset(buffer, 0, sizeof(buffer));
-    if (btc_storage_get_ble_bonding_key(&bd_addr, key_type, buffer, key_len) == BT_STATUS_SUCCESS) {
-        if (add_key) {
-            BD_ADDR bta_bd_addr;
-            bdcpy(bta_bd_addr, bd_addr.address);
-
-            if (!*device_added) {
-                BTA_DmAddBleDevice(bta_bd_addr, addr_type, BT_DEVICE_TYPE_BLE);
-                *device_added = true;
-            }
-
-            char bd_str[20] = {0};
-            LOG_DEBUG("%s() Adding key type %d for %s", __func__,
-                key_type, bdaddr_to_string(&bd_addr, bd_str, sizeof(bd_str)));
-            BTA_DmAddBleKey(bta_bd_addr, (tBTA_LE_KEY_VALUE *)buffer, key_type);
-        }
-
-        *key_found = true;
-    }
+    btc_config_lock();
+    _btc_storage_save();
+    btc_config_unlock();
 }
 
-bt_status_t btc_storage_add_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
+static bt_status_t _btc_storage_add_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
                                             char *key,
                                             uint8_t key_type,
                                             uint8_t key_length)
@@ -211,34 +70,48 @@ bt_status_t btc_storage_add_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
     bdstr_t bdstr;
     bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
     const char* name;
+
     switch (key_type) {
     case BTM_LE_KEY_PENC:
-        name = "LE_KEY_PENC";
+        name = BTC_BLE_STORAGE_LE_KEY_PENC_STR;
         break;
     case BTM_LE_KEY_PID:
-        name = "LE_KEY_PID";
+        name = BTC_BLE_STORAGE_LE_KEY_PID_STR;
         break;
     case BTM_LE_KEY_PCSRK:
-        name = "LE_KEY_PCSRK";
+        name = BTC_BLE_STORAGE_LE_KEY_PCSRK_STR;
         break;
     case BTM_LE_KEY_LENC:
-        name = "LE_KEY_LENC";
+        name = BTC_BLE_STORAGE_LE_KEY_LENC_STR;
         break;
     case BTM_LE_KEY_LCSRK:
-        name = "LE_KEY_LCSRK";
+        name = BTC_BLE_STORAGE_LE_KEY_LCSRK_STR;
         break;
     case BTM_LE_KEY_LID:
-        name = "LE_KEY_LID";
+        name = BTC_BLE_STORAGE_LE_KEY_LID_STR;
         break;
     default:
         return BT_STATUS_FAIL;
     }
 
     int ret = btc_config_set_bin(bdstr, name, (const uint8_t *)key, key_length);
-    btc_config_save();
+    _btc_storage_save();
     return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
 }
 
+bt_status_t btc_storage_add_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
+                                            char *key,
+                                            uint8_t key_type,
+                                            uint8_t key_length)
+{
+    bt_status_t ret;
+
+    btc_config_lock();
+    ret = _btc_storage_add_ble_bonding_key(remote_bd_addr, key, key_type, key_length);
+    btc_config_unlock();
+
+    return ret;
+}
 
 /*******************************************************************************
 **
@@ -250,7 +123,7 @@ bt_status_t btc_storage_add_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
 **                  BT_STATUS_FAIL otherwise
 **
 *******************************************************************************/
-bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
+static bt_status_t _btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
                                             uint8_t key_type,
                                             char *key_value,
                                             int key_length)
@@ -260,22 +133,22 @@ bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
     const char* name;
     switch (key_type) {
     case BTM_LE_KEY_PENC:
-        name = "LE_KEY_PENC";
+        name = BTC_BLE_STORAGE_LE_KEY_PENC_STR;
         break;
     case BTM_LE_KEY_PID:
-        name = "LE_KEY_PID";
+        name = BTC_BLE_STORAGE_LE_KEY_PID_STR;
         break;
     case BTM_LE_KEY_PCSRK:
-        name = "LE_KEY_PCSRK";
+        name = BTC_BLE_STORAGE_LE_KEY_PCSRK_STR;
         break;
     case BTM_LE_KEY_LENC:
-        name = "LE_KEY_LENC";
+        name = BTC_BLE_STORAGE_LE_KEY_LENC_STR;
         break;
     case BTM_LE_KEY_LCSRK:
-        name = "LE_KEY_LCSRK";
+        name = BTC_BLE_STORAGE_LE_KEY_LCSRK_STR;
         break;
     case BTM_LE_KEY_LID:
-        name =  "LE_KEY_LID";
+        name =  BTC_BLE_STORAGE_LE_KEY_LID_STR;
     default:
         return BT_STATUS_FAIL;
     }
@@ -285,37 +158,19 @@ bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
 
 }
 
-bool btc_storage_compare_address_key_value(bt_bdaddr_t *remote_bd_addr,
-                                                   uint8_t key_type, void *key_value, int key_length)
+bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
+                                            uint8_t key_type,
+                                            char *key_value,
+                                            int key_length)
 {
-    bdstr_t bdstr;
-    bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
-    char *key_type_str;
-    switch (key_type) {
-    case BTM_LE_KEY_PENC:
-        key_type_str = "LE_KEY_PENC";
-        break;
-    case BTM_LE_KEY_PID:
-        key_type_str = "LE_KEY_PID";
-        break;
-    case BTM_LE_KEY_PCSRK:
-        key_type_str = "LE_KEY_PCSRK";
-        break;
-    case BTM_LE_KEY_LENC:
-        key_type_str = "LE_KEY_LENC";
-        break;
-    case BTM_LE_KEY_LCSRK:
-        key_type_str = "LE_KEY_LCSRK";
-        break;
-    case BTM_LE_KEY_LID:
-        key_type_str =  "LE_KEY_LID";
-    default:
-        return false;
-    }
+    bt_status_t ret;
 
-    return btc_compare_address_key_value(bdstr, key_type_str, key_value, key_length);
-}
+    btc_config_lock();
+    ret = _btc_storage_get_ble_bonding_key(remote_bd_addr, key_type, key_value, key_length);
+    btc_config_unlock();
 
+    return ret;
+}
 
 /*******************************************************************************
 **
@@ -327,70 +182,46 @@ bool btc_storage_compare_address_key_value(bt_bdaddr_t *remote_bd_addr,
 **                  BT_STATUS_FAIL otherwise
 **
 *******************************************************************************/
-bt_status_t btc_storage_remove_ble_bonding_keys(bt_bdaddr_t *remote_bd_addr)
+static bt_status_t _btc_storage_remove_ble_bonding_keys(bt_bdaddr_t *remote_bd_addr)
 {
+    int ret = 1;
     bdstr_t bdstr;
     bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
+
     BTIF_TRACE_DEBUG(" %s in bd addr:%s",__FUNCTION__, bdstr);
-    int ret = 1;
-    if (btc_config_exist(bdstr, BTC_LE_DEV_TYPE)) {
-        ret &= btc_config_remove(bdstr, BTC_LE_DEV_TYPE);
+
+    if (btc_config_exist(bdstr, BTC_BLE_STORAGE_ADDR_TYPE_STR)) {
+        ret &= btc_config_remove(bdstr, BTC_BLE_STORAGE_ADDR_TYPE_STR);
     }
-    if (btc_config_exist(bdstr, "LE_KEY_PENC")) {
-        ret &= btc_config_remove(bdstr, "LE_KEY_PENC");
+    if (btc_config_exist(bdstr, BTC_BLE_STORAGE_LE_KEY_PENC_STR)) {
+        ret &= btc_config_remove(bdstr, BTC_BLE_STORAGE_LE_KEY_PENC_STR);
     }
-    if (btc_config_exist(bdstr, "LE_KEY_PID")) {
-        ret &= btc_config_remove(bdstr, "LE_KEY_PID");
+    if (btc_config_exist(bdstr, BTC_BLE_STORAGE_LE_KEY_PID_STR)) {
+        ret &= btc_config_remove(bdstr, BTC_BLE_STORAGE_LE_KEY_PID_STR);
     }
-    if (btc_config_exist(bdstr, "LE_KEY_PCSRK")) {
-        ret &= btc_config_remove(bdstr, "LE_KEY_PCSRK");
+    if (btc_config_exist(bdstr, BTC_BLE_STORAGE_LE_KEY_PCSRK_STR)) {
+        ret &= btc_config_remove(bdstr, BTC_BLE_STORAGE_LE_KEY_PCSRK_STR);
     }
-    if (btc_config_exist(bdstr, "LE_KEY_LENC")) {
-        ret &= btc_config_remove(bdstr, "LE_KEY_LENC");
+    if (btc_config_exist(bdstr, BTC_BLE_STORAGE_LE_KEY_LENC_STR)) {
+        ret &= btc_config_remove(bdstr, BTC_BLE_STORAGE_LE_KEY_LENC_STR);
     }
-    if (btc_config_exist(bdstr, "LE_KEY_LCSRK")) {
-        ret &= btc_config_remove(bdstr, "LE_KEY_LCSRK");
+    if (btc_config_exist(bdstr, BTC_BLE_STORAGE_LE_KEY_LCSRK_STR)) {
+        ret &= btc_config_remove(bdstr, BTC_BLE_STORAGE_LE_KEY_LCSRK_STR);
     }
-    //remove the address information after delete the ble key.
-    ret = btc_config_remove_section(bdstr);
-    btc_config_save();
+    //here don't remove section, because config_save will check it
+    _btc_storage_save();
     return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
 }
 
-bt_status_t btc_storage_clear_bond_devices(void)
+bt_status_t btc_storage_remove_ble_bonding_keys(bt_bdaddr_t *remote_bd_addr)
 {
-    bt_bdaddr_t bd_addr;
-    int device_type = 0;
-    for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end();
-            iter = btc_config_section_next(iter)) {
-        const char *name = btc_config_section_name(iter);
-        if (!string_is_bdaddr(name) &&
-            !btc_config_get_int(name, BTC_LE_DEV_TYPE, &device_type) &&
-            ((device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) {
-            continue;
-        }
+    bt_status_t ret;
 
-        string_to_bdaddr(name, &bd_addr);
-        //remove the ble bonding keys from the config and then save the config to the flash
-        if (btc_storage_remove_ble_bonding_keys(&bd_addr) != BT_STATUS_SUCCESS) {
-            LOG_ERROR("%s, remove bonding key faild", __func__);
-            return BT_STATUS_FAIL;
-        }
-        // the bonded_devices Structure record the devices which has been added to the BTM layer global variable
-        for (int i = 0; i < bonded_devices.num_devices; i++) {
-            //if the address is equal to the record device address, remove it from the BTM layer global variable
-            if (!memcmp(bd_addr.address, bonded_devices.devices[i].address, sizeof(bt_bdaddr_t))) {
-                BD_ADDR bta_addr;
-                memcpy(bta_addr, bd_addr.address, sizeof(BD_ADDR));
-                if(BTA_DmRemoveDevice(bta_addr) != BTA_SUCCESS) {
-                    LOG_ERROR("%s, remove device faild", __func__);
-                    return BT_STATUS_FAIL;
-                }
-            }
-        }
-    }
+    btc_config_lock();
+    ret = _btc_storage_remove_ble_bonding_keys(remote_bd_addr);
+    btc_config_unlock();
 
-    return BT_STATUS_SUCCESS;
+    return ret;
 }
 
 /*******************************************************************************
@@ -403,32 +234,46 @@ bt_status_t btc_storage_clear_bond_devices(void)
 **                  BT_STATUS_FAIL otherwise
 **
 *******************************************************************************/
-bt_status_t btc_storage_add_ble_local_key(char *key,
+static bt_status_t _btc_storage_add_ble_local_key(char *key,
                                           uint8_t key_type,
                                           uint8_t key_length)
 {
     const char* name;
     switch (key_type) {
     case BTC_LE_LOCAL_KEY_IR:
-        name = "LE_LOCAL_KEY_IR";
+        name = BTC_BLE_STORAGE_LE_LOCAL_KEY_IR_STR;
         break;
     case BTC_LE_LOCAL_KEY_IRK:
-        name = "LE_LOCAL_KEY_IRK";
+        name = BTC_BLE_STORAGE_LE_LOCAL_KEY_IRK_STR;
         break;
     case BTC_LE_LOCAL_KEY_DHK:
-        name = "LE_LOCAL_KEY_DHK";
+        name = BTC_BLE_STORAGE_LE_LOCAL_KEY_DHK_STR;
         break;
     case BTC_LE_LOCAL_KEY_ER:
-        name = "LE_LOCAL_KEY_ER";
+        name = BTC_BLE_STORAGE_LE_LOCAL_KEY_ER_STR;
         break;
     default:
         return BT_STATUS_FAIL;
     }
-    int ret = btc_config_set_bin("Adapter", name, (const uint8_t *)key, key_length);
-    btc_config_save();
+
+    int ret = btc_config_set_bin(BTC_BLE_STORAGE_LOCAL_ADAPTER_STR, name, (const uint8_t *)key, key_length);
+    _btc_storage_save();
     return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
 }
 
+bt_status_t btc_storage_add_ble_local_key(char *key,
+                                          uint8_t key_type,
+                                          uint8_t key_length)
+{
+    bt_status_t ret;
+
+    btc_config_lock();
+    ret = _btc_storage_add_ble_local_key(key, key_type, key_length);
+    btc_config_unlock();
+
+    return ret;
+}
+
 /*******************************************************************************
 **
 ** Function         btc_storage_get_ble_local_key
@@ -439,32 +284,47 @@ bt_status_t btc_storage_add_ble_local_key(char *key,
 **                  BT_STATUS_FAIL otherwise
 **
 *******************************************************************************/
-bt_status_t btc_storage_get_ble_local_key(uint8_t key_type,
+static bt_status_t _btc_storage_get_ble_local_key(uint8_t key_type,
                                           char *key_value,
                                           int key_length)
 {
     const char* name;
     switch (key_type) {
     case BTC_LE_LOCAL_KEY_IR:
-        name = "LE_LOCAL_KEY_IR";
+        name = BTC_BLE_STORAGE_LE_LOCAL_KEY_IR_STR;
         break;
     case BTC_LE_LOCAL_KEY_IRK:
-        name = "LE_LOCAL_KEY_IRK";
+        name = BTC_BLE_STORAGE_LE_LOCAL_KEY_IRK_STR;
         break;
     case BTC_LE_LOCAL_KEY_DHK:
-        name = "LE_LOCAL_KEY_DHK";
+        name = BTC_BLE_STORAGE_LE_LOCAL_KEY_DHK_STR;
         break;
     case BTC_LE_LOCAL_KEY_ER:
-        name = "LE_LOCAL_KEY_ER";
+        name = BTC_BLE_STORAGE_LE_LOCAL_KEY_ER_STR;
         break;
     default:
         return BT_STATUS_FAIL;
     }
     size_t length = key_length;
-    int ret = btc_config_get_bin("Adapter", name, (uint8_t *)key_value, &length);
+
+    int ret = btc_config_get_bin(BTC_BLE_STORAGE_LOCAL_ADAPTER_STR, name, (uint8_t *)key_value, &length);
+
     return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
 }
 
+bt_status_t btc_storage_get_ble_local_key(uint8_t key_type,
+                                          char *key_value,
+                                          int key_length)
+{
+    bt_status_t ret;
+
+    btc_config_lock();
+    ret = _btc_storage_get_ble_local_key(key_type, key_value, key_length);
+    btc_config_unlock();
+
+    return ret;
+}
+
 /*******************************************************************************
 **
 ** Function         btc_storage_remove_ble_local_keys
@@ -475,37 +335,314 @@ bt_status_t btc_storage_get_ble_local_key(uint8_t key_type,
 **                  BT_STATUS_FAIL otherwise
 **
 *******************************************************************************/
-bt_status_t btc_storage_remove_ble_local_keys(void)
+static bt_status_t _btc_storage_remove_ble_local_keys(void)
 {
     int ret = 1;
-    if (btc_config_exist("Adapter", "LE_LOCAL_KEY_IR")) {
-        ret &= btc_config_remove("Adapter", "LE_LOCAL_KEY_IR");
+
+    if (btc_config_exist(BTC_BLE_STORAGE_LOCAL_ADAPTER_STR, BTC_BLE_STORAGE_LE_LOCAL_KEY_IR_STR)) {
+        ret &= btc_config_remove(BTC_BLE_STORAGE_LOCAL_ADAPTER_STR, BTC_BLE_STORAGE_LE_LOCAL_KEY_IR_STR);
+    }
+    if (btc_config_exist(BTC_BLE_STORAGE_LOCAL_ADAPTER_STR, BTC_BLE_STORAGE_LE_LOCAL_KEY_IRK_STR)) {
+        ret &= btc_config_remove(BTC_BLE_STORAGE_LOCAL_ADAPTER_STR, BTC_BLE_STORAGE_LE_LOCAL_KEY_IRK_STR);
+    }
+    if (btc_config_exist(BTC_BLE_STORAGE_LOCAL_ADAPTER_STR, BTC_BLE_STORAGE_LE_LOCAL_KEY_DHK_STR)) {
+        ret &= btc_config_remove(BTC_BLE_STORAGE_LOCAL_ADAPTER_STR, BTC_BLE_STORAGE_LE_LOCAL_KEY_DHK_STR);
+    }
+    if (btc_config_exist(BTC_BLE_STORAGE_LOCAL_ADAPTER_STR, BTC_BLE_STORAGE_LE_LOCAL_KEY_ER_STR)) {
+        ret &= btc_config_remove(BTC_BLE_STORAGE_LOCAL_ADAPTER_STR, BTC_BLE_STORAGE_LE_LOCAL_KEY_ER_STR);
+    }
+    _btc_storage_save();
+
+    return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
+}
+
+bt_status_t btc_storage_remove_ble_local_keys(void)
+{
+    bt_status_t ret;
+
+    btc_config_lock();
+    ret = _btc_storage_remove_ble_local_keys();
+    btc_config_unlock();
+
+    return ret;
+}
+
+bool _btc_storage_compare_address_key_value(bt_bdaddr_t *remote_bd_addr,
+                                                   uint8_t key_type, void *key_value, int key_length)
+{
+    bdstr_t bdstr;
+    bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
+    char *key_type_str;
+    switch (key_type) {
+    case BTM_LE_KEY_PENC:
+        key_type_str = BTC_BLE_STORAGE_LE_KEY_PENC_STR;
+        break;
+    case BTM_LE_KEY_PID:
+        key_type_str = BTC_BLE_STORAGE_LE_KEY_PID_STR;
+        break;
+    case BTM_LE_KEY_PCSRK:
+        key_type_str = BTC_BLE_STORAGE_LE_KEY_PCSRK_STR;
+        break;
+    case BTM_LE_KEY_LENC:
+        key_type_str = BTC_BLE_STORAGE_LE_KEY_LENC_STR;
+        break;
+    case BTM_LE_KEY_LCSRK:
+        key_type_str = BTC_BLE_STORAGE_LE_KEY_LCSRK_STR;
+        break;
+    case BTM_LE_KEY_LID:
+        key_type_str =  BTC_BLE_STORAGE_LE_KEY_LID_STR;
+    default:
+        return false;
+    }
+
+    return btc_compare_address_key_value(bdstr, key_type_str, key_value, key_length);
+}
+
+bool btc_storage_compare_address_key_value(bt_bdaddr_t *remote_bd_addr,
+                                                   uint8_t key_type, void *key_value, int key_length)
+{
+    bool ret;
+
+    btc_config_lock();
+    ret = _btc_storage_compare_address_key_value(remote_bd_addr, key_type, key_value, key_length);
+    btc_config_unlock();
+
+    return ret;
+}
+
+static bt_status_t _btc_storage_set_ble_dev_type(bt_bdaddr_t *bd_addr, bool flush)
+{
+    bool ret = 1;
+    bdstr_t bdstr;
+    uint32_t dev_type = 0;
+
+    bdaddr_to_string(bd_addr, bdstr, sizeof(bdstr));
+
+    btc_config_get_int(bdstr, BTC_BLE_STORAGE_DEV_TYPE_STR, (int *)&dev_type);
+    ret = btc_config_set_int(bdstr, BTC_BLE_STORAGE_DEV_TYPE_STR, BT_DEVICE_TYPE_BLE|dev_type);
+    if (ret == false) {
+        return BT_STATUS_FAIL;
+    }
+
+    if (flush) {
+        _btc_storage_save();
+    }
+
+    return BT_STATUS_SUCCESS;
+}
+
+bt_status_t btc_storage_set_ble_dev_type(bt_bdaddr_t *bd_addr, bool flush)
+{
+    bt_status_t ret;
+
+    btc_config_lock();
+    ret = _btc_storage_set_ble_dev_type(bd_addr, flush);
+    btc_config_unlock();
+
+    return ret;
+}
+
+static bool _btc_storage_get_ble_dev_type(bt_bdaddr_t *bd_addr)
+{
+    bool ret = 1;
+    bdstr_t bdstr;
+    uint32_t dev_type = 0;
+
+    bdaddr_to_string(bd_addr, bdstr, sizeof(bdstr));
+
+    BTIF_TRACE_DEBUG(" %s in bd addr:%s",__FUNCTION__, bdstr);
+
+    ret = btc_config_get_int(bdstr, BTC_BLE_STORAGE_DEV_TYPE_STR, (int *)&dev_type);
+    if (ret == false) {
+        return false;
     }
-    if (btc_config_exist("Adapter", "LE_LOCAL_KEY_IRK")) {
-        ret &= btc_config_remove("Adapter", "LE_LOCAL_KEY_IRK");
+
+    return (dev_type & BT_DEVICE_TYPE_BLE);
+}
+
+bool btc_storage_get_ble_dev_type(bt_bdaddr_t *bd_addr)
+{
+    bt_status_t ret;
+
+    btc_config_lock();
+    ret = _btc_storage_get_ble_dev_type(bd_addr);
+    btc_config_unlock();
+
+    return ret;
+}
+
+
+static bt_status_t _btc_storage_remove_ble_dev_type(bt_bdaddr_t *remote_bd_addr, bool flush)
+{
+    bool ret = true;
+    bdstr_t bdstr;
+    uint32_t dev_type = 0;
+
+    bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
+
+    BTIF_TRACE_DEBUG(" %s in bd addr:%s",__FUNCTION__, bdstr);
+
+    ret = btc_config_get_int(bdstr, BTC_BLE_STORAGE_DEV_TYPE_STR, (int *)&dev_type);
+    if (ret == false) {
+        //cannot find the key, just return SUCCESS, indicate already removed
+        return BT_STATUS_SUCCESS;
     }
-    if (btc_config_exist("Adapter", "LE_LOCAL_KEY_DHK")) {
-        ret &= btc_config_remove("Adapter", "LE_LOCAL_KEY_DHK");
+
+    if (dev_type == BT_DEVICE_TYPE_DUMO) {
+        ret = btc_config_set_int(bdstr, BTC_BLE_STORAGE_DEV_TYPE_STR, BT_DEVICE_TYPE_BREDR);
+    } else if (dev_type == BT_DEVICE_TYPE_BLE) {
+        ret = btc_config_remove(bdstr, BTC_BLE_STORAGE_DEV_TYPE_STR);
     }
-    if (btc_config_exist("Adapter", "LE_LOCAL_KEY_ER")) {
-        ret &= btc_config_remove("Adapter", "LE_LOCAL_KEY_ER");
+
+    if (ret == false) {
+        return BT_STATUS_FAIL;
     }
-    btc_config_save();
+
+    if (flush) {
+        _btc_storage_save();
+    }
+
+    return BT_STATUS_SUCCESS;
+}
+
+bt_status_t btc_storage_remove_ble_dev_type(bt_bdaddr_t *remote_bd_addr, bool flush)
+{
+    bt_status_t ret;
+
+    btc_config_lock();
+    ret = _btc_storage_remove_ble_dev_type(remote_bd_addr, flush);
+    btc_config_unlock();
+
+    return ret;
+}
+
+static bt_status_t _btc_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr, uint8_t addr_type, bool flush)
+{
+    int ret;
+    bdstr_t bdstr;
+
+    bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr_t));
+    ret = btc_config_set_int(bdstr, BTC_BLE_STORAGE_ADDR_TYPE_STR, (int)addr_type);
+    if (ret == false) {
+        return BT_STATUS_FAIL;
+    }
+
+    if (flush) {
+        _btc_storage_save();
+    }
+
+    return BT_STATUS_SUCCESS;
+}
+
+bt_status_t btc_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr, uint8_t addr_type, bool flush)
+{
+    bt_status_t ret;
+
+    btc_config_lock();
+    ret = _btc_storage_set_remote_addr_type(remote_bd_addr, addr_type, flush);
+    btc_config_unlock();
+
+    return ret;
+}
+
+static bt_status_t _btc_storage_remove_remote_addr_type(bt_bdaddr_t *remote_bd_addr, bool flush)
+{
+    bool ret = true;
+    bdstr_t bdstr;
+    uint32_t dev_type = 0;
+
+    bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
+
+    ret = btc_config_get_int(bdstr, BTC_BLE_STORAGE_ADDR_TYPE_STR, (int *)&dev_type);
+    if (ret == false) {
+        //cannot find the key, just return SUCCESS, indicate already removed
+        return BT_STATUS_SUCCESS;
+    }
+
+    ret = btc_config_remove(bdstr, BTC_BLE_STORAGE_ADDR_TYPE_STR);
+    if (ret == false) {
+        return BT_STATUS_FAIL;
+    }
+
+    if (flush) {
+        _btc_storage_save();
+    }
+
+    return  BT_STATUS_SUCCESS;
+}
+
+bt_status_t btc_storage_remove_remote_addr_type(bt_bdaddr_t *remote_bd_addr, bool flush)
+{
+    bt_status_t ret;
+
+    btc_config_lock();
+    ret = _btc_storage_remove_remote_addr_type(remote_bd_addr, flush);
+    btc_config_unlock();
+
+    return ret;
+}
+
+static bt_status_t _btc_storage_get_remote_addr_type(bt_bdaddr_t *remote_bd_addr,
+                                             int*addr_type)
+{
+    bdstr_t bdstr;
+    bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
+    int ret = btc_config_get_int(bdstr, BTC_BLE_STORAGE_ADDR_TYPE_STR, addr_type);
     return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
 }
 
+bt_status_t btc_storage_get_remote_addr_type(bt_bdaddr_t *remote_bd_addr,
+                                             int*addr_type)
+{
+    bt_status_t ret;
+
+    btc_config_lock();
+    ret = _btc_storage_get_remote_addr_type(remote_bd_addr, addr_type);
+    btc_config_unlock();
+
+    return ret;
+}
+
+static void _btc_read_le_key(const uint8_t key_type, const size_t key_len, bt_bdaddr_t bd_addr,
+                 const uint8_t addr_type, const bool add_key, bool *device_added, bool *key_found)
+{
+    assert(device_added);
+    assert(key_found);
+
+    char buffer[100];
+    memset(buffer, 0, sizeof(buffer));
+
+    bt_status_t ret = _btc_storage_get_ble_bonding_key(&bd_addr, key_type, buffer, key_len);
+
+    if (ret == BT_STATUS_SUCCESS) {
+        if (add_key) {
+            BD_ADDR bta_bd_addr;
+            bdcpy(bta_bd_addr, bd_addr.address);
+
+            if (!*device_added) {
+                BTA_DmAddBleDevice(bta_bd_addr, addr_type, BT_DEVICE_TYPE_BLE);
+                *device_added = true;
+            }
+
+            char bd_str[20] = {0};
+            LOG_DEBUG("%s() Adding key type %d for %s", __func__,
+                key_type, bdaddr_to_string(&bd_addr, bd_str, sizeof(bd_str)));
+            BTA_DmAddBleKey(bta_bd_addr, (tBTA_LE_KEY_VALUE *)buffer, key_type);
+        }
 
-bt_status_t btc_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add, 
-                                           btc_bonded_devices_t *p_bonded_devices)
+        *key_found = true;
+    }
+}
+static bt_status_t _btc_storage_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add)
 {
-    int device_type;
+    uint32_t device_type;
     int addr_type;
     bt_bdaddr_t bd_addr;
     BD_ADDR bta_bd_addr;
     bool device_added = false;
     bool key_found = false;
 
-    if (!btc_config_get_int(remote_bd_addr, BTC_LE_DEV_TYPE, &device_type)) {
+    if (!btc_config_get_int(remote_bd_addr, BTC_BLE_STORAGE_DEV_TYPE_STR, (int *)&device_type)) {
         LOG_ERROR("%s, device_type = %x", __func__, device_type);
         return BT_STATUS_FAIL;
     }
@@ -513,36 +650,29 @@ bt_status_t btc_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add,
     string_to_bdaddr(remote_bd_addr, &bd_addr);
     bdcpy(bta_bd_addr, bd_addr.address);
 
-    if (btc_storage_get_remote_addr_type(&bd_addr, &addr_type) != BT_STATUS_SUCCESS) {
+    if (_btc_storage_get_remote_addr_type(&bd_addr, &addr_type) != BT_STATUS_SUCCESS) {
         addr_type = BLE_ADDR_PUBLIC;
-        btc_storage_set_remote_addr_type(&bd_addr, BLE_ADDR_PUBLIC);
+        _btc_storage_set_remote_addr_type(&bd_addr, BLE_ADDR_PUBLIC, true);
     }
 
-    btc_read_le_key(BTM_LE_KEY_PENC, sizeof(tBTM_LE_PENC_KEYS),
+    _btc_read_le_key(BTM_LE_KEY_PENC, sizeof(tBTM_LE_PENC_KEYS),
                     bd_addr, addr_type, add, &device_added, &key_found);
 
-    btc_read_le_key(BTM_LE_KEY_PID, sizeof(tBTM_LE_PID_KEYS),
+    _btc_read_le_key(BTM_LE_KEY_PID, sizeof(tBTM_LE_PID_KEYS),
                     bd_addr, addr_type, add, &device_added, &key_found);
 
-    btc_read_le_key(BTM_LE_KEY_LID, sizeof(tBTM_LE_PID_KEYS),
+    _btc_read_le_key(BTM_LE_KEY_LID, sizeof(tBTM_LE_PID_KEYS),
                     bd_addr, addr_type, add, &device_added, &key_found);
 
-    btc_read_le_key(BTM_LE_KEY_PCSRK, sizeof(tBTM_LE_PCSRK_KEYS),
+    _btc_read_le_key(BTM_LE_KEY_PCSRK, sizeof(tBTM_LE_PCSRK_KEYS),
                     bd_addr, addr_type, add, &device_added, &key_found);
 
-    btc_read_le_key(BTM_LE_KEY_LENC, sizeof(tBTM_LE_LENC_KEYS),
+    _btc_read_le_key(BTM_LE_KEY_LENC, sizeof(tBTM_LE_LENC_KEYS),
                     bd_addr, addr_type, add, &device_added, &key_found);
 
-    btc_read_le_key(BTM_LE_KEY_LCSRK, sizeof(tBTM_LE_LCSRK_KEYS),
+    _btc_read_le_key(BTM_LE_KEY_LCSRK, sizeof(tBTM_LE_LCSRK_KEYS),
                     bd_addr, addr_type, add, &device_added, &key_found);
 
-    // Fill in the bonded devices
-    if (device_added)
-    {
-        memcpy(&p_bonded_devices->devices[p_bonded_devices->num_devices++],
-               &bd_addr, sizeof(bt_bdaddr_t));
-    }
-
     if (key_found) {
         return BT_STATUS_SUCCESS;
     }
@@ -550,91 +680,120 @@ bt_status_t btc_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add,
     return BT_STATUS_FAIL;
 }
 
-bt_status_t btc_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr,
-        uint8_t addr_type)
+static bt_status_t btc_storage_in_fetch_bonded_ble_devices(int add)
 {
-    bdstr_t bdstr;
-    bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bt_bdaddr_t));
-    int ret = btc_config_set_int(bdstr, "AddrType", (int)addr_type);
-    btc_config_save();
-    return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
+    bt_status_t status = BT_STATUS_FAIL;
+    uint32_t device_type = 0;
+
+    btc_config_lock();
+    for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end();
+            iter = btc_config_section_next(iter)) {
+        const char *name = btc_config_section_name(iter);
+        
+        if (!string_is_bdaddr(name) ||
+            !btc_config_get_int(name, BTC_BLE_STORAGE_DEV_TYPE_STR, (int *)&device_type) ||
+            ((device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) {
+            continue;
+        }
+        LOG_DEBUG("%s, name = %s", __func__, name);
+        if (_btc_storage_in_fetch_bonded_ble_device(name, add) != BT_STATUS_SUCCESS) {
+            LOG_DEBUG("Remote device:%s, no link key or ble key found", name);
+        } else {
+            status = BT_STATUS_SUCCESS;
+        }
+    }
+    btc_config_unlock();
+
+    return status;
 }
 
 /*******************************************************************************
 **
-** Function         btc_storage_get_remote_addr_type
+** Function         btc_storage_load_bonded_devices
 **
-** Description      btc storage API - Fetches the remote addr type
+** Description      btc storage API - Loads all the bonded devices from NVRAM
+**                  and adds to the BTA.
+**                  Additionally, this API also invokes the adaper_properties_cb
+**                  and remote_device_properties_cb for each of the bonded devices.
 **
-** Returns          BT_STATUS_SUCCESS if the fetch was successful,
-**                      BT_STATUS_FAIL otherwise
+** Returns          BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise
 **
 *******************************************************************************/
-bt_status_t btc_storage_get_remote_addr_type(bt_bdaddr_t *remote_bd_addr,
-                                             int*addr_type)
+bt_status_t btc_storage_load_bonded_ble_devices(void)
 {
-    bdstr_t bdstr;
-    bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
-    int ret = btc_config_get_int(bdstr, "AddrType", addr_type);
-    return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
+    bt_status_t status;
+    status = btc_storage_in_fetch_bonded_ble_devices(1);
+    LOG_DEBUG("Storage load rslt %d\n", status);
+    return status;
 }
 
-int btc_storage_get_num_ble_bond_devices(void)
+bt_status_t btc_storage_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev, int dev_num)
 {
-    int num_dev = 0;
-    int device_type = 0;
+    bt_bdaddr_t bd_addr;
+    uint32_t device_type = 0;
+    char buffer[sizeof(tBTM_LE_KEY_VALUE)] = {0};
+
+    btc_config_lock();
     for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end();
             iter = btc_config_section_next(iter)) {
+
+        if (dev_num-- <= 0) {
+            break;
+        }
+
         const char *name = btc_config_section_name(iter);
-        if (!string_is_bdaddr(name) &&
-            !btc_config_get_int(name, BTC_LE_DEV_TYPE, &device_type) &&
-            device_type != BT_DEVICE_TYPE_BLE) {
+
+        if (!string_is_bdaddr(name) ||
+                !btc_config_get_int(name, BTC_BLE_STORAGE_DEV_TYPE_STR, (int *)&device_type) ||
+                !(device_type & BT_DEVICE_TYPE_BLE)) {
             continue;
         }
 
-        num_dev++;
+        string_to_bdaddr(name, &bd_addr);
+        memcpy(bond_dev->bd_addr, bd_addr.address, sizeof(bt_bdaddr_t));
+        //resolve the peer device long term key
+        if (_btc_storage_get_ble_bonding_key(&bd_addr, BTM_LE_KEY_PENC, buffer, sizeof(tBTM_LE_PENC_KEYS)) == BT_STATUS_SUCCESS) {
+            bond_dev->bond_key.key_mask |= ESP_BLE_ENC_KEY_MASK;
+            memcpy(&bond_dev->bond_key.penc_key, buffer, sizeof(tBTM_LE_PENC_KEYS));
+        }
+        //resolve the peer device csrk
+        if (_btc_storage_get_ble_bonding_key(&bd_addr, BTM_LE_KEY_PCSRK, buffer, sizeof(tBTM_LE_PCSRK_KEYS)) == BT_STATUS_SUCCESS) {
+            bond_dev->bond_key.key_mask |= ESP_BLE_CSR_KEY_MASK;
+            memcpy(&bond_dev->bond_key.pcsrk_key, buffer, sizeof(tBTM_LE_PCSRK_KEYS));
+        }
+        //resolve the peer device irk
+        if (_btc_storage_get_ble_bonding_key(&bd_addr, BTM_LE_KEY_PID, buffer, sizeof(tBTM_LE_PID_KEYS)) == BT_STATUS_SUCCESS) {
+            bond_dev->bond_key.key_mask |= ESP_BLE_ID_KEY_MASK;
+            memcpy(&bond_dev->bond_key.pid_key, buffer, sizeof(tBTM_LE_PID_KEYS));
+        }
+        //serch for the next bond device
+        bond_dev++;
     }
+    btc_config_unlock();
 
-    return num_dev;
+    return BT_STATUS_SUCCESS;
 }
 
-void btc_dm_load_ble_local_keys(void)
+int btc_storage_get_num_ble_bond_devices(void)
 {
-    memset(&ble_local_key_cb, 0, sizeof(btc_dm_local_key_cb_t));
-
-    if (btc_storage_get_ble_local_key(BTC_LE_LOCAL_KEY_ER,(char*)&ble_local_key_cb.er[0],
-                                      BT_OCTET16_LEN)== BT_STATUS_SUCCESS) {
-        ble_local_key_cb.is_er_rcvd = TRUE;
-        LOG_DEBUG("%s BLE ER key loaded",__func__ );
-    }
+    int num_dev = 0;
+    uint32_t device_type = 0;
 
-    if ((btc_storage_get_ble_local_key(BTC_LE_LOCAL_KEY_IR,(char*)&ble_local_key_cb.id_keys.ir[0],
-                                       BT_OCTET16_LEN)== BT_STATUS_SUCCESS )&&
-            (btc_storage_get_ble_local_key(BTC_LE_LOCAL_KEY_IRK, (char*)&ble_local_key_cb.id_keys.irk[0],
-                                           BT_OCTET16_LEN)== BT_STATUS_SUCCESS)&&
-            (btc_storage_get_ble_local_key(BTC_LE_LOCAL_KEY_DHK,(char*)&ble_local_key_cb.id_keys.dhk[0],
-                                           BT_OCTET16_LEN)== BT_STATUS_SUCCESS)) {
-        ble_local_key_cb.is_id_keys_rcvd = TRUE;
-        LOG_DEBUG("%s BLE ID keys loaded", __func__);
-    }
+    btc_config_lock();
+    for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end();
+            iter = btc_config_section_next(iter)) {
+        const char *name = btc_config_section_name(iter);
+        if (!string_is_bdaddr(name) ||
+                !btc_config_get_int(name, BTC_BLE_STORAGE_DEV_TYPE_STR, (int *)&device_type) ||
+                !(device_type & BT_DEVICE_TYPE_BLE)) {
+            continue;
+        }
 
-}
-void btc_dm_get_ble_local_keys(tBTA_DM_BLE_LOCAL_KEY_MASK *p_key_mask, BT_OCTET16 er,
-                               tBTA_BLE_LOCAL_ID_KEYS *p_id_keys)
-{
-    if (ble_local_key_cb.is_er_rcvd ) {
-        memcpy(&er[0], &ble_local_key_cb.er[0], sizeof(BT_OCTET16));
-        *p_key_mask |= BTA_BLE_LOCAL_KEY_TYPE_ER;
+        num_dev++;
     }
+    btc_config_unlock();
 
-    if (ble_local_key_cb.is_id_keys_rcvd) {
-        memcpy(&p_id_keys->ir[0], &ble_local_key_cb.id_keys.ir[0], sizeof(BT_OCTET16));
-        memcpy(&p_id_keys->irk[0],  &ble_local_key_cb.id_keys.irk[0], sizeof(BT_OCTET16));
-        memcpy(&p_id_keys->dhk[0],  &ble_local_key_cb.id_keys.dhk[0], sizeof(BT_OCTET16));
-        *p_key_mask |= BTA_BLE_LOCAL_KEY_TYPE_ID;
-    }
-    LOG_DEBUG("%s  *p_key_mask=0x%02x",__func__,   *p_key_mask);
+    return num_dev;
 }
-
 #endif  ///SMP_INCLUDED == TRUE
                                        
index 94738806461ab0914d125022a14cc273ef5b2aab..9249cfd8ff702ce26a38d0732136da0adef5fdae 100644 (file)
@@ -33,49 +33,6 @@ static const char *CONFIG_FILE_PATH = "bt_config.conf";
 static const period_ms_t CONFIG_SETTLE_PERIOD_MS = 3000;
 
 static void btc_key_value_to_string(uint8_t *key_vaule, char *value_str, int key_length);
-
-// TODO(zachoverflow): Move these two functions out, because they are too specific for this file
-// {grumpy-cat/no, monty-python/you-make-me-sad}
-bool btc_get_device_type(const BD_ADDR bd_addr, int *p_device_type)
-{
-    if (p_device_type == NULL) {
-        return FALSE;
-    }
-
-    bt_bdaddr_t bda;
-    bdcpy(bda.address, bd_addr);
-
-    bdstr_t bd_addr_str;
-    bdaddr_to_string(&bda, bd_addr_str, sizeof(bd_addr_str));
-
-    if (!btc_config_get_int(bd_addr_str, BTC_LE_DEV_TYPE, p_device_type)) {
-        return FALSE;
-    }
-
-    LOG_DEBUG("%s: Device [%s] type %d\n", __FUNCTION__, bd_addr_str, *p_device_type);
-    return TRUE;
-}
-
-bool btc_get_address_type(const BD_ADDR bd_addr, int *p_addr_type)
-{
-    if (p_addr_type == NULL) {
-        return FALSE;
-    }
-
-    bt_bdaddr_t bda;
-    bdcpy(bda.address, bd_addr);
-
-    bdstr_t bd_addr_str;
-    bdaddr_to_string(&bda, bd_addr_str, sizeof(bd_addr_str));
-
-    if (!btc_config_get_int(bd_addr_str, "AddrType", p_addr_type)) {
-        return FALSE;
-    }
-
-    LOG_DEBUG("%s: Device [%s] address type %d\n", __FUNCTION__, bd_addr_str, *p_addr_type);
-    return TRUE;
-}
-
 static osi_mutex_t lock;  // protects operations on |config|.
 static config_t *config;
 
@@ -88,11 +45,9 @@ bool btc_compare_address_key_value(const char *section, char *key_type, void *ke
         return false;
     }
     btc_key_value_to_string((uint8_t *)key_value, value_str, key_length);
-    osi_mutex_lock(&lock, OSI_MUTEX_MAX_TIMEOUT);
     if ((status = config_has_key_in_section(config, key_type, value_str)) == true) {
         config_remove_section(config, section);
     }
-    osi_mutex_unlock(&lock);
     return status;
 }
 
@@ -160,11 +115,7 @@ bool btc_config_has_section(const char *section)
     assert(config != NULL);
     assert(section != NULL);
 
-    osi_mutex_lock(&lock, OSI_MUTEX_MAX_TIMEOUT);
-    bool ret = config_has_section(config, section);
-    osi_mutex_unlock(&lock);
-
-    return ret;
+    return config_has_section(config, section);
 }
 
 bool btc_config_exist(const char *section, const char *key)
@@ -173,11 +124,7 @@ bool btc_config_exist(const char *section, const char *key)
     assert(section != NULL);
     assert(key != NULL);
 
-    osi_mutex_lock(&lock, OSI_MUTEX_MAX_TIMEOUT);
-    bool ret = config_has_key(config, section, key);
-    osi_mutex_unlock(&lock);
-
-    return ret;
+    return config_has_key(config, section, key);
 }
 
 bool btc_config_get_int(const char *section, const char *key, int *value)
@@ -187,12 +134,10 @@ bool btc_config_get_int(const char *section, const char *key, int *value)
     assert(key != NULL);
     assert(value != NULL);
 
-    osi_mutex_lock(&lock, OSI_MUTEX_MAX_TIMEOUT);
     bool ret = config_has_key(config, section, key);
     if (ret) {
         *value = config_get_int(config, section, key, *value);
     }
-    osi_mutex_unlock(&lock);
 
     return ret;
 }
@@ -203,9 +148,7 @@ bool btc_config_set_int(const char *section, const char *key, int value)
     assert(section != NULL);
     assert(key != NULL);
 
-    osi_mutex_lock(&lock, OSI_MUTEX_MAX_TIMEOUT);
     config_set_int(config, section, key, value);
-    osi_mutex_unlock(&lock);
 
     return true;
 }
@@ -218,9 +161,7 @@ bool btc_config_get_str(const char *section, const char *key, char *value, int *
     assert(value != NULL);
     assert(size_bytes != NULL);
 
-    osi_mutex_lock(&lock, OSI_MUTEX_MAX_TIMEOUT);
     const char *stored_value = config_get_string(config, section, key, NULL);
-    osi_mutex_unlock(&lock);
 
     if (!stored_value) {
         return false;
@@ -239,9 +180,7 @@ bool btc_config_set_str(const char *section, const char *key, const char *value)
     assert(key != NULL);
     assert(value != NULL);
 
-    osi_mutex_lock(&lock, OSI_MUTEX_MAX_TIMEOUT);
     config_set_string(config, section, key, value, false);
-    osi_mutex_unlock(&lock);
 
     return true;
 }
@@ -254,9 +193,7 @@ bool btc_config_get_bin(const char *section, const char *key, uint8_t *value, si
     assert(value != NULL);
     assert(length != NULL);
 
-    osi_mutex_lock(&lock, OSI_MUTEX_MAX_TIMEOUT);
     const char *value_str = config_get_string(config, section, key, NULL);
-    osi_mutex_unlock(&lock);
 
     if (!value_str) {
         return false;
@@ -287,9 +224,7 @@ size_t btc_config_get_bin_length(const char *section, const char *key)
     assert(section != NULL);
     assert(key != NULL);
 
-    osi_mutex_lock(&lock, OSI_MUTEX_MAX_TIMEOUT);
     const char *value_str = config_get_string(config, section, key, NULL);
-    osi_mutex_unlock(&lock);
 
     if (!value_str) {
         return 0;
@@ -321,9 +256,7 @@ bool btc_config_set_bin(const char *section, const char *key, const uint8_t *val
         str[(i * 2) + 1] = lookup[value[i] & 0x0F];
     }
 
-    osi_mutex_lock(&lock, OSI_MUTEX_MAX_TIMEOUT);
     config_set_string(config, section, key, str, false);
-    osi_mutex_unlock(&lock);
 
     osi_free(str);
     return true;
@@ -355,17 +288,15 @@ const char *btc_config_section_name(const btc_config_section_iter_t *section)
     return config_section_name((const config_section_node_t *)section);
 }
 
+
+
 bool btc_config_remove(const char *section, const char *key)
 {
     assert(config != NULL);
     assert(section != NULL);
     assert(key != NULL);
 
-    osi_mutex_lock(&lock, OSI_MUTEX_MAX_TIMEOUT);
-    bool ret = config_remove_key(config, section, key);
-    osi_mutex_unlock(&lock);
-
-    return ret;
+    return config_remove_key(config, section, key);
 }
 
 bool btc_config_remove_section(const char *section)
@@ -373,81 +304,37 @@ bool btc_config_remove_section(const char *section)
     assert(config != NULL);
     assert(section != NULL);
 
-    osi_mutex_lock(&lock, OSI_MUTEX_MAX_TIMEOUT);
-    bool ret = config_remove_section(config, section);
-    osi_mutex_unlock(&lock);
-
-    return ret;
-}
-
-void btc_config_save(void)
-{
-       assert(config != NULL);
-    // Garbage collection process: the config file accumulates
-    // cached information about remote devices during regular
-    // inquiry scans. We remove some of these junk entries
-    // so the file doesn't grow indefinitely. We have to take care
-    // to make sure we don't remove information about bonded
-    // devices (hence the check for link keys).
-    static const size_t CACHE_MAX = 256;
-    const char *keys[CACHE_MAX];
-    size_t num_keys = 0;
-    size_t total_candidates = 0;
-
-    osi_mutex_lock(&lock, OSI_MUTEX_MAX_TIMEOUT);
-    for (const config_section_node_t *snode = config_section_begin(config); snode != config_section_end(config); snode = config_section_next(snode)) {
-        const char *section = config_section_name(snode);
-        if (!string_is_bdaddr(section)) {
-            continue;
-        }
-
-        if (config_has_key(config, section, "LinkKey") ||
-                config_has_key(config, section, "LE_KEY_PENC") ||
-                config_has_key(config, section, "LE_KEY_PID") ||
-                config_has_key(config, section, "LE_KEY_PCSRK") ||
-                config_has_key(config, section, "LE_KEY_LENC") ||
-                config_has_key(config, section, "LE_KEY_LCSRK")) {
-            continue;
-        }
-
-        if (num_keys < CACHE_MAX) {
-            keys[num_keys++] = section;
-        }
-
-        ++total_candidates;
-    }
-
-    if (total_candidates > CACHE_MAX * 2)
-        while (num_keys > 0) {
-            config_remove_section(config, keys[--num_keys]);
-        }
-    config_save(config, CONFIG_FILE_PATH);
-    osi_mutex_unlock(&lock);
+    return config_remove_section(config, section);
 }
 
 void btc_config_flush(void)
 {
     assert(config != NULL);
-    osi_mutex_lock(&lock, OSI_MUTEX_MAX_TIMEOUT);
+
     config_save(config, CONFIG_FILE_PATH);
-    osi_mutex_unlock(&lock);
 }
 
 int btc_config_clear(void)
 {
     assert(config != NULL);
 
-
-    osi_mutex_lock(&lock, OSI_MUTEX_MAX_TIMEOUT);
     config_free(config);
 
     config = config_new_empty();
     if (config == NULL) {
-        osi_mutex_unlock(&lock);
         return false;
     }
     int ret = config_save(config, CONFIG_FILE_PATH);
-    osi_mutex_unlock(&lock);
     return ret;
 }
 
+void btc_config_lock(void)
+{
+    osi_mutex_lock(&lock, OSI_MUTEX_MAX_TIMEOUT);
+}
+
+void btc_config_unlock(void)
+{
+    osi_mutex_unlock(&lock);
+}
+
index 06d78a2b4838ccd4ed53930bcc832d64844e0a59..e43b5ede9e33d8191a08503de989afd498508ace 100644 (file)
 **  Static variables
 ******************************************************************************/
 static tBTA_SERVICE_MASK btc_enabled_services = 0;
+#if (SMP_INCLUDED == TRUE)
+static btc_dm_pairing_cb_t pairing_cb;
+static btc_dm_local_key_cb_t ble_local_key_cb;
+#endif
+
 /******************************************************************************
 **  Static functions
 ******************************************************************************/
@@ -117,6 +122,110 @@ static void btc_disable_bluetooth_evt(void)
 }
 
 #if (SMP_INCLUDED == TRUE)
+void btc_dm_load_ble_local_keys(void)
+{
+    memset(&ble_local_key_cb, 0, sizeof(btc_dm_local_key_cb_t));
+
+    if (btc_storage_get_ble_local_key(BTC_LE_LOCAL_KEY_ER,(char*)&ble_local_key_cb.er[0],
+                                      BT_OCTET16_LEN)== BT_STATUS_SUCCESS) {
+        ble_local_key_cb.is_er_rcvd = TRUE;
+        LOG_DEBUG("%s BLE ER key loaded",__func__ );
+    }
+
+    if ((btc_storage_get_ble_local_key(BTC_LE_LOCAL_KEY_IR,(char*)&ble_local_key_cb.id_keys.ir[0],
+                                       BT_OCTET16_LEN)== BT_STATUS_SUCCESS )&&
+            (btc_storage_get_ble_local_key(BTC_LE_LOCAL_KEY_IRK, (char*)&ble_local_key_cb.id_keys.irk[0],
+                                           BT_OCTET16_LEN)== BT_STATUS_SUCCESS)&&
+            (btc_storage_get_ble_local_key(BTC_LE_LOCAL_KEY_DHK,(char*)&ble_local_key_cb.id_keys.dhk[0],
+                                           BT_OCTET16_LEN)== BT_STATUS_SUCCESS)) {
+        ble_local_key_cb.is_id_keys_rcvd = TRUE;
+        LOG_DEBUG("%s BLE ID keys loaded", __func__);
+    }
+
+}
+void btc_dm_get_ble_local_keys(tBTA_DM_BLE_LOCAL_KEY_MASK *p_key_mask, BT_OCTET16 er,
+                               tBTA_BLE_LOCAL_ID_KEYS *p_id_keys)
+{
+    if (ble_local_key_cb.is_er_rcvd ) {
+        memcpy(&er[0], &ble_local_key_cb.er[0], sizeof(BT_OCTET16));
+        *p_key_mask |= BTA_BLE_LOCAL_KEY_TYPE_ER;
+    }
+
+    if (ble_local_key_cb.is_id_keys_rcvd) {
+        memcpy(&p_id_keys->ir[0], &ble_local_key_cb.id_keys.ir[0], sizeof(BT_OCTET16));
+        memcpy(&p_id_keys->irk[0],  &ble_local_key_cb.id_keys.irk[0], sizeof(BT_OCTET16));
+        memcpy(&p_id_keys->dhk[0],  &ble_local_key_cb.id_keys.dhk[0], sizeof(BT_OCTET16));
+        *p_key_mask |= BTA_BLE_LOCAL_KEY_TYPE_ID;
+    }
+    LOG_DEBUG("%s  *p_key_mask=0x%02x",__func__,   *p_key_mask);
+}
+
+
+static void btc_dm_remove_ble_bonding_keys(void)
+{
+    bt_bdaddr_t bd_addr;
+    LOG_DEBUG("%s\n",__func__);
+
+    bdcpy(bd_addr.address, pairing_cb.bd_addr);
+
+    btc_storage_remove_remote_addr_type(&bd_addr, false);
+    btc_storage_remove_ble_dev_type(&bd_addr, false);
+    btc_storage_remove_ble_bonding_keys(&bd_addr);
+}
+
+static void btc_dm_save_ble_bonding_keys(void)
+{
+    bt_bdaddr_t bd_addr;
+
+    bdcpy(bd_addr.address, pairing_cb.bd_addr);
+
+    btc_storage_set_ble_dev_type(&bd_addr, false);
+    LOG_DEBUG("%s, penc = %d, pid = %d", __func__, pairing_cb.ble.is_penc_key_rcvd, pairing_cb.ble.is_pid_key_rcvd);
+    if (pairing_cb.ble.is_penc_key_rcvd) {
+        btc_storage_add_ble_bonding_key(&bd_addr,
+                                        (char *) &pairing_cb.ble.penc_key,
+                                        BTM_LE_KEY_PENC,
+                                        sizeof(tBTM_LE_PENC_KEYS));
+    }
+
+    if (pairing_cb.ble.is_pid_key_rcvd) {
+        btc_storage_add_ble_bonding_key(&bd_addr,
+                                        (char *) &pairing_cb.ble.pid_key,
+                                        BTM_LE_KEY_PID,
+                                        sizeof(tBTM_LE_PID_KEYS));
+    }
+
+
+    if (pairing_cb.ble.is_pcsrk_key_rcvd) {
+        btc_storage_add_ble_bonding_key(&bd_addr,
+                                        (char *) &pairing_cb.ble.pcsrk_key,
+                                        BTM_LE_KEY_PCSRK,
+                                        sizeof(tBTM_LE_PCSRK_KEYS));
+    }
+
+
+    if (pairing_cb.ble.is_lenc_key_rcvd) {
+        btc_storage_add_ble_bonding_key(&bd_addr,
+                                        (char *) &pairing_cb.ble.lenc_key,
+                                        BTM_LE_KEY_LENC,
+                                        sizeof(tBTM_LE_LENC_KEYS));
+    }
+
+    if (pairing_cb.ble.is_lcsrk_key_rcvd) {
+        btc_storage_add_ble_bonding_key(&bd_addr,
+                                        (char *) &pairing_cb.ble.lcsrk_key,
+                                        BTM_LE_KEY_LCSRK,
+                                        sizeof(tBTM_LE_LCSRK_KEYS));
+    }
+
+    if (pairing_cb.ble.is_lidk_key_rcvd) {
+        btc_storage_add_ble_bonding_key(&bd_addr,
+                                        NULL,
+                                        BTM_LE_KEY_LID,
+                                        0);
+    }
+}
+
 static void btc_dm_ble_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
 {
     /* Save link key, if not temporary */
@@ -136,7 +245,7 @@ static void btc_dm_ble_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
                              (pairing_cb.bd_addr[0] << 24) + (pairing_cb.bd_addr[1] << 16) + (pairing_cb.bd_addr[2] << 8) + pairing_cb.bd_addr[3],
                              (pairing_cb.bd_addr[4] << 8) + pairing_cb.bd_addr[5]);
          if (btc_storage_get_remote_addr_type(&bdaddr, &addr_type) != BT_STATUS_SUCCESS) {
-            btc_storage_set_remote_addr_type(&bdaddr, p_auth_cmpl->addr_type);
+            btc_storage_set_remote_addr_type(&bdaddr, p_auth_cmpl->addr_type, true);
         }
         /* check the irk has been save in the flash or not, if the irk has already save, means that the peer device has bonding
            before. */
@@ -144,7 +253,7 @@ static void btc_dm_ble_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
             btc_storage_compare_address_key_value(&bdaddr, BTM_LE_KEY_PID,
                                                   (void *)&pairing_cb.ble.pid_key, sizeof(tBTM_LE_PID_KEYS));
         }
-        btc_save_ble_bonding_keys();
+        btc_dm_save_ble_bonding_keys();
     } else {
         /*Map the HCI fail reason  to  bt status  */
         switch (p_auth_cmpl->fail_reason) {
@@ -358,7 +467,9 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg)
         memcpy(bd_addr.address, p_data->link_down.bd_addr, sizeof(BD_ADDR));
         btm_set_bond_type_dev(p_data->link_down.bd_addr, BOND_TYPE_UNKNOWN);
         //remove the bonded key in the config and nvs flash.
-        //btc_storage_remove_ble_bonding_keys(&bd_addr);
+        btc_storage_remove_ble_dev_type(&bd_addr, false);
+        btc_storage_remove_remote_addr_type(&bd_addr, false);
+        btc_storage_remove_ble_bonding_keys(&bd_addr);
         ble_msg.act = ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT;
         param.remove_bond_dev_cmpl.status = (p_data->link_down.status == HCI_SUCCESS) ? ESP_BT_STATUS_SUCCESS : ESP_BT_STATUS_FAIL;
         memcpy(param.remove_bond_dev_cmpl.bd_addr, p_data->link_down.bd_addr, sizeof(BD_ADDR));
index 4f18cbfc91786cd902499ae2adc8f7e9151d1c74..333b768af42b8b0ba2594633a05f6fc7f31d81b0 100644 (file)
@@ -43,11 +43,14 @@ bt_status_t btc_storage_add_bonded_device(bt_bdaddr_t *remote_bd_addr,
     bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
     LOG_DEBUG("add to storage: Remote device:%s\n", bdstr);
 
-    int ret = btc_config_set_int(bdstr, "LinkKeyType", (int)key_type);
-    ret &= btc_config_set_int(bdstr, "PinLength", (int)pin_length);
-    ret &= btc_config_set_bin(bdstr, "LinkKey", link_key, sizeof(LINK_KEY));
+    btc_config_lock();
+    int ret = btc_config_set_int(bdstr, BTC_STORAGE_LINK_KEY_TYPE_STR, (int)key_type);
+    ret &= btc_config_set_int(bdstr, BTC_STORAGE_PIN_LENGTH_STR, (int)pin_length);
+    ret &= btc_config_set_bin(bdstr, BTC_STORAGE_LINK_KEY_STR, link_key, sizeof(LINK_KEY));
     /* write bonded info immediately */
     btc_config_flush();
+    btc_config_unlock();
+
     LOG_DEBUG("Storage add rslt %d\n", ret);
     return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
 }
@@ -66,6 +69,7 @@ static bt_status_t btc_in_fetch_bonded_devices(int add)
 {
     BOOLEAN bt_linkkey_file_found = FALSE;
 
+    btc_config_lock();
     for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end(); iter = btc_config_section_next(iter)) {
         const char *name = btc_config_section_name(iter);
         if (!string_is_bdaddr(name)) {
@@ -75,21 +79,19 @@ static bt_status_t btc_in_fetch_bonded_devices(int add)
         LOG_DEBUG("Remote device:%s\n", name);
         LINK_KEY link_key;
         size_t size = sizeof(link_key);
-        if (btc_config_get_bin(name, "LinkKey", link_key, &size)) {
+        if (btc_config_get_bin(name, BTC_STORAGE_LINK_KEY_STR, link_key, &size)) {
             int linkkey_type;
-            if (btc_config_get_int(name, "LinkKeyType", &linkkey_type)) {
-                //int pin_len;
-                //btc_config_get_int(name, "PinLength", &pin_len))
+            if (btc_config_get_int(name, BTC_STORAGE_LINK_KEY_TYPE_STR, &linkkey_type)) {
                 bt_bdaddr_t bd_addr;
                 string_to_bdaddr(name, &bd_addr);
                 if (add) {
                     DEV_CLASS dev_class = {0, 0, 0};
                     int cod;
                     int pin_length = 0;
-                    if (btc_config_get_int(name, "DevClass", &cod)) {
+                    if (btc_config_get_int(name, BTC_STORAGE_DEV_CLASS_STR, &cod)) {
                         uint2devclass((UINT32)cod, dev_class);
                     }
-                    btc_config_get_int(name, "PinLength", &pin_length);
+                    btc_config_get_int(name, BTC_STORAGE_PIN_LENGTH_STR, &pin_length);
 #if (SMP_INCLUDED == TRUE)
                     BTA_DmAddDevice(bd_addr.address, dev_class, link_key, 0, 0,
                                     (UINT8)linkkey_type, 0, pin_length);
@@ -104,6 +106,8 @@ static bt_status_t btc_in_fetch_bonded_devices(int add)
             LOG_DEBUG("Remote device:%s, no link key\n", name);
         }
     }
+    btc_config_unlock();
+
     return BT_STATUS_SUCCESS;
 }
 
@@ -142,19 +146,22 @@ bt_status_t btc_storage_remove_bonded_device(bt_bdaddr_t *remote_bd_addr)
 {
     bdstr_t bdstr;
     bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
+    int ret = 1;
     LOG_DEBUG("Add to storage: Remote device:%s\n", bdstr);
 
-    int ret = 1;
-    if (btc_config_exist(bdstr, "LinkKeyType")) {
-        ret &= btc_config_remove(bdstr, "LinkKeyType");
+    btc_config_lock();
+    if (btc_config_exist(bdstr, BTC_STORAGE_LINK_KEY_TYPE_STR)) {
+        ret &= btc_config_remove(bdstr, BTC_STORAGE_LINK_KEY_TYPE_STR);
     }
-    if (btc_config_exist(bdstr, "PinLength")) {
-        ret &= btc_config_remove(bdstr, "PinLength");
+    if (btc_config_exist(bdstr, BTC_STORAGE_PIN_LENGTH_STR)) {
+        ret &= btc_config_remove(bdstr, BTC_STORAGE_PIN_LENGTH_STR);
     }
-    if (btc_config_exist(bdstr, "LinkKey")) {
-        ret &= btc_config_remove(bdstr, "LinkKey");
+    if (btc_config_exist(bdstr, BTC_STORAGE_LINK_KEY_STR)) {
+        ret &= btc_config_remove(bdstr, BTC_STORAGE_LINK_KEY_STR);
     }
     /* write bonded info immediately */
     btc_config_flush();
+    btc_config_unlock();
+
     return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
 }
index 111f1f0a2b31eb8e266cbfea92be168756279443..0d4d43e7c74623fed17d33b5a8842743ffc8abc4 100644 (file)
 #define BTC_LE_LOCAL_KEY_DHK      (1<<2)
 #define BTC_LE_LOCAL_KEY_ER       (1<<3)
 
+#define BTC_BLE_STORAGE_DEV_TYPE_STR                "DevType"
+#define BTC_BLE_STORAGE_ADDR_TYPE_STR               "AddrType"
+#define BTC_BLE_STORAGE_LINK_KEY_STR                "LinkKey"
+#define BTC_BLE_STORAGE_LE_KEY_PENC_STR             "LE_KEY_PENC"
+#define BTC_BLE_STORAGE_LE_KEY_PID_STR              "LE_KEY_PID"
+#define BTC_BLE_STORAGE_LE_KEY_PCSRK_STR            "LE_KEY_PCSRK"
+#define BTC_BLE_STORAGE_LE_KEY_LENC_STR             "LE_KEY_LENC"
+#define BTC_BLE_STORAGE_LE_KEY_LID_STR              "LE_KEY_LID"
+#define BTC_BLE_STORAGE_LE_KEY_LCSRK_STR            "LE_KEY_LCSRK"
+
+#define BTC_BLE_STORAGE_LOCAL_ADAPTER_STR           "Adapter"
+#define BTC_BLE_STORAGE_LE_LOCAL_KEY_IR_STR         "LE_LOCAL_KEY_IR"
+#define BTC_BLE_STORAGE_LE_LOCAL_KEY_IRK_STR        "LE_LOCAL_KEY_IRK"
+#define BTC_BLE_STORAGE_LE_LOCAL_KEY_DHK_STR        "LE_LOCAL_KEY_DHK"
+#define BTC_BLE_STORAGE_LE_LOCAL_KEY_ER_STR         "LE_LOCAL_KEY_ER"
+
 /************************************************************************************
 **  Local type definitions
 ************************************************************************************/
-typedef struct
-{
-    uint32_t num_devices;
-    bt_bdaddr_t devices[BTM_SEC_MAX_DEVICE_RECORDS];
-} btc_bonded_devices_t;
-
-typedef struct
-{
-    bool                   is_penc_key_rcvd;
-    tBTM_LE_PENC_KEYS         penc_key;       /* received peer encryption key */
-    bool                   is_pcsrk_key_rcvd;
-    tBTM_LE_PCSRK_KEYS        pcsrk_key;       /* received peer device SRK */
-    bool                   is_pid_key_rcvd;
-    tBTM_LE_PID_KEYS          pid_key;        /* peer device ID key */
-    bool                   is_lenc_key_rcvd;
-    tBTM_LE_LENC_KEYS         lenc_key;       /* local encryption reproduction keys LTK = = d1(ER,DIV,0)*/
-    bool                   is_lcsrk_key_rcvd;
-    tBTM_LE_LCSRK_KEYS        lcsrk_key;      /* local device CSRK = d1(ER,DIV,1)*/
-    bool                   is_lidk_key_rcvd;   /* local identity key received */
-} btc_dm_ble_cb_t;
-
-typedef struct
-{
-    bt_bdaddr_t static_bdaddr;
-    BD_ADDR bd_addr;
-    btc_dm_ble_cb_t ble;
-} btc_dm_pairing_cb_t;
-
-typedef struct
-{
-    uint8_t       ir[BT_OCTET16_LEN];
-    uint8_t       irk[BT_OCTET16_LEN];
-    uint8_t       dhk[BT_OCTET16_LEN];
-}btc_dm_local_key_id_t;
-
-typedef struct
-{
-    bool                 is_er_rcvd;
-    uint8_t             er[BT_OCTET16_LEN];
-    bool                 is_id_keys_rcvd;
-    btc_dm_local_key_id_t  id_keys;  /* ID kyes */
-}btc_dm_local_key_cb_t;
-
 typedef struct
 {
     BT_OCTET16 sp_c;
@@ -77,63 +50,37 @@ typedef struct
 } btc_dm_oob_cb_t;
 
 
-extern btc_dm_pairing_cb_t pairing_cb;
-extern btc_dm_local_key_cb_t ble_local_key_cb;
-extern btc_bonded_devices_t bonded_devices;
+void btc_storage_save(void);
 
-bt_status_t btc_storage_load_bonded_ble_devices(void);
-
-bt_status_t btc_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev);
+bt_status_t btc_storage_add_ble_bonding_key( bt_bdaddr_t *remote_bd_addr, char *key, uint8_t key_type, uint8_t key_length);
 
-bt_status_t btc_in_fetch_bonded_ble_devices(int add);
+bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr, uint8_t key_type, char *key_value, int key_length);
 
-void btc_dm_remove_ble_bonding_keys(void);
+bt_status_t btc_storage_remove_ble_bonding_keys(bt_bdaddr_t *remote_bd_addr);
 
-bt_status_t btc_storage_add_ble_bonding_key( bt_bdaddr_t *remote_bd_addr,
-                                                                                      char *key,
-                                                                                      uint8_t key_type,
-                                                                                      uint8_t key_length);
+bool btc_storage_compare_address_key_value(bt_bdaddr_t *remote_bd_addr, uint8_t key_type, void *key_value, int key_length);
 
-bool btc_compare_le_key_value(const uint8_t key_type, const size_t key_len, const tBTA_LE_KEY_VALUE *key_vaule,
-                    bt_bdaddr_t bd_addr);
+bt_status_t btc_storage_add_ble_local_key(char *key, uint8_t key_type, uint8_t key_length);
 
-void btc_save_ble_bonding_keys(void);
+bt_status_t btc_storage_remove_ble_local_keys(void);
 
-bt_status_t btc_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add, 
-                                           btc_bonded_devices_t *p_bonded_devices);
+bt_status_t btc_storage_get_ble_local_key(uint8_t key_type, char *key_value, int key_len);
 
-bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
-                                                                uint8_t key_type,
-                                                                char *key_value,
-                                                                int key_length);
+bt_status_t btc_storage_get_remote_addr_type(bt_bdaddr_t *remote_bd_addr, int *addr_type);
 
-bool btc_storage_compare_address_key_value(bt_bdaddr_t *remote_bd_addr,
-                                                   uint8_t key_type, void *key_value, int key_length);
-bt_status_t btc_storage_add_ble_local_key(char *key,
-                                                                              uint8_t key_type,
-                                                                              uint8_t key_length);
+bt_status_t btc_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr, uint8_t addr_type, bool flush);
 
-bt_status_t btc_storage_remove_ble_bonding_keys(bt_bdaddr_t *remote_bd_addr);
+bt_status_t btc_storage_remove_remote_addr_type(bt_bdaddr_t *remote_bd_addr, bool flush);
 
-bt_status_t btc_storage_clear_bond_devices(void);
+bt_status_t btc_storage_set_ble_dev_type(bt_bdaddr_t *bd_addr, bool flush);
 
-bt_status_t btc_storage_remove_ble_local_keys(void);
+bt_status_t btc_storage_remove_ble_dev_type(bt_bdaddr_t *remote_bd_addr, bool flush);
 
-bt_status_t btc_storage_get_ble_local_key(uint8_t key_type,
-                                                                             char *key_value,
-                                                                             int key_len);
+bt_status_t btc_storage_load_bonded_ble_devices(void);
 
-bt_status_t btc_storage_get_remote_addr_type(bt_bdaddr_t *remote_bd_addr,
-                                                                                     int *addr_type);
+bt_status_t btc_storage_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev, int dev_num);
 
 int btc_storage_get_num_ble_bond_devices(void);
 
-bt_status_t btc_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr,
-                                                                                     uint8_t addr_type);
-
-void btc_dm_load_ble_local_keys(void);
-
-void btc_dm_get_ble_local_keys(tBTA_DM_BLE_LOCAL_KEY_MASK *p_key_mask, BT_OCTET16 er,
-                                                            tBTA_BLE_LOCAL_ID_KEYS *p_id_keys);
 #endif  ///SMP_INCLUDED == TRUE
-#endif  ///__BTC_BLE_STORAGE_H__
\ No newline at end of file
+#endif  ///__BTC_BLE_STORAGE_H__
index 2367c53b40d49bc919c150e33f84abf3595b7906..79f6137e85190495fbc0b015aadd10e011426141 100644 (file)
@@ -20,8 +20,6 @@
 
 #include "bt_types.h"
 
-#define BTC_LE_DEV_TYPE           "DevType"
-
 typedef struct btc_config_section_iter_t btc_config_section_iter_t;
 
 bool btc_config_init(void);
@@ -46,7 +44,6 @@ const btc_config_section_iter_t *btc_config_section_end(void);
 const btc_config_section_iter_t *btc_config_section_next(const btc_config_section_iter_t *section);
 const char *btc_config_section_name(const btc_config_section_iter_t *section);
 
-void btc_config_save(void);
 void btc_config_flush(void);
 int btc_config_clear(void);
 
@@ -55,4 +52,7 @@ bool btc_get_address_type(const BD_ADDR bd_addr, int *p_addr_type);
 bool btc_compare_address_key_value(const char *section, char *key_type, void *key_value, int key_length);
 bool btc_get_device_type(const BD_ADDR bd_addr, int *p_device_type);
 
+void btc_config_lock(void);
+void btc_config_unlock(void);
+
 #endif
index e397d82b4f7af992080cdaab9d8daf51f2e266a1..44f4d84c199d64893802740c0ab79462452acdad 100644 (file)
@@ -29,6 +29,45 @@ typedef union {
     tBTA_DM_SEC sec;
 } btc_dm_sec_args_t;
 
+typedef struct
+{
+    bool                   is_penc_key_rcvd;
+    tBTM_LE_PENC_KEYS         penc_key;       /* received peer encryption key */
+    bool                   is_pcsrk_key_rcvd;
+    tBTM_LE_PCSRK_KEYS        pcsrk_key;       /* received peer device SRK */
+    bool                   is_pid_key_rcvd;
+    tBTM_LE_PID_KEYS          pid_key;        /* peer device ID key */
+    bool                   is_lenc_key_rcvd;
+    tBTM_LE_LENC_KEYS         lenc_key;       /* local encryption reproduction keys LTK = = d1(ER,DIV,0)*/
+    bool                   is_lcsrk_key_rcvd;
+    tBTM_LE_LCSRK_KEYS        lcsrk_key;      /* local device CSRK = d1(ER,DIV,1)*/
+    bool                   is_lidk_key_rcvd;   /* local identity key received */
+} btc_dm_ble_cb_t;
+
+typedef struct
+{
+    bt_bdaddr_t            static_bdaddr;
+    BD_ADDR                bd_addr;
+    btc_dm_ble_cb_t        ble;
+} btc_dm_pairing_cb_t;
+
+typedef struct
+{
+    uint8_t                ir[BT_OCTET16_LEN];
+    uint8_t                irk[BT_OCTET16_LEN];
+    uint8_t                dhk[BT_OCTET16_LEN];
+} btc_dm_local_key_id_t;
+
+typedef struct
+{
+    bool                 is_er_rcvd;
+    uint8_t              er[BT_OCTET16_LEN];
+    bool                 is_id_keys_rcvd;
+    btc_dm_local_key_id_t  id_keys;  /* ID kyes */
+} btc_dm_local_key_cb_t;
+
+
+
 // void btc_dm_call_handler(btc_msg_t *msg);
 void btc_dm_sec_evt(tBTA_DM_SEC_EVT event, tBTA_DM_SEC *data);
 void btc_dm_sec_cb_handler(btc_msg_t *msg);
@@ -37,4 +76,11 @@ void btc_dm_sec_arg_deep_copy(btc_msg_t *msg, void *dst, void *src);
 bt_status_t btc_dm_enable_service(tBTA_SERVICE_ID service_id);
 bt_status_t btc_dm_disable_service(tBTA_SERVICE_ID service_id);
 
+#if (SMP_INCLUDED == TRUE)
+void btc_dm_load_ble_local_keys(void);
+
+void btc_dm_get_ble_local_keys(tBTA_DM_BLE_LOCAL_KEY_MASK *p_key_mask, BT_OCTET16 er,
+                                                            tBTA_BLE_LOCAL_ID_KEYS *p_id_keys);
+#endif
+
 #endif /* __BTC_DM_H__ */
index c2fb6ccbba528064000debb04acbec1a583de49a..9e69b4139e8bd0f2b97bfd1612607c78bf54037c 100644 (file)
 #include "bt_defs.h"
 #include "bt_types.h"
 
+
+#define BTC_STORAGE_DEV_CLASS_STR       "DevClass"
+#define BTC_STORAGE_LINK_KEY_STR        "LinkKey"    /* same as the ble */
+#define BTC_STORAGE_LINK_KEY_TYPE_STR   "LinkKeyType"
+#define BTC_STORAGE_PIN_LENGTH_STR      "PinLength"
+
 /*******************************************************************************
 **
 ** Function         btc_storage_add_bonded_device
index a4dccae0e1eaff80f79d2e6a90eb3397c10dc7e1..5869f393d106cfde0def11bd7f4db78c9c09174a 100644 (file)
@@ -26,6 +26,7 @@
 #include "esp_bt_defs.h"
 #include "esp_gap_ble_api.h"
 #include "btc_ble_storage.h"
+#include "btc_dm.h"
 
 static tBTA_BLE_ADV_DATA gl_bta_adv_data;
 static tBTA_BLE_ADV_DATA gl_bta_scan_rsp_data;
@@ -793,71 +794,6 @@ static void btc_ble_set_rand_addr (BD_ADDR rand_addr)
     }
 }
 
-#if (SMP_INCLUDED)
-static void btc_ble_remove_bond_device(esp_bt_status_t status)
-{
-    int ret;
-    esp_ble_gap_cb_param_t param;
-    btc_msg_t msg;
-    param.remove_bond_dev_cmpl.status = status;
-    msg.sig = BTC_SIG_API_CB;
-    msg.pid = BTC_PID_GAP_BLE;
-    msg.act = ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT;
-
-    ret = btc_transfer_context(&msg, &param,
-                               sizeof(esp_ble_gap_cb_param_t), NULL);
-
-    if (ret != BT_STATUS_SUCCESS) {
-        LOG_ERROR("%s btc_transfer_context failed", __func__);
-    }
-}
-
-static void btc_ble_clear_bond_device(void)
-{
-    int ret;
-    esp_ble_gap_cb_param_t param;
-    btc_msg_t msg;
-    ret = btc_storage_clear_bond_devices();
-    param.clear_bond_dev_cmpl.status = ret;
-    msg.sig = BTC_SIG_API_CB;
-    msg.pid = BTC_PID_GAP_BLE;
-    msg.act = ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT;
-
-    ret = btc_transfer_context(&msg, &param,
-                               sizeof(esp_ble_gap_cb_param_t), NULL);
-
-    if (ret != BT_STATUS_SUCCESS) {
-        LOG_ERROR("%s btc_transfer_context failed", __func__);
-    }
-
-}
-
-static void btc_ble_get_bond_device_list(void)
-{
-    int ret;
-    esp_ble_gap_cb_param_t param;
-    esp_ble_bond_dev_t *bond_dev;
-    btc_msg_t msg;
-    int num_dev = btc_storage_get_num_ble_bond_devices();
-    bond_dev = (esp_ble_bond_dev_t *)osi_malloc(sizeof(esp_ble_bond_dev_t)*num_dev);
-
-    param.get_bond_dev_cmpl.status = btc_get_bonded_ble_devices_list(bond_dev);
-    param.get_bond_dev_cmpl.dev_num = num_dev;
-    param.get_bond_dev_cmpl.bond_dev = bond_dev;
-    msg.sig = BTC_SIG_API_CB;
-    msg.pid = BTC_PID_GAP_BLE;
-    msg.act = ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT;
-
-    ret = btc_transfer_context(&msg, &param, sizeof(esp_ble_gap_cb_param_t), btc_gap_ble_cb_deep_copy);
-
-    if (ret != BT_STATUS_SUCCESS) {
-        LOG_ERROR("%s btc_transfer_context failed", __func__);
-    }
-    // release the buffer after used.
-    osi_free(bond_dev);
-}
-#endif /* #if (SMP_INCLUDED) */
-
 static void btc_ble_config_local_privacy(bool privacy_enable, tBTA_SET_LOCAL_PRIVACY_CBACK *set_local_privacy_cback)
 {
     BTA_DmBleConfigLocalPrivacy(privacy_enable, set_local_privacy_cback);
@@ -954,21 +890,6 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
 void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
 {
     switch (msg->act) {
-    case ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT: {
-        esp_ble_gap_cb_param_t *src = (esp_ble_gap_cb_param_t *)p_src;
-        esp_ble_gap_cb_param_t *dst = (esp_ble_gap_cb_param_t *)p_dest;
-        uint16_t length = 0;
-        if (src->get_bond_dev_cmpl.bond_dev) {
-            length = (src->get_bond_dev_cmpl.dev_num)*sizeof(esp_ble_bond_dev_t);
-            dst->get_bond_dev_cmpl.bond_dev = (esp_ble_bond_dev_t *)osi_malloc(length);
-            if (dst->get_bond_dev_cmpl.bond_dev != NULL) {
-                memcpy(dst->get_bond_dev_cmpl.bond_dev, src->get_bond_dev_cmpl.bond_dev, length);
-            } else {
-                LOG_ERROR("%s %d no mem", __func__, msg->act);
-            }
-        }
-        break;
-    }
     default:
        LOG_ERROR("%s, Unhandled deep copy %d\n", __func__, msg->act);
        break;
@@ -1018,13 +939,6 @@ void btc_gap_ble_cb_deep_free(btc_msg_t *msg)
 {
     LOG_DEBUG("%s", __func__);
     switch (msg->act) {
-        case ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT: {
-            esp_ble_bond_dev_t *bond_dev = ((esp_ble_gap_cb_param_t *)msg->arg)->get_bond_dev_cmpl.bond_dev;
-            if (bond_dev) {
-                osi_free(bond_dev);
-            }
-            break;
-        }
         default:
             LOG_DEBUG("Unhandled deep free %d", msg->act);
             break;
@@ -1158,24 +1072,10 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
     }
     case BTC_GAP_BLE_REMOVE_BOND_DEV_EVT: {
         BD_ADDR bd_addr;
-        bt_bdaddr_t bt_addr;
         memcpy(bd_addr, arg->remove_bond_device.bd_addr, sizeof(BD_ADDR));
-        memcpy(bt_addr.address, arg->remove_bond_device.bd_addr, sizeof(bt_bdaddr_t));
-        LOG_DEBUG("BTC_GAP_BLE_REMOVE_BOND_DEV_EVT");
-        if (btc_storage_remove_ble_bonding_keys(&bt_addr) == BT_STATUS_SUCCESS) {
-            BTA_DmRemoveDevice(bd_addr);
-        } else {
-            LOG_ERROR("remove device failed: the address[%x:%x:%x:%x:%x:%x] didn't in the bonding list", bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
-            btc_ble_remove_bond_device(ESP_BT_STATUS_FAIL);
-        }
+        BTA_DmRemoveDevice(bd_addr);
         break;
     }
-    case BTC_GAP_BLE_CLEAR_BOND_DEV_EVT:
-        btc_ble_clear_bond_device();
-        break;
-    case BTC_GAP_BLE_GET_BOND_DEV_EVT:
-        btc_ble_get_bond_device_list();
-        break;
 #endif  ///SMP_INCLUDED == TRUE
     case BTC_GAP_BLE_DISCONNECT_EVT:
         btc_ble_disconnect(arg->disconnect.remote_device);
index b6da5360650fab564d66a4004f4018c47b132793..601167a5a36cbb9d9ac48b4cdecc9cf6ce4372d4 100644 (file)
@@ -41,8 +41,6 @@ typedef enum {
     BTC_GAP_BLE_CONFIRM_REPLY_EVT,
     BTC_GAP_BLE_DISCONNECT_EVT,
     BTC_GAP_BLE_REMOVE_BOND_DEV_EVT,
-    BTC_GAP_BLE_CLEAR_BOND_DEV_EVT,
-    BTC_GAP_BLE_GET_BOND_DEV_EVT,
 } btc_gap_ble_act_t;
 
 /* btc_ble_gap_args_t */
index bd40a044e61393e0798f8b3e95f88b3d632c18ab..1feb6c332337aa0fe93e761a1278d126fb6f0706 100644 (file)
@@ -22,7 +22,7 @@
 #include "bta_sys.h"
 #include "bta_dm_co.h"
 #include "bta_dm_ci.h"
-#include "btc_ble_storage.h"
+#include "btc_dm.h"
 #if (defined(BTIF_INCLUDED) && BTIF_INCLUDED == TRUE)
 #include "bt_utils.h"
 #if (BTM_OOB_INCLUDED == TRUE)
index 5b5205dd9a5d0faab461005ccc04c998482f4972..1c5117c7f25046582b9dab1c0d33a1987e38f0ae 100644 (file)
@@ -32,6 +32,7 @@
 #include "alarm.h"
 #include "thread.h"
 #include "mutex.h"
+#include "fixed_queue.h"
 
 typedef struct {
     uint16_t opcode;
index 76f93638ad375e9490c61c9ae1eef83432c9dcc9..5e9b8c695b50c2da918ff28f691d3e5922236a63 100644 (file)
@@ -21,7 +21,6 @@
 
 #include "bt_types.h"
 #include "allocator.h"
-#include "fixed_queue.h"
 #include "osi.h"
 #include "future.h"
 ///// LEGACY DEFINITIONS /////
index c7cc57a5a4016e5a09582657b2c45370ba3ea2f0..616f3aa96065171c9cd2aae65e3ebd8ec78e1cd5 100644 (file)
@@ -2988,21 +2988,18 @@ tBTM_STATUS btm_ble_start_scan(void)
     tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var;
     tBTM_STATUS status = BTM_CMD_STARTED;
 
-    if (p_inq->adv_mode != BTM_BLE_ADV_DISABLE) {
+    /* start scan, disable duplicate filtering */
+    if (!btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, p_inq->scan_duplicate_filter)) {
         status = BTM_NO_RESOURCES;
     } else {
-        /* start scan, disable duplicate filtering */
-        if (!btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, p_inq->scan_duplicate_filter)) {
-            status = BTM_NO_RESOURCES;
+        btm_cb.ble_ctr_cb.inq_var.state = BTM_BLE_SCANNING;
+        if (p_inq->scan_type == BTM_BLE_SCAN_MODE_ACTI) {
+            btm_ble_set_topology_mask(BTM_BLE_STATE_ACTIVE_SCAN_BIT);
         } else {
-            btm_cb.ble_ctr_cb.inq_var.state = BTM_BLE_SCANNING;
-            if (p_inq->scan_type == BTM_BLE_SCAN_MODE_ACTI) {
-                btm_ble_set_topology_mask(BTM_BLE_STATE_ACTIVE_SCAN_BIT);
-            } else {
-                btm_ble_set_topology_mask(BTM_BLE_STATE_PASSIVE_SCAN_BIT);
-            }
+            btm_ble_set_topology_mask(BTM_BLE_STATE_PASSIVE_SCAN_BIT);
         }
     }
+
     return status;
 }
 
@@ -3019,18 +3016,17 @@ void btm_ble_stop_scan(void)
 {
     BTM_TRACE_EVENT ("btm_ble_stop_scan ");
 
-    if (btm_cb.ble_ctr_cb.inq_var.adv_mode == BTM_BLE_ADV_DISABLE) {
-        /* Clear the inquiry callback if set */
-        btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE;
-        btm_cb.ble_ctr_cb.inq_var.state = BTM_BLE_STOP_SCAN;
-        /* stop discovery now */
-        btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE);
+    /* Clear the inquiry callback if set */
+    btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE;
+    btm_cb.ble_ctr_cb.inq_var.state = BTM_BLE_STOP_SCAN;
+    /* stop discovery now */
+    btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE);
 
-        btm_update_scanner_filter_policy(SP_ADV_ALL);
+    btm_update_scanner_filter_policy(SP_ADV_ALL);
 
-        btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_SCAN;
-    }
+    btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_SCAN;
 }
+
 /*******************************************************************************
 **
 ** Function         btm_ble_stop_inquiry
@@ -3149,14 +3145,10 @@ static BOOLEAN btm_ble_adv_states_operation(BTM_TOPOLOGY_FUNC_PTR *p_handler, UI
 *******************************************************************************/
 tBTM_STATUS btm_ble_start_adv(void)
 {
-    tBTM_BLE_CB *p_ble_cb = & btm_cb.ble_ctr_cb;
     tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
     tBTM_STATUS     rt = BTM_NO_RESOURCES;
     BTM_TRACE_EVENT ("btm_ble_start_adv\n");
 
-    if (BTM_BLE_IS_OBS_ACTIVE(p_ble_cb->scan_activity)) {
-        return BTM_NO_RESOURCES;
-    }
 
     if (!btm_ble_adv_states_operation (btm_ble_topology_check, p_cb->evt_type)) {
         return BTM_WRONG_MODE;
@@ -3200,12 +3192,10 @@ tBTM_STATUS btm_ble_start_adv(void)
 *******************************************************************************/
 tBTM_STATUS btm_ble_stop_adv(void)
 {
-    tBTM_BLE_CB *p_ble_cb = & btm_cb.ble_ctr_cb;
     tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
     tBTM_STATUS rt = BTM_SUCCESS;
 
-    if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE
-            && !BTM_BLE_IS_OBS_ACTIVE(p_ble_cb->scan_activity)) {
+    if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) {
         if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_DISABLE)) {
             p_cb->fast_adv_on = FALSE;
             p_cb->adv_mode = BTM_BLE_ADV_DISABLE;
index 30b618001b214c66411b0964d234e6fe2fceb246..0266a212d5ad85aa4bb9e0eed06d79f25e2ca5c3 100644 (file)
@@ -2216,9 +2216,10 @@ void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport)
         gatt_free_pending_ind(p_tcb);
         gatt_free_pending_enc_queue(p_tcb);
         gatt_free_pending_prepare_write_queue(p_tcb);
+#if (GATTS_INCLUDED == TRUE)
         fixed_queue_free(p_tcb->sr_cmd.multi_rsp_q, osi_free_func);
         p_tcb->sr_cmd.multi_rsp_q = NULL;
-
+#endif  ///GATTS_INCLUDED == TRUE
         for (i = 0; i < GATT_MAX_APPS; i ++) {
             p_reg = &gatt_cb.cl_rcb[i];
             if (p_reg->in_use && p_reg->app_cb.p_conn_cb) {
index e2d7d842ef34ea54174fd6169e0dd98fcf912a94..a11cd3eeceaa9272ed0faa67bc4d4d6f8143bd0c 100644 (file)
@@ -102,11 +102,10 @@ typedef enum {
     ESP_BLE_PWR_TYPE_CONN_HDL6  = 6,            /*!< For connection handle 6 */
     ESP_BLE_PWR_TYPE_CONN_HDL7  = 7,            /*!< For connection handle 7 */
     ESP_BLE_PWR_TYPE_CONN_HDL8  = 8,            /*!< For connection handle 8 */
-    ESP_BLE_PWR_TYPE_CONN_HDL9  = 9,            /*!< For connection handle 9 */
-    ESP_BLE_PWR_TYPE_ADV        = 10,           /*!< For advertising */
-    ESP_BLE_PWR_TYPE_SCAN       = 11,           /*!< For scan */
-    ESP_BLE_PWR_TYPE_DEFAULT    = 12,           /*!< For default, if not set other, it will use default value */
-    ESP_BLE_PWR_TYPE_NUM        = 13,           /*!< TYPE numbers */
+    ESP_BLE_PWR_TYPE_ADV        = 9,           /*!< For advertising */
+    ESP_BLE_PWR_TYPE_SCAN       = 10,           /*!< For scan */
+    ESP_BLE_PWR_TYPE_DEFAULT    = 11,           /*!< For default, if not set other, it will use default value */
+    ESP_BLE_PWR_TYPE_NUM        = 12,           /*!< TYPE numbers */
 } esp_ble_power_type_t;
 
 /**
index 2651a662d8ccda03c06a2b775fdaf938270855bd..d41e3512971612a4903e1ea1189968408811a1ae 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 2651a662d8ccda03c06a2b775fdaf938270855bd
+Subproject commit d41e3512971612a4903e1ea1189968408811a1ae
index 229685b7c3c3399ac9a6842b2cae5f370647c088..de1b619f93059b9164fd4ae078bf786e2b4324f8 100644 (file)
@@ -269,6 +269,20 @@ esp_err_t uart_set_line_inverse(uart_port_t uart_num, uint32_t inverse_mask);
  */
 esp_err_t uart_set_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t flow_ctrl, uint8_t rx_thresh);
 
+/**
+ * @brief Set software flow control.
+ *
+ * @param uart_num   UART_NUM_0, UART_NUM_1 or UART_NUM_2
+ * @param enable     switch on or off
+ * @param rx_thresh_xon  low water mark
+ * @param rx_thresh_xoff high water mark
+ *
+ * @return
+ *     - ESP_OK   Success
+ *     - ESP_FAIL Parameter error
+ */
+ esp_err_t uart_set_sw_flow_ctrl(uart_port_t uart_num, bool enable, uint8_t rx_thresh_xon,  uint8_t rx_thresh_xoff);
+
 /**
  * @brief Get hardware flow control mode
  *
index 5371a447c8feb40371b9f2276b0ad05b250a5d64..fffae17344cd24f88bca85de4551ea482bf3fd31 100644 (file)
@@ -29,6 +29,9 @@
 #include "driver/uart.h"
 #include "driver/gpio.h"
 
+#define XOFF (char)0x13
+#define XON (char)0x11
+
 static const char* UART_TAG = "uart";
 #define UART_CHECK(a, str, ret_val) \
     if (!(a)) { \
@@ -199,6 +202,22 @@ esp_err_t uart_set_line_inverse(uart_port_t uart_num, uint32_t inverse_mask)
     return ESP_OK;
 }
 
+esp_err_t uart_set_sw_flow_ctrl(uart_port_t uart_num, bool enable,  uint8_t rx_thresh_xon,  uint8_t rx_thresh_xoff)
+{
+    UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL);
+    UART_CHECK((rx_thresh_xon < UART_FIFO_LEN), "rx flow xon thresh error", ESP_FAIL);
+    UART_CHECK((rx_thresh_xoff < UART_FIFO_LEN), "rx flow xon thresh error", ESP_FAIL);
+    UART_ENTER_CRITICAL(&uart_spinlock[uart_num]);
+    UART[uart_num]->flow_conf.sw_flow_con_en = enable? 1:0;
+    UART[uart_num]->flow_conf.xonoff_del = enable?1:0;
+    UART[uart_num]->swfc_conf.xon_threshold =  rx_thresh_xon;
+    UART[uart_num]->swfc_conf.xoff_threshold =  rx_thresh_xoff;
+    UART[uart_num]->swfc_conf.xon_char = XON;
+    UART[uart_num]->swfc_conf.xoff_char = XOFF;
+    UART_EXIT_CRITICAL(&uart_spinlock[uart_num]);
+    return ESP_OK;
+}
+
 //only when UART_HW_FLOWCTRL_RTS is set , will the rx_thresh value be set.
 esp_err_t uart_set_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t flow_ctrl, uint8_t rx_thresh)
 {
index 99f9dd5434547193d59cf2c4a986c91b84f06826..5b5be9a67d89deee9494b2d3e542a14736d35065 100644 (file)
@@ -89,13 +89,14 @@ SECTIONS
     *libesp32.a:core_dump.o(.literal .text .literal.* .text.*)
     *libapp_trace.a:(.literal .text .literal.* .text.*)
     *libxtensa-debug-module.a:eri.o(.literal .text .literal.* .text.*)
-    *libesp32.a:app_trace.o(.literal .text .literal.* .text.*)
     *libphy.a:(.literal .text .literal.* .text.*)
     *librtc.a:(.literal .text .literal.* .text.*)
     *libsoc.a:(.literal .text .literal.* .text.*)
     *libhal.a:(.literal .text .literal.* .text.*)
     *libgcc.a:lib2funcs.o(.literal .text .literal.* .text.*)
     *libspi_flash.a:spi_flash_rom_patch.o(.literal .text .literal.* .text.*)
+    *libgcov.a:(.literal .text .literal.* .text.*)
+    INCLUDE esp32.spiram.rom-functions-iram.ld
     _iram_text_end = ABSOLUTE(.);
   } > iram0_0_seg
 
@@ -117,8 +118,10 @@ SECTIONS
     *libesp32.a:panic.o(.rodata .rodata.*)
     *libphy.a:(.rodata .rodata.*)
     *libapp_trace.a:(.rodata .rodata.*)
+    *libgcov.a:(.rodata .rodata.*)
     *libheap.a:multi_heap.o(.rodata .rodata.*)
     *libheap.a:multi_heap_poisoning.o(.rodata .rodata.*)
+    INCLUDE esp32.spiram.rom-functions-dram.ld
     _data_end = ABSOLUTE(.);
     . = ALIGN(4);
   } >dram0_0_seg
index d60eeb90c3a5faac2e552b035dd89af06e811495..3b11ce2e605893e5e0932269df30760890676f4d 100644 (file)
@@ -215,9 +215,17 @@ PROVIDE ( llc_state = 0x3ffb96f8 );
 PROVIDE ( lldesc_build_chain = 0x4000a850 );
 PROVIDE ( lldesc_num2link = 0x4000a948 );
 PROVIDE ( lldesc_set_owner = 0x4000a974 );
+PROVIDE ( lld_evt_deferred_elt_push = 0x400466b4 );
+PROVIDE ( lld_evt_deferred_elt_pop = 0x400466dc );
+PROVIDE ( lld_evt_winsize_change = 0x40046730 );
+PROVIDE ( lld_evt_rxwin_compute = 0x400467c8 );
+PROVIDE ( lld_evt_slave_time_compute = 0x40046818 );
 PROVIDE ( lld_evt_env = 0x3ffb9704 );
+PROVIDE ( lld_evt_elt_wait_get = 0x400468e4 );
+PROVIDE ( lld_evt_get_next_free_slot = 0x4004692c );
 PROVIDE ( lld_pdu_adv_pk_desc_tab = 0x3ff98c70 );
 PROVIDE ( lld_pdu_llcp_pk_desc_tab = 0x3ff98b68 );
+PROVIDE ( lld_pdu_pack = 0x4004ab14 );
 PROVIDE ( LLM_AA_CT1 = 0x3ff98d8a );
 PROVIDE ( LLM_AA_CT2 = 0x3ff98d88 );
 PROVIDE ( llm_default_handler = 0x3ff98d80 );
@@ -1713,5 +1721,6 @@ PROVIDE ( LM_SniffSubRate = 0x3ffb8214 );
 PROVIDE ( prbs_64bytes = 0x3ff98992 );
 PROVIDE ( nvds_env = 0x3ffb8364 );
 PROVIDE ( nvds_magic_number = 0x3ff9912a );
+PROVIDE ( TASK_DESC_LLD = 0x3ff98b58 );
 /* Above are static data, but can be used, not generated by script >>>>> btdm data */
 
diff --git a/components/esp32/ld/esp32.spiram.rom-functions-dram.ld b/components/esp32/ld/esp32.spiram.rom-functions-dram.ld
new file mode 100644 (file)
index 0000000..da59bc0
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ If the Newlib functions in ROM aren't used (eg because the external SPI RAM workaround is active), these functions will 
+ be linked into the application directly instead. Normally, they would end up in flash, which is undesirable because esp-idf
+ and/or applications may assume that because these functions normally are in ROM, they are accessible even when flash is 
+ inaccessible. To work around this, this ld fragment places these functions in RAM instead. If the ROM functions are used,
+ these defines do nothing, so they can still be included in that situation.
+
+ This file is responsible for placing the rodata segment in DRAM.
+*/
+
+    *lib_a-utoa.o(.rodata .rodata.*)
+    *lib_a-longjmp.o(.rodata .rodata.*)
+    *lib_a-setjmp.o(.rodata .rodata.*)
+    *lib_a-abs.o(.rodata .rodata.*)
+    *lib_a-div.o(.rodata .rodata.*)
+    *lib_a-labs.o(.rodata .rodata.*)
+    *lib_a-ldiv.o(.rodata .rodata.*)
+    *lib_a-quorem.o(.rodata .rodata.*)
+    *lib_a-qsort.o(.rodata .rodata.*)
+    *lib_a-utoa.o(.rodata .rodata.*)
+    *lib_a-itoa.o(.rodata .rodata.*)
+    *lib_a-atoi.o(.rodata .rodata.*)
+    *lib_a-atol.o(.rodata .rodata.*)
+    *lib_a-strtol.o(.rodata .rodata.*)
+    *lib_a-strtoul.o(.rodata .rodata.*)
+    *lib_a-wcrtomb.o(.rodata .rodata.*)
+    *lib_a-fvwrite.o(.rodata .rodata.*)
+    *lib_a-wbuf.o(.rodata .rodata.*)
+    *lib_a-wsetup.o(.rodata .rodata.*)
+    *lib_a-fputwc.o(.rodata .rodata.*)
+    *lib_a-wctomb_r.o(.rodata .rodata.*)
+    *lib_a-ungetc.o(.rodata .rodata.*)
+    *lib_a-makebuf.o(.rodata .rodata.*)
+    *lib_a-fflush.o(.rodata .rodata.*)
+    *lib_a-refill.o(.rodata .rodata.*)
+    *lib_a-s_fpclassify.o(.rodata .rodata.*)
+    *lib_a-locale.o(.rodata .rodata.*)
+    *lib_a-asctime.o(.rodata .rodata.*)
+    *lib_a-ctime.o(.rodata .rodata.*)
+    *lib_a-ctime_r.o(.rodata .rodata.*)
+    *lib_a-lcltime.o(.rodata .rodata.*)
+    *lib_a-lcltime_r.o(.rodata .rodata.*)
+    *lib_a-gmtime.o(.rodata .rodata.*)
+    *lib_a-gmtime_r.o(.rodata .rodata.*)
+    *lib_a-strftime.o(.rodata .rodata.*)
+    *lib_a-mktime.o(.rodata .rodata.*)
+    *lib_a-syswrite.o(.rodata .rodata.*)
+    *lib_a-tzset_r.o(.rodata .rodata.*)
+    *lib_a-tzset.o(.rodata .rodata.*)
+    *lib_a-toupper.o(.rodata .rodata.*)
+    *lib_a-tolower.o(.rodata .rodata.*)
+    *lib_a-toascii.o(.rodata .rodata.*)
+    *lib_a-systimes.o(.rodata .rodata.*)
+    *lib_a-time.o(.rodata .rodata.*)
+    *lib_a-bsd_qsort_r.o(.rodata .rodata.*)
+    *lib_a-qsort_r.o(.rodata .rodata.*)
+    *lib_a-gettzinfo.o(.rodata .rodata.*)
+    *lib_a-strupr.o(.rodata .rodata.*)
+    *lib_a-asctime_r.o(.rodata .rodata.*)
+    *lib_a-bzero.o(.rodata .rodata.*)
+    *lib_a-close.o(.rodata .rodata.*)
+    *lib_a-creat.o(.rodata .rodata.*)
+    *lib_a-environ.o(.rodata .rodata.*)
+    *lib_a-fclose.o(.rodata .rodata.*)
+    *lib_a-isalnum.o(.rodata .rodata.*)
+    *lib_a-isalpha.o(.rodata .rodata.*)
+    *lib_a-isascii.o(.rodata .rodata.*)
+    *lib_a-isblank.o(.rodata .rodata.*)
+    *lib_a-iscntrl.o(.rodata .rodata.*)
+    *lib_a-isdigit.o(.rodata .rodata.*)
+    *lib_a-isgraph.o(.rodata .rodata.*)
+    *lib_a-islower.o(.rodata .rodata.*)
+    *lib_a-isprint.o(.rodata .rodata.*)
+    *lib_a-ispunct.o(.rodata .rodata.*)
+    *lib_a-isspace.o(.rodata .rodata.*)
+    *lib_a-isupper.o(.rodata .rodata.*)
+    *lib_a-memccpy.o(.rodata .rodata.*)
+    *lib_a-memchr.o(.rodata .rodata.*)
+    *lib_a-memcmp.o(.rodata .rodata.*)
+    *lib_a-memcpy.o(.rodata .rodata.*)
+    *lib_a-memmove.o(.rodata .rodata.*)
+    *lib_a-memrchr.o(.rodata .rodata.*)
+    *lib_a-memset.o(.rodata .rodata.*)
+    *lib_a-open.o(.rodata .rodata.*)
+    *lib_a-rand.o(.rodata .rodata.*)
+    *lib_a-rand_r.o(.rodata .rodata.*)
+    *lib_a-read.o(.rodata .rodata.*)
+    *lib_a-rshift.o(.rodata .rodata.*)
+    *lib_a-sbrk.o(.rodata .rodata.*)
+    *lib_a-srand.o(.rodata .rodata.*)
+    *lib_a-strcasecmp.o(.rodata .rodata.*)
+    *lib_a-strcasestr.o(.rodata .rodata.*)
+    *lib_a-strcat.o(.rodata .rodata.*)
+    *lib_a-strchr.o(.rodata .rodata.*)
+    *lib_a-strcmp.o(.rodata .rodata.*)
+    *lib_a-strcoll.o(.rodata .rodata.*)
+    *lib_a-strcpy.o(.rodata .rodata.*)
+    *lib_a-strcspn.o(.rodata .rodata.*)
+    *lib_a-strdup.o(.rodata .rodata.*)
+    *lib_a-strlcat.o(.rodata .rodata.*)
+    *lib_a-strlcpy.o(.rodata .rodata.*)
+    *lib_a-strlen.o(.rodata .rodata.*)
+    *lib_a-strlwr.o(.rodata .rodata.*)
+    *lib_a-strncasecmp.o(.rodata .rodata.*)
+    *lib_a-strncat.o(.rodata .rodata.*)
+    *lib_a-strncmp.o(.rodata .rodata.*)
+    *lib_a-strncpy.o(.rodata .rodata.*)
+    *lib_a-strndup.o(.rodata .rodata.*)
+    *lib_a-strnlen.o(.rodata .rodata.*)
+    *lib_a-strrchr.o(.rodata .rodata.*)
+    *lib_a-strsep.o(.rodata .rodata.*)
+    *lib_a-strspn.o(.rodata .rodata.*)
+    *lib_a-strstr.o(.rodata .rodata.*)
+    *lib_a-strtok_r.o(.rodata .rodata.*)
+    *lib_a-strupr.o(.rodata .rodata.*)
+    *lib_a-stdio.o(.rodata .rodata.*)
+    *lib_a-syssbrk.o(.rodata .rodata.*)
+    *lib_a-sysclose.o(.rodata .rodata.*)
+    *lib_a-sysopen.o(.rodata .rodata.*)
+    *creat.o(.rodata .rodata.*)
+    *lib_a-sysread.o(.rodata .rodata.*)
+    *lib_a-syswrite.o(.rodata .rodata.*)
+    *lib_a-impure.o(.rodata .rodata.*)
+    *lib_a-tzvars.o(.rodata .rodata.*)
+    *lib_a-sf_nan.o(.rodata .rodata.*)
+    *lib_a-tzcalc_limits.o(.rodata .rodata.*)
+    *lib_a-month_lengths.o(.rodata .rodata.*)
+    *lib_a-timelocal.o(.rodata .rodata.*)
+    *lib_a-findfp.o(.rodata .rodata.*)
+    *lock.o(.rodata .rodata.*)
+    *lib_a-getenv_r.o(.rodata .rodata.*)
+    *isatty.o(.rodata .rodata.*)
+    *lib_a-fwalk.o(.rodata .rodata.*)
+    *lib_a-getenv_r.o(.rodata .rodata.*)
+    *lib_a-tzlock.o(.rodata .rodata.*)
+    *lib_a-ctype_.o(.rodata .rodata.*)
+    *lib_a-sccl.o(.rodata .rodata.*)
+    *lib_a-strptime.o(.rodata .rodata.*)
+    *lib_a-envlock.o(.rodata .rodata.*)
+    *lib_a-raise.o(.rodata .rodata.*)
+    *lib_a-strdup_r.o(.rodata .rodata.*)
+    *lib_a-system.o(.rodata .rodata.*)
+    *lib_a-strndup_r.o(.rodata .rodata.*)
diff --git a/components/esp32/ld/esp32.spiram.rom-functions-iram.ld b/components/esp32/ld/esp32.spiram.rom-functions-iram.ld
new file mode 100644 (file)
index 0000000..6f97fb6
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ If the Newlib functions in ROM aren't used (eg because the external SPI RAM workaround is active), these functions will 
+ be linked into the application directly instead. Normally, they would end up in flash, which is undesirable because esp-idf
+ and/or applications may assume that because these functions normally are in ROM, they are accessible even when flash is 
+ inaccessible. To work around this, this ld fragment places these functions in RAM instead. If the ROM functions are used,
+ these defines do nothing, so they can still be included in that situation.
+
+ This file is responsible for placing the literal and text segments in IRAM.
+*/
+
+
+    *lib_a-utoa.o(.literal .text .literal.* .text.*)
+    *lib_a-longjmp.o(.literal .text .literal.* .text.*)
+    *lib_a-setjmp.o(.literal .text .literal.* .text.*)
+    *lib_a-abs.o(.literal .text .literal.* .text.*)
+    *lib_a-div.o(.literal .text .literal.* .text.*)
+    *lib_a-labs.o(.literal .text .literal.* .text.*)
+    *lib_a-ldiv.o(.literal .text .literal.* .text.*)
+    *lib_a-quorem.o(.literal .text .literal.* .text.*)
+    *lib_a-qsort.o(.literal .text .literal.* .text.*)
+    *lib_a-utoa.o(.literal .text .literal.* .text.*)
+    *lib_a-itoa.o(.literal .text .literal.* .text.*)
+    *lib_a-atoi.o(.literal .text .literal.* .text.*)
+    *lib_a-atol.o(.literal .text .literal.* .text.*)
+    *lib_a-strtol.o(.literal .text .literal.* .text.*)
+    *lib_a-strtoul.o(.literal .text .literal.* .text.*)
+    *lib_a-wcrtomb.o(.literal .text .literal.* .text.*)
+    *lib_a-fvwrite.o(.literal .text .literal.* .text.*)
+    *lib_a-wbuf.o(.literal .text .literal.* .text.*)
+    *lib_a-wsetup.o(.literal .text .literal.* .text.*)
+    *lib_a-fputwc.o(.literal .text .literal.* .text.*)
+    *lib_a-wctomb_r.o(.literal .text .literal.* .text.*)
+    *lib_a-ungetc.o(.literal .text .literal.* .text.*)
+    *lib_a-makebuf.o(.literal .text .literal.* .text.*)
+    *lib_a-fflush.o(.literal .text .literal.* .text.*)
+    *lib_a-refill.o(.literal .text .literal.* .text.*)
+    *lib_a-s_fpclassify.o(.literal .text .literal.* .text.*)
+    *lib_a-locale.o(.literal .text .literal.* .text.*)
+    *lib_a-asctime.o(.literal .text .literal.* .text.*)
+    *lib_a-ctime.o(.literal .text .literal.* .text.*)
+    *lib_a-ctime_r.o(.literal .text .literal.* .text.*)
+    *lib_a-lcltime.o(.literal .text .literal.* .text.*)
+    *lib_a-lcltime_r.o(.literal .text .literal.* .text.*)
+    *lib_a-gmtime.o(.literal .text .literal.* .text.*)
+    *lib_a-gmtime_r.o(.literal .text .literal.* .text.*)
+    *lib_a-strftime.o(.literal .text .literal.* .text.*)
+    *lib_a-mktime.o(.literal .text .literal.* .text.*)
+    *lib_a-syswrite.o(.literal .text .literal.* .text.*)
+    *lib_a-tzset_r.o(.literal .text .literal.* .text.*)
+    *lib_a-tzset.o(.literal .text .literal.* .text.*)
+    *lib_a-toupper.o(.literal .text .literal.* .text.*)
+    *lib_a-tolower.o(.literal .text .literal.* .text.*)
+    *lib_a-toascii.o(.literal .text .literal.* .text.*)
+    *lib_a-systimes.o(.literal .text .literal.* .text.*)
+    *lib_a-time.o(.literal .text .literal.* .text.*)
+    *lib_a-bsd_qsort_r.o(.literal .text .literal.* .text.*)
+    *lib_a-qsort_r.o(.literal .text .literal.* .text.*)
+    *lib_a-gettzinfo.o(.literal .text .literal.* .text.*)
+    *lib_a-strupr.o(.literal .text .literal.* .text.*)
+    *lib_a-asctime_r.o(.literal .text .literal.* .text.*)
+    *lib_a-bzero.o(.literal .text .literal.* .text.*)
+    *lib_a-close.o(.literal .text .literal.* .text.*)
+    *lib_a-creat.o(.literal .text .literal.* .text.*)
+    *lib_a-environ.o(.literal .text .literal.* .text.*)
+    *lib_a-fclose.o(.literal .text .literal.* .text.*)
+    *lib_a-isalnum.o(.literal .text .literal.* .text.*)
+    *lib_a-isalpha.o(.literal .text .literal.* .text.*)
+    *lib_a-isascii.o(.literal .text .literal.* .text.*)
+    *lib_a-isblank.o(.literal .text .literal.* .text.*)
+    *lib_a-iscntrl.o(.literal .text .literal.* .text.*)
+    *lib_a-isdigit.o(.literal .text .literal.* .text.*)
+    *lib_a-isgraph.o(.literal .text .literal.* .text.*)
+    *lib_a-islower.o(.literal .text .literal.* .text.*)
+    *lib_a-isprint.o(.literal .text .literal.* .text.*)
+    *lib_a-ispunct.o(.literal .text .literal.* .text.*)
+    *lib_a-isspace.o(.literal .text .literal.* .text.*)
+    *lib_a-isupper.o(.literal .text .literal.* .text.*)
+    *lib_a-memccpy.o(.literal .text .literal.* .text.*)
+    *lib_a-memchr.o(.literal .text .literal.* .text.*)
+    *lib_a-memcmp.o(.literal .text .literal.* .text.*)
+    *lib_a-memcpy.o(.literal .text .literal.* .text.*)
+    *lib_a-memmove.o(.literal .text .literal.* .text.*)
+    *lib_a-memrchr.o(.literal .text .literal.* .text.*)
+    *lib_a-memset.o(.literal .text .literal.* .text.*)
+    *lib_a-open.o(.literal .text .literal.* .text.*)
+    *lib_a-rand.o(.literal .text .literal.* .text.*)
+    *lib_a-rand_r.o(.literal .text .literal.* .text.*)
+    *lib_a-read.o(.literal .text .literal.* .text.*)
+    *lib_a-rshift.o(.literal .text .literal.* .text.*)
+    *lib_a-sbrk.o(.literal .text .literal.* .text.*)
+    *lib_a-srand.o(.literal .text .literal.* .text.*)
+    *lib_a-strcasecmp.o(.literal .text .literal.* .text.*)
+    *lib_a-strcasestr.o(.literal .text .literal.* .text.*)
+    *lib_a-strcat.o(.literal .text .literal.* .text.*)
+    *lib_a-strchr.o(.literal .text .literal.* .text.*)
+    *lib_a-strcmp.o(.literal .text .literal.* .text.*)
+    *lib_a-strcoll.o(.literal .text .literal.* .text.*)
+    *lib_a-strcpy.o(.literal .text .literal.* .text.*)
+    *lib_a-strcspn.o(.literal .text .literal.* .text.*)
+    *lib_a-strdup.o(.literal .text .literal.* .text.*)
+    *lib_a-strlcat.o(.literal .text .literal.* .text.*)
+    *lib_a-strlcpy.o(.literal .text .literal.* .text.*)
+    *lib_a-strlen.o(.literal .text .literal.* .text.*)
+    *lib_a-strlwr.o(.literal .text .literal.* .text.*)
+    *lib_a-strncasecmp.o(.literal .text .literal.* .text.*)
+    *lib_a-strncat.o(.literal .text .literal.* .text.*)
+    *lib_a-strncmp.o(.literal .text .literal.* .text.*)
+    *lib_a-strncpy.o(.literal .text .literal.* .text.*)
+    *lib_a-strndup.o(.literal .text .literal.* .text.*)
+    *lib_a-strnlen.o(.literal .text .literal.* .text.*)
+    *lib_a-strrchr.o(.literal .text .literal.* .text.*)
+    *lib_a-strsep.o(.literal .text .literal.* .text.*)
+    *lib_a-strspn.o(.literal .text .literal.* .text.*)
+    *lib_a-strstr.o(.literal .text .literal.* .text.*)
+    *lib_a-strtok_r.o(.literal .text .literal.* .text.*)
+    *lib_a-strupr.o(.literal .text .literal.* .text.*)
+    *lib_a-stdio.o(.literal .text .literal.* .text.*)
+    *lib_a-syssbrk.o(.literal .text .literal.* .text.*)
+    *lib_a-sysclose.o(.literal .text .literal.* .text.*)
+    *lib_a-sysopen.o(.literal .text .literal.* .text.*)
+    *creat.o(.literal .text .literal.* .text.*)
+    *lib_a-sysread.o(.literal .text .literal.* .text.*)
+    *lib_a-syswrite.o(.literal .text .literal.* .text.*)
+    *lib_a-impure.o(.literal .text .literal.* .text.*)
+    *lib_a-tzvars.o(.literal .text .literal.* .text.*)
+    *lib_a-sf_nan.o(.literal .text .literal.* .text.*)
+    *lib_a-tzcalc_limits.o(.literal .text .literal.* .text.*)
+    *lib_a-month_lengths.o(.literal .text .literal.* .text.*)
+    *lib_a-timelocal.o(.literal .text .literal.* .text.*)
+    *lib_a-findfp.o(.literal .text .literal.* .text.*)
+    *lock.o(.literal .text .literal.* .text.*)
+    *lib_a-getenv_r.o(.literal .text .literal.* .text.*)
+    *isatty.o(.literal .text .literal.* .text.*)
+    *lib_a-fwalk.o(.literal .text .literal.* .text.*)
+    *lib_a-getenv_r.o(.literal .text .literal.* .text.*)
+    *lib_a-tzlock.o(.literal .text .literal.* .text.*)
+    *lib_a-ctype_.o(.literal .text .literal.* .text.*)
+    *lib_a-sccl.o(.literal .text .literal.* .text.*)
+    *lib_a-strptime.o(.literal .text .literal.* .text.*)
+    *lib_a-envlock.o(.literal .text .literal.* .text.*)
+    *lib_a-raise.o(.literal .text .literal.* .text.*)
+    *lib_a-strdup_r.o(.literal .text .literal.* .text.*)
+    *lib_a-system.o(.literal .text .literal.* .text.*)
+    *lib_a-strndup_r.o(.literal .text .literal.* .text.*)
index d74564495eafb449c13b5fe42eae2ce10d12f412..2367d8273cd84c9583f39f4fa4316564f136aace 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include "FreeRTOS.h"
+#include "esp_attr.h"
 #include "sdkconfig.h"
 
 #ifdef __GNUC__
@@ -19,5 +20,5 @@
 #endif
 
 #ifdef CONFIG_ESP32_DEBUG_OCDAWARE
-const int USED uxTopUsedPriority = configMAX_PRIORITIES - 1;
-#endif
\ No newline at end of file
+const int USED DRAM_ATTR uxTopUsedPriority = configMAX_PRIORITIES - 1;
+#endif
index 81e8a7734719987e673e41a0f93d2f487c54d230..3ccd3fda695f3032a24f44185caad6ae005545f4 100644 (file)
@@ -269,9 +269,7 @@ extern void vPortCleanUpTCB ( void *pxTCB );
 #define configXT_BOARD                      1   /* Board mode */
 #define configXT_SIMULATOR                                     0
 
-#if CONFIG_ESP32_ENABLE_COREDUMP
 #define configENABLE_TASK_SNAPSHOT                     1
-#endif
 
 #if CONFIG_SYSVIEW_ENABLE
 #ifndef __ASSEMBLER__
index 0433deb2af4da5707c0a0d0c5e602ebc09389d2c..9126f862e0e2ba42091812a829f9029a1586f899 100644 (file)
@@ -4991,22 +4991,24 @@ TickType_t uxReturn;
 #endif /* configUSE_TASK_NOTIFICATIONS */
 
 #if ( configENABLE_TASK_SNAPSHOT == 1 )
-
-    static void prvTaskGetSnapshot( TaskSnapshot_t *pxTaskSnapshotArray, UBaseType_t *uxTask, TCB_t *pxTCB )
-    {
-        pxTaskSnapshotArray[ *uxTask ].pxTCB = pxTCB;
-        pxTaskSnapshotArray[ *uxTask ].pxTopOfStack = (StackType_t *)pxTCB->pxTopOfStack;
-        #if( portSTACK_GROWTH < 0 )
-        {
-            pxTaskSnapshotArray[ *uxTask ].pxEndOfStack = pxTCB->pxEndOfStack;
-        }
-        #else
-        {
-            pxTaskSnapshotArray[ *uxTask ].pxEndOfStack = pxTCB->pxStack;
-        }
-        #endif
-        (*uxTask)++;
-    }
+       static void prvTaskGetSnapshot( TaskSnapshot_t *pxTaskSnapshotArray, UBaseType_t *uxTask, TCB_t *pxTCB )
+       {
+               if (pxTCB == NULL) {
+                       return;
+               }
+               pxTaskSnapshotArray[ *uxTask ].pxTCB = pxTCB;
+               pxTaskSnapshotArray[ *uxTask ].pxTopOfStack = (StackType_t *)pxTCB->pxTopOfStack;
+               #if( portSTACK_GROWTH < 0 )
+               {
+                       pxTaskSnapshotArray[ *uxTask ].pxEndOfStack = pxTCB->pxEndOfStack;
+               }
+               #else
+               {
+                       pxTaskSnapshotArray[ *uxTask ].pxEndOfStack = pxTCB->pxStack;
+               }
+               #endif
+               (*uxTask)++;
+       }
 
        static void prvTaskGetSnapshotsFromList( TaskSnapshot_t *pxTaskSnapshotArray, UBaseType_t *uxTask, const UBaseType_t uxArraySize, List_t *pxList )
        {
@@ -5017,12 +5019,11 @@ TickType_t uxReturn;
                        listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );
                        do
                        {
-                               listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );
-
                                if( *uxTask >= uxArraySize )
                                        break;
 
-                prvTaskGetSnapshot( pxTaskSnapshotArray, uxTask, pxNextTCB );
+                               listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );
+                               prvTaskGetSnapshot( pxTaskSnapshotArray, uxTask, pxNextTCB );
                        } while( pxNextTCB != pxFirstTCB );
                }
                else
@@ -5035,8 +5036,6 @@ TickType_t uxReturn;
        {
                UBaseType_t uxTask = 0, i = 0;
 
-PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB[ portNUM_PROCESSORS ] = { NULL };
-
 
                *pxTcbSz = sizeof(TCB_t);
                /* Fill in an TaskStatus_t structure with information on each
@@ -5052,12 +5051,11 @@ PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB[ portNUM_PROCESSORS ] = { NULL };
                task in the Blocked state. */
                prvTaskGetSnapshotsFromList( pxTaskSnapshotArray, &uxTask, uxArraySize, ( List_t * ) pxDelayedTaskList );
                prvTaskGetSnapshotsFromList( pxTaskSnapshotArray, &uxTask, uxArraySize, ( List_t * ) pxOverflowDelayedTaskList );
-        for (i = 0; i < portNUM_PROCESSORS; i++) {
-            if( uxTask >= uxArraySize )
-                    break;
-            prvTaskGetSnapshot( pxTaskSnapshotArray, &uxTask, pxCurrentTCB[ i ] );
-            prvTaskGetSnapshotsFromList( pxTaskSnapshotArray, &uxTask, uxArraySize, &( xPendingReadyList[ i ] ) );
-        }
+               for (i = 0; i < portNUM_PROCESSORS; i++) {
+                       if( uxTask >= uxArraySize )
+                               break;
+                       prvTaskGetSnapshotsFromList( pxTaskSnapshotArray, &uxTask, uxArraySize, &( xPendingReadyList[ i ] ) );
+               }
 
                #if( INCLUDE_vTaskDelete == 1 )
                {
diff --git a/components/freertos/test/test_tasks_snapshot.c b/components/freertos/test/test_tasks_snapshot.c
new file mode 100644 (file)
index 0000000..c9364cc
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ Test FreeRTOS support for core dump.
+*/
+
+#include <stdio.h>
+#include "soc/cpu.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "unity.h"
+
+#define TEST_MAX_TASKS_NUM     32
+
+/* simple test to check that in normal conditions uxTaskGetSnapshotAll does not generate exception */
+TEST_CASE("Tasks snapshot", "[freertos]")
+{
+    TaskSnapshot_t tasks[TEST_MAX_TASKS_NUM];
+    UBaseType_t tcb_sz;
+    int other_core_id = xPortGetCoreID() == 0 ? 1 : 0;
+
+    // uxTaskGetSnapshotAll is supposed to be called when all tasks on both CPUs are 
+    // inactive and can not alter FreeRTOS internal tasks lists, e.g. from panic handler
+    unsigned state = portENTER_CRITICAL_NESTED();
+#if CONFIG_FREERTOS_UNICORE == 0
+    esp_cpu_stall(other_core_id);
+#endif
+    UBaseType_t task_num = uxTaskGetSnapshotAll(tasks, TEST_MAX_TASKS_NUM, &tcb_sz);
+#if CONFIG_FREERTOS_UNICORE == 0
+    esp_cpu_unstall(other_core_id);
+#endif
+    portEXIT_CRITICAL_NESTED(state);
+
+    printf("Dumped %d tasks. TCB size %d\n", task_num, tcb_sz);
+    TEST_ASSERT_NOT_EQUAL(0, task_num);
+    TEST_ASSERT_NOT_EQUAL(0, tcb_sz);
+}
index 44ddd33681285378db0180bb96d950a3a95e8cd0..c5ce7a8adebaa0c66684c8960bcb244fd3c8e526 100644 (file)
@@ -23,6 +23,7 @@
 #include "tcpip_adapter.h"
 
 #include "apps/dhcpserver.h"
+#include "apps/dhcpserver_options.h"
 
 #if ESP_DHCP
 
 #define DHCPS_STATE_IDLE 5
 #define DHCPS_STATE_RELEASE 6
 
+typedef struct _list_node {
+       void *pnode;
+       struct _list_node *pnext;
+} list_node;
+
 ////////////////////////////////////////////////////////////////////////////////////
 
 static const u32_t magic_cookie  = 0x63538263;
@@ -135,7 +141,7 @@ void *dhcps_option_info(u8_t op_id, u32_t opt_len)
  *                pinsert -- the insert node of the list
  * Returns      : none
 *******************************************************************************/
-void node_insert_to_list(list_node **phead, list_node *pinsert)
+static void node_insert_to_list(list_node **phead, list_node *pinsert)
 {
     list_node *plist = NULL;
     struct dhcps_pool *pdhcps_pool = NULL;
index 9e361833d3de0dda5c73d67006f5eae8be2b7967..a0024ab5f05354fb72368d50b13566411d3cfb8f 100644 (file)
@@ -36,123 +36,6 @@ typedef struct dhcps_msg {
         u8_t options[312];
 }dhcps_msg;
 
-/** DHCP OPTIONS CODE **/
-typedef enum
-{
-    /* RFC 1497 Vendor Extensions */
-
-    PAD = 0,
-    END = 255,
-
-    SUBNET_MASK = 1,
-    TIME_OFFSET = 2,
-    ROUTER = 3,
-    TIME_SERVER = 4,
-    NAME_SERVER = 5,
-    DOMAIN_NAME_SERVER = 6,
-    LOG_SERVER = 7,
-    COOKIE_SERVER = 8,
-    LPR_SERVER = 9,
-    IMPRESS_SERVER = 10,
-    RESOURCE_LOCATION_SERVER = 11,
-    HOST_NAME = 12,
-    BOOT_FILE_SIZE = 13,
-    MERIT_DUMP_FILE = 14,
-    DOMAIN_NAME = 15,
-    SWAP_SERVER = 16,
-    ROOT_PATH = 17,
-    EXTENSIONS_PATH = 18,
-
-    /* IP Layer Parameters per Host */
-
-    IP_FORWARDING = 19,
-    NON_LOCAL_SOURCE_ROUTING = 20,
-    POLICY_FILTER = 21,
-    MAXIMUM_DATAGRAM_REASSEMBLY_SIZE = 22,
-    DEFAULT_IP_TIME_TO_LIVE = 23,
-    PATH_MTU_AGING_TIMEOUT = 24,
-    PATH_MTU_PLATEAU_TABLE = 25,
-
-    /* IP Layer Parameters per Interface */
-
-    INTERFACE_MTU = 26,
-    ALL_SUBNETS_ARE_LOCAL = 27,
-    BROADCAST_ADDRESS = 28,
-    PERFORM_MASK_DISCOVERY = 29,
-    MASK_SUPPLIER = 30,
-    PERFORM_ROUTER_DISCOVERY = 31,
-    ROUTER_SOLICITATION_ADDRESS = 32,
-    STATIC_ROUTE = 33,
-
-    /* Link Layer Parameters per Interface */
-
-    TRAILER_ENCAPSULATION = 34,
-    ARP_CACHE_TIMEOUT = 35,
-    ETHERNET_ENCAPSULATION = 36,
-
-    /* TCP Parameters */
-
-    TCP_DEFAULT_TTL = 37,
-    TCP_KEEPALIVE_INTERVAL = 38,
-    TCP_KEEPALIVE_GARBAGE = 39,
-
-    /* Application and Service Parameters */
-
-    NETWORK_INFORMATION_SERVICE_DOMAIN = 40,
-    NETWORK_INFORMATION_SERVERS = 41,
-    NETWORK_TIME_PROTOCOL_SERVERS = 42,
-    VENDOR_SPECIFIC_INFORMATION = 43,
-    NETBIOS_OVER_TCP_IP_NAME_SERVER = 44,
-    NETBIOS_OVER_TCP_IP_DATAGRAM_DISTRIBUTION_SERVER = 45,
-    NETBIOS_OVER_TCP_IP_NODE_TYPE = 46,
-    NETBIOS_OVER_TCP_IP_SCOPE = 47,
-    X_WINDOW_SYSTEM_FONT_SERVER = 48,
-    X_WINDOW_SYSTEM_DISPLAY_MANAGER = 49,
-    NETWORK_INFORMATION_SERVICE_PLUS_DOMAIN = 64,
-    NETWORK_INFORMATION_SERVICE_PLUS_SERVERS = 65,
-    MOBILE_IP_HOME_AGENT = 68,
-    SMTP_SERVER = 69,
-    POP3_SERVER = 70,
-    NNTP_SERVER = 71,
-    DEFAULT_WWW_SERVER = 72,
-    DEFAULT_FINGER_SERVER = 73,
-    DEFAULT_IRC_SERVER = 74,
-    STREETTALK_SERVER = 75,
-    STREETTALK_DIRECTORY_ASSISTANCE_SERVER = 76,
-
-    /* DHCP Extensions */
-
-    REQUESTED_IP_ADDRESS = 50,
-    IP_ADDRESS_LEASE_TIME = 51,
-    OPTION_OVERLOAD = 52,
-    TFTP_SERVER_NAME = 66,
-    BOOTFILE_NAME = 67,
-    DHCP_MESSAGE_TYPE = 53,
-    SERVER_IDENTIFIER = 54,
-    PARAMETER_REQUEST_LIST = 55,
-    MESSAGE = 56,
-    MAXIMUM_DHCP_MESSAGE_SIZE = 57,
-    RENEWAL_T1_TIME_VALUE = 58,
-    REBINDING_T2_TIME_VALUE = 59,
-    VENDOR_CLASS_IDENTIFIER = 60,
-    CLIENT_IDENTIFIER = 61,
-
-    USER_CLASS = 77,
-    FQDN = 81,
-    DHCP_AGENT_OPTIONS = 82,
-    NDS_SERVERS = 85,
-    NDS_TREE_NAME = 86,
-    NDS_CONTEXT = 87,
-    CLIENT_LAST_TRANSACTION_TIME = 91,
-    ASSOCIATED_IP = 92,
-    USER_AUTHENTICATION_PROTOCOL = 98,
-    AUTO_CONFIGURE = 116,
-    NAME_SERVICE_SEARCH = 117,
-    SUBNET_SELECTION = 118,
-    DOMAIN_SEARCH = 119,
-    CLASSLESS_ROUTE = 121,
-} dhcp_msg_option;
-
 /*   Defined in esp_misc.h */
 typedef struct {
        bool enable;
@@ -176,11 +59,6 @@ struct dhcps_pool{
        u32_t lease_timer;
 };
 
-typedef struct _list_node{
-       void *pnode;
-       struct _list_node *pnext;
-}list_node;
-
 typedef u32_t dhcps_time_t;
 typedef u8_t dhcps_offer_t;
 
diff --git a/components/lwip/include/lwip/apps/dhcpserver_options.h b/components/lwip/include/lwip/apps/dhcpserver_options.h
new file mode 100644 (file)
index 0000000..38d46f6
--- /dev/null
@@ -0,0 +1,134 @@
+// Copyright 2017 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#pragma once
+
+/** DHCP Options
+
+    This macros are not part of the public dhcpserver.h interface.
+ **/
+typedef enum
+{
+    /* RFC 1497 Vendor Extensions */
+
+    PAD = 0,
+    END = 255,
+
+    SUBNET_MASK = 1,
+    TIME_OFFSET = 2,
+    ROUTER = 3,
+    TIME_SERVER = 4,
+    NAME_SERVER = 5,
+    DOMAIN_NAME_SERVER = 6,
+    LOG_SERVER = 7,
+    COOKIE_SERVER = 8,
+    LPR_SERVER = 9,
+    IMPRESS_SERVER = 10,
+    RESOURCE_LOCATION_SERVER = 11,
+    HOST_NAME = 12,
+    BOOT_FILE_SIZE = 13,
+    MERIT_DUMP_FILE = 14,
+    DOMAIN_NAME = 15,
+    SWAP_SERVER = 16,
+    ROOT_PATH = 17,
+    EXTENSIONS_PATH = 18,
+
+    /* IP Layer Parameters per Host */
+
+    IP_FORWARDING = 19,
+    NON_LOCAL_SOURCE_ROUTING = 20,
+    POLICY_FILTER = 21,
+    MAXIMUM_DATAGRAM_REASSEMBLY_SIZE = 22,
+    DEFAULT_IP_TIME_TO_LIVE = 23,
+    PATH_MTU_AGING_TIMEOUT = 24,
+    PATH_MTU_PLATEAU_TABLE = 25,
+
+    /* IP Layer Parameters per Interface */
+
+    INTERFACE_MTU = 26,
+    ALL_SUBNETS_ARE_LOCAL = 27,
+    BROADCAST_ADDRESS = 28,
+    PERFORM_MASK_DISCOVERY = 29,
+    MASK_SUPPLIER = 30,
+    PERFORM_ROUTER_DISCOVERY = 31,
+    ROUTER_SOLICITATION_ADDRESS = 32,
+    STATIC_ROUTE = 33,
+
+    /* Link Layer Parameters per Interface */
+
+    TRAILER_ENCAPSULATION = 34,
+    ARP_CACHE_TIMEOUT = 35,
+    ETHERNET_ENCAPSULATION = 36,
+
+    /* TCP Parameters */
+
+    TCP_DEFAULT_TTL = 37,
+    TCP_KEEPALIVE_INTERVAL = 38,
+    TCP_KEEPALIVE_GARBAGE = 39,
+
+    /* Application and Service Parameters */
+
+    NETWORK_INFORMATION_SERVICE_DOMAIN = 40,
+    NETWORK_INFORMATION_SERVERS = 41,
+    NETWORK_TIME_PROTOCOL_SERVERS = 42,
+    VENDOR_SPECIFIC_INFORMATION = 43,
+    NETBIOS_OVER_TCP_IP_NAME_SERVER = 44,
+    NETBIOS_OVER_TCP_IP_DATAGRAM_DISTRIBUTION_SERVER = 45,
+    NETBIOS_OVER_TCP_IP_NODE_TYPE = 46,
+    NETBIOS_OVER_TCP_IP_SCOPE = 47,
+    X_WINDOW_SYSTEM_FONT_SERVER = 48,
+    X_WINDOW_SYSTEM_DISPLAY_MANAGER = 49,
+    NETWORK_INFORMATION_SERVICE_PLUS_DOMAIN = 64,
+    NETWORK_INFORMATION_SERVICE_PLUS_SERVERS = 65,
+    MOBILE_IP_HOME_AGENT = 68,
+    SMTP_SERVER = 69,
+    POP3_SERVER = 70,
+    NNTP_SERVER = 71,
+    DEFAULT_WWW_SERVER = 72,
+    DEFAULT_FINGER_SERVER = 73,
+    DEFAULT_IRC_SERVER = 74,
+    STREETTALK_SERVER = 75,
+    STREETTALK_DIRECTORY_ASSISTANCE_SERVER = 76,
+
+    /* DHCP Extensions */
+
+    REQUESTED_IP_ADDRESS = 50,
+    IP_ADDRESS_LEASE_TIME = 51,
+    OPTION_OVERLOAD = 52,
+    TFTP_SERVER_NAME = 66,
+    BOOTFILE_NAME = 67,
+    DHCP_MESSAGE_TYPE = 53,
+    SERVER_IDENTIFIER = 54,
+    PARAMETER_REQUEST_LIST = 55,
+    MESSAGE = 56,
+    MAXIMUM_DHCP_MESSAGE_SIZE = 57,
+    RENEWAL_T1_TIME_VALUE = 58,
+    REBINDING_T2_TIME_VALUE = 59,
+    VENDOR_CLASS_IDENTIFIER = 60,
+    CLIENT_IDENTIFIER = 61,
+
+    USER_CLASS = 77,
+    FQDN = 81,
+    DHCP_AGENT_OPTIONS = 82,
+    NDS_SERVERS = 85,
+    NDS_TREE_NAME = 86,
+    NDS_CONTEXT = 87,
+    CLIENT_LAST_TRANSACTION_TIME = 91,
+    ASSOCIATED_IP = 92,
+    USER_AUTHENTICATION_PROTOCOL = 98,
+    AUTO_CONFIGURE = 116,
+    NAME_SERVICE_SEARCH = 117,
+    SUBNET_SELECTION = 118,
+    DOMAIN_SEARCH = 119,
+    CLASSLESS_ROUTE = 121,
+} dhcp_msg_option;
index 57759ecd83798fda1280f998e70c9076cdad0408..0f06def07ea0cd18e58cfb4831c1af590f86f6d9 100644 (file)
@@ -402,6 +402,7 @@ static esp_err_t nvs_get_str_or_blob(nvs_handle handle, nvs::ItemType type, cons
         return ESP_ERR_NVS_INVALID_LENGTH;
     }
 
+    *length = dataSize;
     return entry.mStoragePtr->readItem(entry.mNsIndex, type, key, out_value, dataSize);
 }
 
index 5a35c11f4a12ad094a6e8c90f5248baab449b5c8..f419256cf334b9b8c7db3cd0f025c96e7cd53bce 100644 (file)
@@ -530,6 +530,10 @@ TEST_CASE("nvs api tests", "[nvs]")
     TEST_ESP_ERR(ESP_ERR_NVS_INVALID_LENGTH, nvs_get_str(handle_2, "key", buf, &buf_len_short));
     CHECK(buf_len_short == buf_len);
     
+    size_t buf_len_long = buf_len + 1;
+    TEST_ESP_OK(nvs_get_str(handle_2, "key", buf, &buf_len_long));
+    CHECK(buf_len_long == buf_len);
+
     TEST_ESP_OK(nvs_get_str(handle_2, "key", buf, &buf_len));
 
     CHECK(0 == strcmp(buf, str));
index 624b219d3d21946431cd3a8ae3a56966c6701725..70f96dfd4964ec615e1aaac153cd5be8e1dc3674 100644 (file)
@@ -1,3 +1,5 @@
 COMPONENT_ADD_INCLUDEDIRS := include
 COMPONENT_PRIV_INCLUDEDIRS := spiffs/src
 COMPONENT_SRCDIRS := . spiffs/src
+
+COMPONENT_SUBMODULES := spiffs
index 25676266ac420ce82898d2245dba5e6930d01476..f9d7afe6bca8060e242e65dfe85213b45cfec480 100644 (file)
@@ -33,6 +33,7 @@
 #include "netif/ethernetif.h"
 
 #include "apps/dhcpserver.h"
+#include "apps/dhcpserver_options.h"
 
 #include "esp_event.h"
 #include "esp_log.h"
index 34e35de3de71ae08aa4dc47cf0c979681fb58281..54660741e60dbc822e741dd398dd3c0c252da713 100644 (file)
@@ -358,7 +358,7 @@ Warning On Undefined Variables
 
 By default, the build process will print a warning if an undefined variable is referenced (like ``$(DOES_NOT_EXIST)``). This can be useful to find errors in variable names.
 
-If you don't want this behaviour, it can be disabled by disabling :ref:`CONFIG_MAKE_WARN_UNDEFINED_VARIABLES`.
+If you don't want this behaviour, it can be disabled in menuconfig's top level menu under `SDK tool configuration`.
 
 Note that this option doesn't trigger a warning if ``ifdef`` or ``ifndef`` are used in Makefiles.
 
index 89833e83d73763fef94e428248ed0682a13d2df6..e4b0347f85008b8bfa9bb05c697f77dbd2e3bd12 100644 (file)
@@ -66,6 +66,7 @@ In half duplex, the length of write phase and read phase are decided by ``trans_
 ``trans_conf.rx_length`` respectively. ** Note that a half duplex transaction with both a read and 
 write phase is not supported when using DMA. ** If such transaction is needed, you have to use one 
 of the alternative solutions:
+
   1. use full-duplex mode instead.
   2. disable the DMA by set the last parameter to 0 in bus initialization function just as belows:
      ``ret=spi_bus_initialize(VSPI_HOST, &buscfg, 0);``  
@@ -109,8 +110,10 @@ Transaction data
 Normally, data to be transferred to or from a device will be read from or written to a chunk of memory
 indicated by the ``rx_buffer`` and ``tx_buffer`` members of the transaction structure. 
 When DMA is enabled for transfers, these buffers are highly recommended to meet the requirements as belows:
+
   1. allocated in DMA-capable memory using ``pvPortMallocCaps(size, MALLOC_CAP_DMA)``;
   2. 32-bit aligned (start from the boundary and have length of multiples of 4 bytes).
+
 If these requirements are not satisfied, efficiency of the transaction will suffer due to the allocation and 
 memcpy of temporary buffers.
 
index 16c8598dfee3c4b5118cf984e43068d78650ca1a..31cda9cf3df9010f9d7252f50eb39cc247ae32bf 100644 (file)
@@ -207,7 +207,7 @@ Here are couple of tips on navigation and use of ``menuconfig``:
 \r
 .. note::\r
 \r
-    Most ESP32 development boards have a 40MHz crystal installed. However, some boards use a 26MHz crystal. If your board uses a 26MHz crystal, or you get garbage output from serial port after code upload, adjust the :ref:`CONFIG_ESP32_XTAL_FREQ` option in menuconfig.\r
+    Most ESP32 development boards have a 40MHz crystal installed. However, some boards use a 26MHz crystal. If your board uses a 26MHz crystal, or you get garbage output from serial port after code upload, adjust the :ref:`CONFIG_ESP32_XTAL_FREQ_SEL` option in menuconfig.\r
 \r
 .. _get-started-build-flash:\r
 \r
index 9bc89f37ea21c2359c1abd1f1f83ffb41cc69e9d..566098d69039b52d40dd653416f2edd88b0a5b14 100644 (file)
@@ -69,6 +69,7 @@ might add it in a safe way as a client API instead."""
 import os
 import re
 import sys
+import platform
 
 # File layout:
 #
@@ -165,7 +166,8 @@ class Config(object):
         self.m = register_special_symbol(TRISTATE, "m", "m")
         self.y = register_special_symbol(TRISTATE, "y", "y")
         # DEFCONFIG_LIST uses this
-        register_special_symbol(STRING, "UNAME_RELEASE", os.uname()[2])
+        # changed os.uname to platform.uname for compatibility with Windows
+        register_special_symbol(STRING, "UNAME_RELEASE", platform.uname()[2])
 
         # The symbol with "option defconfig_list" set, containing a list of
         # default .config files
diff --git a/docs/sphinx-known-warnings.txt b/docs/sphinx-known-warnings.txt
new file mode 100644 (file)
index 0000000..3981c7b
--- /dev/null
@@ -0,0 +1,9 @@
+_build/inc/esp_a2dp_api.inc:26: WARNING: Invalid definition: Expected identifier in nested name. [error at 21]
+  union esp_a2d_mcc_t::@1  esp_a2d_mcc_t::cie
+  ---------------------^
+_build/inc/esp_bt_defs.inc:11: WARNING: Invalid definition: Expected identifier in nested name. [error at 21]
+  union esp_bt_uuid_t::@0  esp_bt_uuid_t::uuid
+  ---------------------^
+/builds/idf/esp-idf/docs/api-reference/storage/sdmmc.rst:24: WARNING: cpp:typeOrConcept targets a member (sdmmc_host_t::slot).
+/builds/idf/esp-idf/docs/api-reference/storage/sdmmc.rst:24: WARNING: cpp:typeOrConcept targets a member (sdmmc_host_t::slot).
+/builds/idf/esp-idf/docs/api-reference/storage/sdmmc.rst:24: WARNING: cpp:typeOrConcept targets a member (sdmmc_host_t::slot).
index 2bee5d759a8da7462babfc6f8803e2c3c5579d23..12d33f2de2e175d8ad5183c31916993f1f60752c 100644 (file)
@@ -233,6 +233,35 @@ static char *esp_key_type_to_str(esp_ble_key_type_t key_type)
    return key_str;
 }
 
+static void show_bonded_devices(void)
+{
+    int dev_num = esp_ble_get_bond_device_num();
+
+    esp_ble_bond_dev_t *dev_list = (esp_ble_bond_dev_t *)malloc(sizeof(esp_ble_bond_dev_t) * dev_num);
+    esp_ble_get_bond_device_list(&dev_num, dev_list);
+    ESP_LOGI(GATTS_TABLE_TAG, "Bonded devices number : %d\n", dev_num);
+
+    ESP_LOGI(GATTS_TABLE_TAG, "Bonded devices list : %d\n", dev_num);
+    for (int i = 0; i < dev_num; i++) {
+        esp_log_buffer_hex(GATTS_TABLE_TAG, (void *)dev_list[i].bd_addr, sizeof(esp_bd_addr_t));
+    }
+
+    free(dev_list);
+}
+
+static void __attribute__((unused)) remove_all_bonded_devices(void)
+{
+    int dev_num = esp_ble_get_bond_device_num();
+
+    esp_ble_bond_dev_t *dev_list = (esp_ble_bond_dev_t *)malloc(sizeof(esp_ble_bond_dev_t) * dev_num);
+    esp_ble_get_bond_device_list(&dev_num, dev_list);
+    for (int i = 0; i < dev_num; i++) {
+        esp_ble_remove_bond_device(dev_list[i].bd_addr);
+    }
+
+    free(dev_list);
+}
+
 static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
 {
     ESP_LOGV(GATTS_TABLE_TAG, "GAP_EVT, event %d\n", event);
@@ -279,23 +308,15 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param
                 (bd_addr[4] << 8) + bd_addr[5]);
         ESP_LOGI(GATTS_TABLE_TAG, "address type = %d", param->ble_security.auth_cmpl.addr_type);
         ESP_LOGI(GATTS_TABLE_TAG, "pair status = %s",param->ble_security.auth_cmpl.success ? "success" : "fail");
+        show_bonded_devices();
         break;
     }
     case ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT: {
-        ESP_LOGI(GATTS_TABLE_TAG, "ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT status = %d", param->remove_bond_dev_cmpl.status);
-        break;
-    }
-    case ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT: {
-        ESP_LOGI(GATTS_TABLE_TAG, "ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT status = %d", param->clear_bond_dev_cmpl.status);
-        break;
-    }
-    case ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT: {
-        ESP_LOGI(GATTS_TABLE_TAG, "ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT status = %d, num = %d", param->get_bond_dev_cmpl.status, param->get_bond_dev_cmpl.dev_num);
-        esp_ble_bond_dev_t *bond_dev = param->get_bond_dev_cmpl.bond_dev;
-        for(int i = 0; i < param->get_bond_dev_cmpl.dev_num; i++) {
-            ESP_LOGI(GATTS_TABLE_TAG, "mask = %x", bond_dev[i].bond_key.key_mask);
-            esp_log_buffer_hex(GATTS_TABLE_TAG, (void *)bond_dev[i].bd_addr, sizeof(esp_bd_addr_t));
-        }
+        ESP_LOGD(GATTS_TABLE_TAG, "ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT status = %d", param->remove_bond_dev_cmpl.status);
+        ESP_LOGI(GATTS_TABLE_TAG, "ESP_GAP_BLE_REMOVE_BOND_DEV");
+        ESP_LOGI(GATTS_TABLE_TAG, "-----ESP_GAP_BLE_REMOVE_BOND_DEV----");
+        esp_log_buffer_hex(GATTS_TABLE_TAG, (void *)param->remove_bond_dev_cmpl.bd_addr, sizeof(esp_bd_addr_t));
+        ESP_LOGI(GATTS_TABLE_TAG, "------------------------------------");
         break;
     }
     case ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT:
@@ -493,6 +514,12 @@ void app_main()
     esp_ble_gap_set_security_param(ESP_BLE_SM_SET_INIT_KEY, &init_key, sizeof(uint8_t));
     esp_ble_gap_set_security_param(ESP_BLE_SM_SET_RSP_KEY, &rsp_key, sizeof(uint8_t));
 
+    /* Just show how to clear all the bonded devices 
+     * Delay 30s, clear all the bonded devices
+     * 
+     * vTaskDelay(30000 / portTICK_PERIOD_MS);
+     * remove_all_bonded_devices();
+     */
 }
 
 
index edbe74394726c29e812d5beac6bcde0724ff0d3a..8c30fd326e269e6330cee2711634946e4f25bad2 100644 (file)
@@ -455,9 +455,9 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
         break;
     }
     case ESP_GATTS_ADD_CHAR_DESCR_EVT:
-        gl_profile_tab[PROFILE_A_APP_ID].descr_handle = param->add_char.attr_handle;
+        gl_profile_tab[PROFILE_A_APP_ID].descr_handle = param->add_char_descr.attr_handle;
         ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n",
-                 param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle);
+                 param->add_char_descr.status, param->add_char_descr.attr_handle, param->add_char_descr.service_handle);
         break;
     case ESP_GATTS_DELETE_EVT:
         break;
@@ -608,9 +608,9 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
                                      NULL, NULL);
         break;
     case ESP_GATTS_ADD_CHAR_DESCR_EVT:
-        gl_profile_tab[PROFILE_B_APP_ID].descr_handle = param->add_char.attr_handle;
+        gl_profile_tab[PROFILE_B_APP_ID].descr_handle = param->add_char_descr.attr_handle;
         ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n",
-                 param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle);
+                 param->add_char_descr.status, param->add_char_descr.attr_handle, param->add_char_descr.service_handle);
         break;
     case ESP_GATTS_DELETE_EVT:
         break;
diff --git a/examples/system/gcov/Makefile b/examples/system/gcov/Makefile
new file mode 100644 (file)
index 0000000..f31bb6a
--- /dev/null
@@ -0,0 +1,25 @@
+#
+# This is a project Makefile. It is assumed the directory this Makefile resides in is a
+# project subdirectory.
+#
+
+PROJECT_NAME := gcov_example
+
+include $(IDF_PATH)/make/project.mk
+
+GCOV := $(call dequote,$(CONFIG_TOOLPREFIX))gcov
+REPORT_DIR := $(BUILD_DIR_BASE)/coverage_report
+
+lcov-report:
+       echo "Generating coverage report in: $(REPORT_DIR)"
+       echo "Using gcov: $(GCOV)"
+       mkdir -p $(REPORT_DIR)/html
+       lcov --gcov-tool $(GCOV) -c -d $(BUILD_DIR_BASE) -o $(REPORT_DIR)/$(PROJECT_NAME).info
+       genhtml -o $(REPORT_DIR)/html $(REPORT_DIR)/$(PROJECT_NAME).info
+
+cov-data-clean:
+       echo "Remove coverage data files..."
+       find $(BUILD_DIR_BASE) -name "*.gcda" -exec rm {} +
+       rm -rf $(REPORT_DIR)
+
+.PHONY: lcov-report cov-data-clean
diff --git a/examples/system/gcov/README.md b/examples/system/gcov/README.md
new file mode 100644 (file)
index 0000000..effc75b
--- /dev/null
@@ -0,0 +1,112 @@
+# Blink Example with Coverage Info
+
+See the README.md file in the upper level 'examples' directory for more information about examples.
+
+GCC has useful feature which allows to generate code coverage information. Generated data show how many times every program execution paths has been taken.
+Basing on coverage data developers can detect untested pieces of code and also it gives valuable information about critical (frequently used) execution paths.
+In general case when coverage option is enabled GCC generates additional code to accumulate necessary data and save them into files. File system is not always available
+in ESP32 based projects or size of the file storage can be very limited to keep all the coverage data. To overcome those limitations IDF provides functionality
+to transfer the data to the host and save them on host file system. The data transfer is done via JTAG.
+This example shows how to generate coverage information for the program.
+
+
+## How To Gather Coverage Info
+
+Below are the steps which should be performed to obtain coverage info. Steps 1-3 are already done for this example project. They should be performed if user wants to fork new IDF-based project and needs to collect coverage info.
+
+1. Enable application tracing module in menuconfig. Choose `Trace memory` in `Component config -> Application Level Tracing -> Data Destination`.
+2. Enable coverage info generation for necessary source files. To do this add the following line to the 'component.mk' files of your project:
+`CFLAGS += --coverage`
+It will enable coverage info for all source files of your component. If you need to enable the option only for certain files you need to add the following line for every file of interest:
+`gcov_example.o: CFLAGS += --coverage`
+Replace `gcov_example.o` with path to your file.
+3. Add call to `esp_gcov_dump` function in your program. This function will wait for command from the host and dump coverage data. The exact place where to put call to `esp_gcov_dump` depends on the program.
+Usually it should be placed at the end of the program execution (at exit). See `gcov_example.c` for example.
+4. Build, flash and run program.
+5. Wait until `esp_gcov_dump` is called. To detect this a call to `printf` can be used (see `gcov_example.c`) or, for example, you can use a LED to indicate the readiness to dump data.
+6. Connect OpenOCD to the target and start telnet session with it.
+7. Run the following OpenOCD command:
+`esp32 gcov`
+Example of the command output:
+
+```
+> esp32 gcov
+Total trace memory: 16384 bytes
+Connect targets...
+Target halted. PRO_CPU: PC=0x400D0CDC (active)    APP_CPU: PC=0x00000000
+esp32: target state: halted
+Resume targets
+Targets connected.
+Open file '/home/alexey/projects/esp/esp-idf/examples/system/gcov/build/main/gcov_example.gcda'
+Open file '/home/alexey/projects/esp/esp-idf/examples/system/gcov/build/main/gcov_example.gcda'
+Open file '/home/alexey/projects/esp/esp-idf/examples/system/gcov/build/main/gcov_example_func.gcda'
+Open file '/home/alexey/projects/esp/esp-idf/examples/system/gcov/build/main/gcov_example_func.gcda'
+Disconnect targets...
+Target halted. PRO_CPU: PC=0x400D17CA (active)    APP_CPU: PC=0x400D0CDC
+esp32: target state: halted
+Resume targets
+Targets disconnected.
+>
+```
+
+As shown in the output above there can be errors reported. This is because GCOV code tries to open non-existing coverage data files for reading before writing to them. It is normal situation and actually is not an error.
+GCOV will save coverage data for every source file in directories for corresponding object files, usually under root build directory `build`.
+
+## How To Process Coverage Info
+
+There are several ways to process collected data. Two of the most common are:
+
+1. Using `gcov` tool supplied along with xtensa toolchain. See [GCOV documentation](https://gcc.gnu.org/onlinedocs/gcc/Gcov.html) for details.
+2. Using `lcov` and `genhtml` tools. This way allows to generate pretty looking coverage reports in html. This example shows how to add build target to generate such kind of reports.
+Add the following lines to you project's `Makefile` after the line including `project.mk`:
+
+```
+GCOV := $(call dequote,$(CONFIG_TOOLPREFIX))gcov
+REPORT_DIR := $(BUILD_DIR_BASE)/coverage_report
+
+lcov-report:
+       echo "Generating coverage report in: $(REPORT_DIR)"
+       echo "Using gcov: $(GCOV)"
+       mkdir -p $(REPORT_DIR)/html
+       lcov --gcov-tool $(GCOV) -c -d $(BUILD_DIR_BASE) -o $(REPORT_DIR)/$(PROJECT_NAME).info
+       genhtml -o $(REPORT_DIR)/html $(REPORT_DIR)/$(PROJECT_NAME).info
+
+cov-data-clean:
+       echo "Remove coverage data files..."
+       find $(BUILD_DIR_BASE) -name "*.gcda" -exec rm {} +
+       rm -rf $(REPORT_DIR)
+
+.PHONY: lcov-report cov-data-clean
+```
+
+Those lines add two build targets:
+* `lcov-report` - generates html coverage report in `$(BUILD_DIR_BASE)/coverage_report/html` directory.
+* `cov-data-clean` - removes all coverage data files and reports.
+
+To generate report type the following command:
+`make lcov-report`
+
+The sample output of the command is below:
+
+```
+Generating coverage report in: /home/alexey/projects/esp/esp-idf/examples/system/gcov/build/coverage_report
+Using gcov: ~/projects/esp/crosstool-NG/builds/xtensa-esp32-elf/bin/xtensa-esp32-elf-gcov
+Capturing coverage data from /home/alexey/projects/esp/esp-idf/examples/system/gcov/build
+Found gcov version: 5.2.0
+Scanning /home/alexey/projects/esp/esp-idf/examples/system/gcov/build for .gcda files ...
+Found 2 data files in /home/alexey/projects/esp/esp-idf/examples/system/gcov/build
+Processing main/gcov_example_func.gcda
+Processing main/gcov_example.gcda
+Finished .info-file creation
+Reading data file /home/alexey/projects/esp/esp-idf/examples/system/gcov/build/coverage_report/gcov_example.info
+Found 2 entries.
+Found common filename prefix "/home/alexey/projects/esp/esp-idf/examples/system/gcov"
+Writing .css and .png files.
+Generating output.
+Processing file main/gcov_example.c
+Processing file main/gcov_example_func.c
+Writing directory view page.
+Overall coverage rate:
+  lines......: 90.0% (18 of 20 lines)
+  functions..: 100.0% (3 of 3 functions)
+```
\ No newline at end of file
diff --git a/examples/system/gcov/main/Kconfig.projbuild b/examples/system/gcov/main/Kconfig.projbuild
new file mode 100644 (file)
index 0000000..f44a3df
--- /dev/null
@@ -0,0 +1,14 @@
+menu "Example Configuration"
+
+config BLINK_GPIO
+    int "Blink GPIO number"
+       range 0 34
+       default 5
+       help
+               GPIO number (IOxx) to blink on and off.
+
+               Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to blink.
+
+               GPIOs 35-39 are input-only so cannot be used as outputs.
+
+endmenu
diff --git a/examples/system/gcov/main/component.mk b/examples/system/gcov/main/component.mk
new file mode 100644 (file)
index 0000000..ed258ed
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# "main" pseudo-component makefile.
+#
+# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
+
+CFLAGS += --coverage
diff --git a/examples/system/gcov/main/gcov_example.c b/examples/system/gcov/main/gcov_example.c
new file mode 100644 (file)
index 0000000..c323886
--- /dev/null
@@ -0,0 +1,55 @@
+/* Blink Example with covergae info
+
+   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 "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "driver/gpio.h"
+#include "esp_app_trace.h"
+#include "sdkconfig.h"
+
+/* Can run 'make menuconfig' to choose the GPIO to blink,
+   or you can edit the following line and set a number here.
+*/
+#define BLINK_GPIO CONFIG_BLINK_GPIO
+
+void blink_dummy_func(void);
+
+void blink_task(void *pvParameter)
+{
+    int dump_gcov_after = 2;
+    /* Configure the IOMUX register for pad BLINK_GPIO (some pads are
+       muxed to GPIO on reset already, but some default to other
+       functions and need to be switched to GPIO. Consult the
+       Technical Reference for a list of pads and their default
+       functions.)
+    */
+    gpio_pad_select_gpio(BLINK_GPIO);
+    /* Set the GPIO as a push/pull output */
+    gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
+    while(dump_gcov_after-- > 0) {
+        /* Blink off (output low) */
+        gpio_set_level(BLINK_GPIO, 0);
+        vTaskDelay(1000 / portTICK_PERIOD_MS);
+        /* Blink on (output high) */
+        gpio_set_level(BLINK_GPIO, 1);
+        vTaskDelay(1000 / portTICK_PERIOD_MS);
+        blink_dummy_func();
+    }
+
+    // Dump gcov data
+    printf("Ready to dump GCOV data...\n");
+    esp_gcov_dump();
+    printf("GCOV data have been dumped.\n");
+    while(1);
+}
+
+void app_main()
+{
+    xTaskCreate(&blink_task, "blink_task", configMINIMAL_STACK_SIZE, NULL, 5, NULL);
+}
diff --git a/examples/system/gcov/main/gcov_example_func.c b/examples/system/gcov/main/gcov_example_func.c
new file mode 100644 (file)
index 0000000..b65b242
--- /dev/null
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+
+void blink_dummy_func(void)
+{
+    static int i;
+    printf("Counter = %d\n", i++);
+}
+
diff --git a/examples/system/gcov/sdkconfig.defaults b/examples/system/gcov/sdkconfig.defaults
new file mode 100644 (file)
index 0000000..7cf11e0
--- /dev/null
@@ -0,0 +1,7 @@
+CONFIG_ESP32_APPTRACE_DEST_TRAX=y
+# CONFIG_ESP32_APPTRACE_DEST_NONE is not set
+CONFIG_ESP32_APPTRACE_ENABLE=y
+CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y
+CONFIG_ESP32_APPTRACE_ONPANIC_HOST_FLUSH_TMO=-1
+CONFIG_ESP32_APPTRACE_POSTMORTEM_FLUSH_TRAX_THRESH=0
+CONFIG_ESP32_APPTRACE_PENDING_DATA_SIZE_MAX=0
index b140db7145b3e4616d8ab81d7a179bba3b368b32..eb90b0a465fb3a3f8ba4014c37211fabcc08d353 100644 (file)
@@ -125,7 +125,7 @@ COMPONENT_DIRS += $(abspath $(SRCDIRS))
 endif
 
 # The project Makefile can define a list of components, but if it does not do this we just take all available components
-# in the component dirs. A component is COMPONENT_DIRS directory, or immediate subdirectory, 
+# in the component dirs. A component is COMPONENT_DIRS directory, or immediate subdirectory,
 # which contains a component.mk file.
 #
 # Use the "make list-components" target to debug this step.
@@ -222,6 +222,7 @@ LDFLAGS ?= -nostdlib \
        $(COMPONENT_LDFLAGS) \
        -lgcc \
        -lstdc++ \
+       -lgcov \
        -Wl,--end-group \
        -Wl,-EL