aws / amazon-freertos

DEPRECATED - See README.md
https://aws.amazon.com/freertos/
MIT License
2.54k stars 1.1k forks source link

[General] Cannot use Bluedroid, NVS crashes/panics #3536

Closed taherrera closed 1 year ago

taherrera commented 2 years ago

Hello,

I am trying to use bluetooth classic on the ESP32. For this I basically copied the Arduino implementation of bluetooth for the ESP32. On ESP-IDF v4.4, this bluetooth implementation works perfectly, however on Amazon-Freertos it does not work.

To use this library, I have to change the menuconfig and use these configurations: Bluetooth controller -> BR/EDR Only Bluetooth Host -> Bluedroid - Dual-mode Bluedroid options -> Classic Bluetooth Bluedroid options -> Classic Bluetooth -> SPP

When I build the project, these lines stand out for me:

-- Project sdkconfig file /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/sdkconfig
Loading defaults file /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/sdkconfig.defaults...
/home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/sdkconfig.defaults:21 CONFIG_NIMBLE_ENABLED was replaced with CONFIG_BT_NIMBLE_ENABLED
/home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/sdkconfig.defaults:22 CONFIG_NIMBLE_MAX_CONNECTIONS was replaced with CONFIG_BT_NIMBLE_MAX_CONNECTIONS
...
...
**/tmp/confgen_tmpdfx8oq18:20 line was updated to CONFIG_BT_BLUEDROID_ENABLED=n**
...

Is Bluedroid being disabled by Amazon-FreeRTOS ? I am confused by this line.

When I initialize bluetooth I can see it broadcasting on my phone, however, when I try to pair I get this error:

Re-enable cpu cache.
Guru Meditation Error: Core  0 panic'ed (Cache disabled but cached memory region accessed). 

Core  0 register dump:
PC      : 0x400d38d8  PS      : 0x00060734  A0      : 0x80083765  A1      : 0x3ffbe0f0  
0x400d38d8: xQueueReceiveFromISR at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/freertos_kernel/queue.c:1834

A2      : 0x3ff81928  A3      : 0x3ffbe110  A4      : 0x3ff101b4  A5      : 0x4008e104  
0x4008e104: _frxt_int_enter at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/freertos_kernel/portable/ThirdParty/GCC/Xtensa_ESP32/portasm.S:119

A6      : 0x00000100  A7      : 0x3ffcaec0  A8      : 0x800826a4  A9      : 0x00000001  
A10     : 0x3ff81928  A11     : 0x00000000  A12     : 0x3ffbe110  A13     : 0x3ffb9274  
A14     : 0x40088d34  A15     : 0x3ffcaed1  SAR     : 0x0000001a  EXCCAUSE: 0x00000007  
0x40088d34: r_ld_fm_frame_isr at ??:?

EXCVADDR: 0x00000000  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0xffffffff  
Core  0 was running in ISR context:
EPC1    : 0x4008d53a  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x400d38d8
0x4008d53a: coex_is_in_isr_wrapper at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/esp_wifi/esp32/esp_adapter.c:577

0x400d38d8: xQueueReceiveFromISR at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/freertos_kernel/queue.c:1834

Backtrace:0x400d38d5:0x3ffbe0f0 0x40083762:0x3ffbe110 0x40083b7e:0x3ffbe150 0x4008370d:0x3ffbe190 0x40080db5:0x3ffbe1b0 0x400887f2:0x3ffbe1d0 0x40088d4a:0x3ffbe1f0 0x4008c866:0x3ffbe220 0x4008d1e7:0x3ffbe240 0x400813ee:0x3ffbe260 0x40082bba:0x3ffcaef0 0x40082ea4:0x3ffcaf10 0x40091115:0x3ffcaf40 0x400916dd:0x3ffcaf60 0x400834c6:0x3ffcaf90 0x40083539:0x3ffcafe0 0x400fe3ad:0x3ffcb000 0x400fd399:0x3ffcb020 0x400fd685:0x3ffcb040 0x400fc135:0x3ffcb0b0 0x400fc581:0x3ffcb130 0x400fcbb7:0x3ffcb1a0 0x400fbc57:0x3ffcb1c0 0x400f4756:0x3ffcb1f0 0x400eb59a:0x3ffcb250 0x400d5841:0x3ffcb270 0x400eb7ed:0x3ffcb2c0 0x400eba2a:0x3ffcb410 0x400e7ee9:0x3ffcb440 0x400e9026:0x3ffcb460
0x400d38d5: xQueueTakeMutexRecursive at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/freertos_kernel/queue.c:706

0x40083762: coex_bb_reset_unlock at ??:?

0x40083b7e: coex_core_release at ??:?

0x4008370d: coex_bt_release at ??:?

0x40080db5: coex_bt_release_wrapper at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/bt/controller/bt.c:1047

0x400887f2: coex_classic_bt_release$part$0 at ld_fm.c:?

0x40088d4a: r_ld_fm_frame_isr at ??:?

0x4008c866: r_rwbt_isr at ??:?

0x4008d1e7: r_rwbtdm_isr_wrapper at intc.c:?

0x400813ee: _xt_lowint1 at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/freertos_kernel/portable/ThirdParty/GCC/Xtensa_ESP32/xtensa_vectors.S:1193

0x40082bba: DPORT_SEQUENCE_REG_READ at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/soc/soc/esp32/include/soc/dport_access.h:110
 (inlined by) is_page_mapped_in_cache at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/spi_flash/flash_mmap.c:484

0x40082ea4: spi_flash_check_and_flush_cache at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/spi_flash/flash_mmap.c:516

0x40091115: memspi_host_flush_cache at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/spi_flash/memspi_host_driver.c:132

0x400916dd: spi_flash_chip_generic_write at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/spi_flash/spi_flash_chip_generic.c:202

0x400834c6: esp_flash_write at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/spi_flash/esp_flash_api.c:616

0x40083539: spi_flash_write at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/spi_flash/esp_flash_api.c:756

0x400fe3ad: nvs::nvs_flash_write(unsigned int, void const*, unsigned int) at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/nvs_flash/src/nvs_ops.cpp:72

0x400fd399: nvs::Page::writeEntry(nvs::Item const&) at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/nvs_flash/src/nvs_page.cpp:104

0x400fd685: nvs::Page::writeItem(unsigned char, nvs::ItemType, char const*, void const*, unsigned int, unsigned char) at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/nvs_flash/src/nvs_page.cpp:257

0x400fc135: nvs::Storage::writeMultiPageBlob(unsigned char, char const*, void const*, unsigned int, nvs::VerOffset) at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/nvs_flash/src/nvs_storage.cpp:249

0x400fc581: nvs::Storage::writeItem(unsigned char, nvs::ItemType, char const*, void const*, unsigned int) at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/nvs_flash/src/nvs_storage.cpp:310
 (inlined by) nvs::Storage::writeItem(unsigned char, nvs::ItemType, char const*, void const*, unsigned int) at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/nvs_flash/src/nvs_storage.cpp:266

0x400fcbb7: nvs::NVSHandleSimple::set_blob(char const*, void const*, unsigned int) at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/nvs_flash/src/nvs_handle_simple.cpp:52
 (inlined by) nvs::NVSHandleSimple::set_blob(char const*, void const*, unsigned int) at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/nvs_flash/src/nvs_handle_simple.cpp:47

0x400fbc57: nvs_set_blob at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/nvs_flash/src/nvs_api.cpp:441

0x400f4756: config_save at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/bt/common/osi/config.c:462

0x400eb59a: btc_config_flush at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/bt/host/bluedroid/btc/core/btc_config.c:314

0x400d5841: btc_storage_add_bonded_device at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/bt/host/bluedroid/btc/core/btc_storage.c:54

0x400eb7ed: btc_dm_auth_cmpl_evt at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/bt/host/bluedroid/btc/core/btc_dm.c:348 (discriminator 3)

0x400eba2a: btc_dm_sec_cb_handler at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/bt/host/bluedroid/btc/core/btc_dm.c:656

0x400e7ee9: btc_thread_handler at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/bt/common/btc/core/btc_task.c:184

0x400e9026: osi_thread_run at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/bt/common/osi/thread.c:68

As you can see, there seems to be a problem with writing to a partition. I can also see that the partition differs on Amazon FreeRTOS versus ESP-IDF.

System information

This is the Arduino Implementation of Bluetooth, I initialize Bluetooth by just calling nvs_flash_init() and then BluetoothSerial_begin("test", 0)

// Copyright 2018 Evandro Luis Copercini
//
// 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.

#include "sdkconfig.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "freertos/event_groups.h"

#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BLUEDROID_ENABLED)

#include "BluetoothSerial.h"

#include "esp_bt.h"
#include "esp_bt_main.h"
#include "esp_gap_bt_api.h"
#include "esp_bt_device.h"
#include "esp_spp_api.h"
#include <esp_log.h>

const char * _spp_server_name = "ESP32SPP";

#define RX_QUEUE_SIZE 512
#define TX_QUEUE_SIZE 32
#define SPP_TX_QUEUE_TIMEOUT 1000
#define SPP_TX_DONE_TIMEOUT 1000
#define SPP_CONGESTED_TIMEOUT 1000

static uint32_t _spp_client = 0;
static xQueueHandle _spp_rx_queue = NULL;
static xQueueHandle _spp_tx_queue = NULL;
static SemaphoreHandle_t _spp_tx_done = NULL;
static TaskHandle_t _spp_task_handle = NULL;
static EventGroupHandle_t _spp_event_group = NULL;
static EventGroupHandle_t _bt_event_group = NULL;
static bool secondConnectionAttempt;
static esp_spp_cb_t * custom_spp_callback = NULL;
static BluetoothSerialDataCb custom_data_callback = NULL;
static esp_bd_addr_t current_bd_addr;
static ConfirmRequestCb confirm_request_callback = NULL;
static AuthCompleteCb auth_complete_callback = NULL;

#define INQ_LEN 0x10
#define INQ_NUM_RSPS 20
#define READY_TIMEOUT (10 * 1000)
#define SCAN_TIMEOUT (INQ_LEN * 2 * 1000)
static esp_bd_addr_t _peer_bd_addr;
static char _remote_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1];
static bool _isRemoteAddressSet;
static bool _isMaster;
static esp_bt_pin_code_t _pin_code;
static int _pin_len;
static bool _isPinSet;
static bool _enableSSP;

#define SPP_RUNNING     0x01
#define SPP_CONNECTED   0x02
#define SPP_CONGESTED   0x04
#define SPP_DISCONNECTED 0x08

#define BT_DISCOVERY_RUNNING    0x01
#define BT_DISCOVERY_COMPLETED  0x02

const int INQ_TIME = 1280;   // Inquire Time unit 1280 ms
const int MIN_INQ_TIME = (ESP_BT_GAP_MIN_INQ_LEN * INQ_TIME);
const int MAX_INQ_TIME = (ESP_BT_GAP_MAX_INQ_LEN * INQ_TIME);

#include "esp_bt.h"

#ifdef CONFIG_BTDM_CONTROLLER_MODE_BTDM
#define BT_MODE ESP_BT_MODE_BTDM
#elif defined(CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY)
#define BT_MODE ESP_BT_MODE_CLASSIC_BT
#else
#define BT_MODE ESP_BT_MODE_BLE
#endif

typedef struct {
        size_t len;
        uint8_t data[];
} spp_packet_t;

#if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO)
static char *bda2str(esp_bd_addr_t bda, char *str, size_t size)
{
  if (bda == NULL || str == NULL || size < 18) {
    return NULL;
  }

  uint8_t *p = bda;
  sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
          p[0], p[1], p[2], p[3], p[4], p[5]);
  return str;
}
#endif

static bool btStarted(void){
    return (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_ENABLED);
}

static bool btStart(void){
    esp_bt_controller_config_t cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
    if(esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_ENABLED){
        return true;
    }
    if(esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_IDLE){
        esp_bt_controller_init(&cfg);
        while(esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_IDLE){}
    }
    if(esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_INITED){
        if (esp_bt_controller_enable(BT_MODE)) {
            return false;
        }
    }
    if(esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_ENABLED){
        return true;
    }
    return false;
}

static bool btStop(){
    if(esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_IDLE){
        return true;
    }
    if(esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_ENABLED){
        if (esp_bt_controller_disable()) {
            return false;
        }
        while(esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_ENABLED);
    }
    if(esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_INITED){
        if (esp_bt_controller_deinit()) {
            return false;
        }
        vTaskDelay(1);
        if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_IDLE) {          
            return false;       
        }
        return true;
    }
    return false;
}

static bool get_name_from_eir(uint8_t *eir, char *bdname, uint8_t *bdname_len)
{
    if (!eir || !bdname || !bdname_len) {
        return false;
    }

    uint8_t *rmt_bdname, rmt_bdname_len;
    *bdname = *bdname_len = rmt_bdname_len = 0;

    rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_CMPL_LOCAL_NAME, &rmt_bdname_len);
    if (!rmt_bdname) {
        rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_SHORT_LOCAL_NAME, &rmt_bdname_len);
    }
    if (rmt_bdname) {
        rmt_bdname_len = rmt_bdname_len > ESP_BT_GAP_MAX_BDNAME_LEN ? ESP_BT_GAP_MAX_BDNAME_LEN : rmt_bdname_len;
        memcpy(bdname, rmt_bdname, rmt_bdname_len);
        bdname[rmt_bdname_len] = 0;
        *bdname_len = rmt_bdname_len;
        return true;
    }
    return false;
}

static bool btSetPin() {
    esp_bt_pin_type_t pin_type;
    if (_isPinSet) {
        if (_pin_len) {
            pin_type = ESP_BT_PIN_TYPE_FIXED;
        } else {
            _isPinSet = false;
            pin_type = ESP_BT_PIN_TYPE_VARIABLE; // pin_code would be ignored (default)
        }
        return (esp_bt_gap_set_pin(pin_type, _pin_len, _pin_code) == ESP_OK);        
    }
    return false;
}

static esp_err_t _spp_queue_packet(uint8_t *data, size_t len){
    if(!data || !len){
        return ESP_OK;
    }
    spp_packet_t * packet = (spp_packet_t*)malloc(sizeof(spp_packet_t) + len);
    if(!packet){
        return ESP_FAIL;
    }
    packet->len = len;
    memcpy(packet->data, data, len);
    if (!_spp_tx_queue || xQueueSend(_spp_tx_queue, &packet, SPP_TX_QUEUE_TIMEOUT) != pdPASS) {
        free(packet);
        return ESP_FAIL;
    }
    return ESP_OK;
}

#define SPP_TX_MAX 330
static uint8_t _spp_tx_buffer[SPP_TX_MAX];
static uint16_t _spp_tx_buffer_len = 0;

static bool _spp_send_buffer(){
    if((xEventGroupWaitBits(_spp_event_group, SPP_CONGESTED, pdFALSE, pdTRUE, SPP_CONGESTED_TIMEOUT) & SPP_CONGESTED) != 0){
        if(!_spp_client){
            return false;
        }
        esp_err_t err = esp_spp_write(_spp_client, _spp_tx_buffer_len, _spp_tx_buffer);
        if(err != ESP_OK){
            return false;
        }
        _spp_tx_buffer_len = 0;
        if(xSemaphoreTake(_spp_tx_done, SPP_TX_DONE_TIMEOUT) != pdTRUE){
            return false;
        }
        return true;
    }
    return false;
}

static void _spp_tx_task(void * arg){
    //esp_task_wdt_add(NULL); //add current thread to WDT watch
    spp_packet_t *packet = NULL;
    size_t len = 0, to_send = 0;
    uint8_t * data = NULL;
    for (;;) {
        //esp_task_wdt_reset();
        if(_spp_tx_queue && xQueueReceive(_spp_tx_queue, &packet, portMAX_DELAY) == pdTRUE && packet){
            if(packet->len <= (SPP_TX_MAX - _spp_tx_buffer_len)){
                memcpy(_spp_tx_buffer+_spp_tx_buffer_len, packet->data, packet->len);
                _spp_tx_buffer_len+=packet->len;
                free(packet);
                packet = NULL;
                if(SPP_TX_MAX == _spp_tx_buffer_len || uxQueueMessagesWaiting(_spp_tx_queue) == 0){
                    _spp_send_buffer();
                }
            } else {
                len = packet->len;
                data = packet->data;
                to_send = SPP_TX_MAX - _spp_tx_buffer_len;
                memcpy(_spp_tx_buffer+_spp_tx_buffer_len, data, to_send);
                _spp_tx_buffer_len = SPP_TX_MAX;
                data += to_send;
                len -= to_send;
                if(!_spp_send_buffer()){
                    len = 0;
                }
                while(len >= SPP_TX_MAX){
                    memcpy(_spp_tx_buffer, data, SPP_TX_MAX);
                    _spp_tx_buffer_len = SPP_TX_MAX;
                    data += SPP_TX_MAX;
                    len -= SPP_TX_MAX;
                    if(!_spp_send_buffer()){
                        len = 0;
                        break;
                    }
                }
                if(len){
                    memcpy(_spp_tx_buffer, data, len);
                    _spp_tx_buffer_len += len;
                    if(uxQueueMessagesWaiting(_spp_tx_queue) == 0){
                        _spp_send_buffer();
                    }
                }
                free(packet);
                packet = NULL;
            }
        } else { /* something whent wrong */
        }
    }
    vTaskDelete(NULL);
    _spp_task_handle = NULL;
}

static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
{
    switch (event)
    {
    case ESP_SPP_INIT_EVT:
#ifdef ESP_IDF_VERSION_MAJOR
        esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
#else
        esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
#endif
        if (!_isMaster) {

            esp_spp_start_srv(ESP_SPP_SEC_NONE, ESP_SPP_ROLE_SLAVE, 0, _spp_server_name);
        }
        xEventGroupSetBits(_spp_event_group, SPP_RUNNING);
        break;

    case ESP_SPP_SRV_OPEN_EVT://Server connection open
        if (param->srv_open.status == ESP_SPP_SUCCESS) {

            if (!_spp_client){
                _spp_client = param->srv_open.handle;
                _spp_tx_buffer_len = 0;
            } else {
                secondConnectionAttempt = true;
                esp_spp_disconnect(param->srv_open.handle);
            }
            xEventGroupClearBits(_spp_event_group, SPP_DISCONNECTED);
            xEventGroupSetBits(_spp_event_group, SPP_CONNECTED);
        } else {

        }
        break;

    case ESP_SPP_CLOSE_EVT://Client connection closed
        if ((param->close.async == false && param->close.status == ESP_SPP_SUCCESS) || param->close.async) {

            if(secondConnectionAttempt) {
                secondConnectionAttempt = false;
            } else {
                _spp_client = 0;
                xEventGroupSetBits(_spp_event_group, SPP_DISCONNECTED);
                xEventGroupSetBits(_spp_event_group, SPP_CONGESTED);
            }        
            xEventGroupClearBits(_spp_event_group, SPP_CONNECTED);
        } else {
            /* fail */
        }
        break;

    case ESP_SPP_CONG_EVT://connection congestion status changed
        if(param->cong.cong){
            xEventGroupClearBits(_spp_event_group, SPP_CONGESTED);
        } else {
            xEventGroupSetBits(_spp_event_group, SPP_CONGESTED);
        }
        break;

    case ESP_SPP_WRITE_EVT://write operation completed
        if (param->write.status == ESP_SPP_SUCCESS) {
            if(param->write.cong){
                xEventGroupClearBits(_spp_event_group, SPP_CONGESTED);
            }
        } else {
            /* fail */
        }
        xSemaphoreGive(_spp_tx_done);//we can try to send another packet
        break;

    case ESP_SPP_DATA_IND_EVT://connection received data
        //esp_log_buffer_hex("",param->data_ind.data,param->data_ind.len); //for low level debug
        //ets_printf("r:%u\n", param->data_ind.len);

        if(custom_data_callback){
            custom_data_callback(param->data_ind.data, param->data_ind.len);
        } else if (_spp_rx_queue != NULL){
            for (int i = 0; i < param->data_ind.len; i++){
                if(xQueueSend(_spp_rx_queue, param->data_ind.data + i, (TickType_t)0) != pdTRUE){
                    break;
                }
            }
        }
        break;

    case ESP_SPP_DISCOVERY_COMP_EVT://discovery complete
        if (param->disc_comp.status == ESP_SPP_SUCCESS) {
            esp_spp_connect(ESP_SPP_SEC_AUTHENTICATE, ESP_SPP_ROLE_MASTER, param->disc_comp.scn[0], _peer_bd_addr);
        } else {
        }
        break;

    case ESP_SPP_OPEN_EVT://Client connection open
        if (!_spp_client){
                _spp_client = param->open.handle;
        } else {
            secondConnectionAttempt = true;
            esp_spp_disconnect(param->open.handle);
        }
        xEventGroupClearBits(_spp_event_group, SPP_DISCONNECTED);
        xEventGroupSetBits(_spp_event_group, SPP_CONNECTED);
        xEventGroupSetBits(_spp_event_group, SPP_CONGESTED);
        break;

    case ESP_SPP_START_EVT://server started
        break;

    case ESP_SPP_CL_INIT_EVT://client initiated a connection
        break;

    default:
        break;
    }
    if(custom_spp_callback)(*custom_spp_callback)(event, param);
}

void BluetoothSerial_onData(BluetoothSerialDataCb cb){
    custom_data_callback = cb;
}

static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
{
    switch(event){
        case ESP_BT_GAP_DISC_RES_EVT:

            break;

        case ESP_BT_GAP_DISC_STATE_CHANGED_EVT:
            if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STOPPED) {
                xEventGroupClearBits(_bt_event_group, BT_DISCOVERY_RUNNING);
                xEventGroupSetBits(_bt_event_group, BT_DISCOVERY_COMPLETED);
            } else { // ESP_BT_GAP_DISCOVERY_STARTED
                xEventGroupClearBits(_bt_event_group, BT_DISCOVERY_COMPLETED);
                xEventGroupSetBits(_bt_event_group, BT_DISCOVERY_RUNNING);
            }
            break;

        case ESP_BT_GAP_RMT_SRVCS_EVT:

            break;

        case ESP_BT_GAP_RMT_SRVC_REC_EVT:

            break;

        case ESP_BT_GAP_AUTH_CMPL_EVT:
            if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) {

                if (auth_complete_callback) {
                    auth_complete_callback(true);
                }
            } else {

                if (auth_complete_callback) {
                    auth_complete_callback(false);
                }
            }
            break;

        case ESP_BT_GAP_PIN_REQ_EVT:
            // default pairing pins

            if (param->pin_req.min_16_digit) {

                esp_bt_pin_code_t pin_code;
                memset(pin_code, '0', ESP_BT_PIN_CODE_LEN);
                esp_bt_gap_pin_reply(param->pin_req.bda, true, 16, pin_code);
            } else {

                esp_bt_pin_code_t pin_code;
                memcpy(pin_code, "1234", 4);
                esp_bt_gap_pin_reply(param->pin_req.bda, true, 4, pin_code);
            }
            break;

        case ESP_BT_GAP_CFM_REQ_EVT:

            if (confirm_request_callback) {
                memcpy(current_bd_addr, param->cfm_req.bda, sizeof(esp_bd_addr_t));
                confirm_request_callback(param->cfm_req.num_val);
            }
            else {
                esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true);
            }
            break;

        case ESP_BT_GAP_KEY_NOTIF_EVT:

            break;

        case ESP_BT_GAP_KEY_REQ_EVT:

            break;

        default:
            break;
    }
}

static bool _init_bt(const char *deviceName)
{
    if(!_bt_event_group){
        _bt_event_group = xEventGroupCreate();
        if(!_bt_event_group){

            return false;
        }
        xEventGroupClearBits(_bt_event_group, 0xFFFFFF);
    }
    if(!_spp_event_group){
        _spp_event_group = xEventGroupCreate();
        if(!_spp_event_group){

            return false;
        }
        xEventGroupClearBits(_spp_event_group, 0xFFFFFF);
        xEventGroupSetBits(_spp_event_group, SPP_CONGESTED);
        xEventGroupSetBits(_spp_event_group, SPP_DISCONNECTED);
    }
    if (_spp_rx_queue == NULL){
        _spp_rx_queue = xQueueCreate(RX_QUEUE_SIZE, sizeof(uint8_t)); //initialize the queue
        if (_spp_rx_queue == NULL){

            return false;
        }
    }
    if (_spp_tx_queue == NULL){
        _spp_tx_queue = xQueueCreate(TX_QUEUE_SIZE, sizeof(spp_packet_t*)); //initialize the queue
        if (_spp_tx_queue == NULL){

            return false;
        }
    }
    if(_spp_tx_done == NULL){
        _spp_tx_done = xSemaphoreCreateBinary();
        if (_spp_tx_done == NULL){

            return false;
        }
        xSemaphoreTake(_spp_tx_done, 0);
    }

    if(!_spp_task_handle){
        xTaskCreatePinnedToCore(_spp_tx_task, "spp_tx", 4096, NULL, 10, &_spp_task_handle, 0 /* CPU */);
        if(!_spp_task_handle){

            return false;
        }
    }

    if (!btStarted() && !btStart()){

        return false;
    }

    esp_bluedroid_status_t bt_state = esp_bluedroid_get_status();
    if (bt_state == ESP_BLUEDROID_STATUS_UNINITIALIZED){
        if (esp_bluedroid_init()) {

            return false;
        }
    }

    if (bt_state != ESP_BLUEDROID_STATUS_ENABLED){
        if (esp_bluedroid_enable()) {

            return false;
        }
    }

    // Why only master need this?  Slave need this during pairing as well
//    if (_isMaster && esp_bt_gap_register_callback(esp_bt_gap_cb) != ESP_OK) {
    if (esp_bt_gap_register_callback(esp_bt_gap_cb) != ESP_OK) {

        return false;
    }

    if (esp_spp_register_callback(esp_spp_cb) != ESP_OK){

        return false;
    }

    if (esp_spp_init(ESP_SPP_MODE_CB) != ESP_OK){

        return false;
    }

    // if (esp_bt_sleep_disable() != ESP_OK){
    //     log_e("esp_bt_sleep_disable failed");
    // }

    esp_bt_dev_set_device_name(deviceName);

    if (_isPinSet) {
        btSetPin();
    }

    if (_enableSSP) {

        esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE;
        esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO;
        esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
    }

    // the default BTA_DM_COD_LOUDSPEAKER does not work with the macOS BT stack
    esp_bt_cod_t cod;
    cod.major = 0b00001;
    cod.minor = 0b000100;
    cod.service = 0b00000010110;
    if (esp_bt_gap_set_cod(cod, ESP_BT_INIT_COD) != ESP_OK) {

        return false;
    }
    return true;
}

static bool _stop_bt()
{
    if (btStarted()){
        if(_spp_client)
            esp_spp_disconnect(_spp_client);
        esp_spp_deinit();
        esp_bluedroid_disable();
        esp_bluedroid_deinit();
        btStop();
    }
    _spp_client = 0;
    if(_spp_task_handle){
        vTaskDelete(_spp_task_handle);
        _spp_task_handle = NULL;
    }
    if(_spp_event_group){
        vEventGroupDelete(_spp_event_group);
        _spp_event_group = NULL;
    }
    if(_spp_rx_queue){
        vQueueDelete(_spp_rx_queue);
        //ToDo: clear RX queue when in packet mode
        _spp_rx_queue = NULL;
    }
    if(_spp_tx_queue){
        spp_packet_t *packet = NULL;
        while(xQueueReceive(_spp_tx_queue, &packet, 0) == pdTRUE){
            free(packet);
        }
        vQueueDelete(_spp_tx_queue);
        _spp_tx_queue = NULL;
    }
    if (_spp_tx_done) {
        vSemaphoreDelete(_spp_tx_done);
        _spp_tx_done = NULL;
    }
    if (_bt_event_group) {
        vEventGroupDelete(_bt_event_group);
        _bt_event_group = NULL;
    }
    return true;
}

static bool waitForConnect(int timeout) {
    TickType_t xTicksToWait = timeout / portTICK_PERIOD_MS;
    return (xEventGroupWaitBits(_spp_event_group, SPP_CONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_CONNECTED) != 0;
}

static bool waitForDiscovered(int timeout) {
    TickType_t xTicksToWait = timeout / portTICK_PERIOD_MS;
    return (xEventGroupWaitBits(_spp_event_group, BT_DISCOVERY_COMPLETED, pdFALSE, pdTRUE, xTicksToWait) & BT_DISCOVERY_COMPLETED) != 0;
}

bool BluetoothSerial_begin(char * local_name, bool isMaster)
{
    _isMaster = isMaster;
    return _init_bt(local_name);
}

int BluetoothSerial_available(void)
{
    if (_spp_rx_queue == NULL){
        return 0;
    }
    return uxQueueMessagesWaiting(_spp_rx_queue);
}

int BluetoothSerial_peek(void)
{
    uint8_t c;
    if (_spp_rx_queue && xQueuePeek(_spp_rx_queue, &c, 0)){
        return c;
    }
    return -1;
}

bool BluetoothSerial_hasClient(void)
{
    return _spp_client > 0;
}

int BluetoothSerial_read(void)
{

    uint8_t c = 0;
    if (_spp_rx_queue && xQueueReceive(_spp_rx_queue, &c, 0)){
        return c;
    }
    return -1;
}

size_t BluetoothSerial_write(const uint8_t *buffer, size_t size)
{
    if (!_spp_client){
        return 0;
    }
    return (_spp_queue_packet((uint8_t *)buffer, size) == ESP_OK) ? size : 0;
}

void BluetoothSerial_flush()
{
    if (_spp_tx_queue != NULL){
        while(uxQueueMessagesWaiting(_spp_tx_queue) > 0){
           vTaskDelay(100 / portTICK_PERIOD_MS);
        }
    }
}

void BluetoothSerial_end()
{
    _stop_bt();
}

void BluetoothSerial_onConfirmRequest(ConfirmRequestCb cb)
{
    confirm_request_callback = cb;
}

void BluetoothSerial_onAuthComplete(AuthCompleteCb cb)
{
    auth_complete_callback = cb;
}

void BluetoothSerial_confirmReply(bool confirm)
{
    esp_bt_gap_ssp_confirm_reply(current_bd_addr, confirm);  
}

esp_err_t BluetoothSerial_register_callback(esp_spp_cb_t * callback)
{
    custom_spp_callback = callback;
    return ESP_OK;
}

//Simple Secure Pairing
void BluetoothSerial_enableSSP() {
    _enableSSP = true;
}
/*
     * Set default parameters for Legacy Pairing
     * Use fixed pin code
*/
bool BluetoothSerial_setPin(const char *pin) {
    bool isEmpty =  !(pin  && *pin);
    if (isEmpty && !_isPinSet) {
        return true; // nothing to do
    } else if (!isEmpty){
        _pin_len = strlen(pin);
        memcpy(_pin_code, pin, _pin_len);
    } else {
        _pin_len = 0; // resetting pin to none (default)
    }
    _pin_code[_pin_len] = 0;
    _isPinSet = true;
    if (BluetoothSerial_isReady(false, READY_TIMEOUT)) {
        btSetPin();
    }
    return true;
}

bool BluetoothSerial_connect_name(char * remoteName)
{
    if (!BluetoothSerial_isReady(true, READY_TIMEOUT)) return false;
    if (remoteName && strlen(remoteName) < 1) {

        return false; 
    }
    BluetoothSerial_disconnect();
    _isRemoteAddressSet = false;
    strncpy(_remote_name, remoteName, ESP_BT_GAP_MAX_BDNAME_LEN);
    _remote_name[ESP_BT_GAP_MAX_BDNAME_LEN] = 0;

    // will first resolve name to address
#ifdef ESP_IDF_VERSION_MAJOR
        esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
#else
        esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
#endif
    if (esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, INQ_LEN, INQ_NUM_RSPS) == ESP_OK) {
        return waitForConnect(SCAN_TIMEOUT);
    }
    return false;
}

bool BluetoothSerial_connect_addr(uint8_t remoteAddress[])
{
    if (!BluetoothSerial_isReady(true, READY_TIMEOUT)) return false;
    if (!remoteAddress) {

        return false; 
    }
    BluetoothSerial_disconnect();
    _remote_name[0] = 0;
    _isRemoteAddressSet = true;
    memcpy(_peer_bd_addr, remoteAddress, ESP_BD_ADDR_LEN);

    if (esp_spp_start_discovery(_peer_bd_addr) == ESP_OK) {
        return waitForConnect(READY_TIMEOUT);
    }
    return false;
}

bool BluetoothSerial_connect()
{
    if (!BluetoothSerial_isReady(true, READY_TIMEOUT)) return false;
    if (_isRemoteAddressSet){
        BluetoothSerial_disconnect();
        // use resolved or set address first

        if (esp_spp_start_discovery(_peer_bd_addr) == ESP_OK) {
            return waitForConnect(READY_TIMEOUT);
        }
        return false;
    } else if (_remote_name[0]) {
        BluetoothSerial_disconnect();

        // will resolve name to address first - it may take a while
#ifdef ESP_IDF_VERSION_MAJOR
        esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
#else
        esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
#endif
        if (esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, INQ_LEN, INQ_NUM_RSPS) == ESP_OK) {
            return waitForConnect(SCAN_TIMEOUT);
        }
        return false;
    }

    return false;
}

bool BluetoothSerial_disconnect() {
    if (_spp_client) {
        BluetoothSerial_flush();

        if (esp_spp_disconnect(_spp_client) == ESP_OK) {
            TickType_t xTicksToWait = READY_TIMEOUT / portTICK_PERIOD_MS;
            return (xEventGroupWaitBits(_spp_event_group, SPP_DISCONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_DISCONNECTED) != 0;
        }
    }
    return false;
}

bool BluetoothSerial_unpairDevice(uint8_t remoteAddress[]) {
    if (BluetoothSerial_isReady(false, READY_TIMEOUT)) {

        return (esp_bt_gap_remove_bond_device(remoteAddress) == ESP_OK);
    }
    return false;
}

bool BluetoothSerial_connected(int timeout) {
    return waitForConnect(timeout);
}

bool BluetoothSerial_isReady(bool checkMaster, int timeout) {
    if (checkMaster && !_isMaster) {

        return false;
    }
    if (!btStarted()) {

        return false;
    }
    TickType_t xTicksToWait = timeout / portTICK_PERIOD_MS;
    return (xEventGroupWaitBits(_spp_event_group, SPP_RUNNING, pdFALSE, pdTRUE, xTicksToWait) & SPP_RUNNING) != 0;
}

#else

#error "must define CONFIG_BT_ENABLED & CONFIG_BLUEDROID_ENABLED"

#endif // if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BLUEDROID_ENABLED)

And this is the .h file:

// Copyright 2018 Evandro Luis Copercini
//
// 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.

#ifndef _BLUETOOTH_SERIAL_H_
#define _BLUETOOTH_SERIAL_H_

#include "sdkconfig.h"

#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BLUEDROID_ENABLED) && defined(CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY)

#include <esp_gap_bt_api.h>
#include <esp_spp_api.h>
//#include "BTScan.h"
#include <string.h>

typedef void (*BluetoothSerialDataCb)(const uint8_t *, size_t);
typedef void  (*ConfirmRequestCb)(uint32_t);
typedef void (*AuthCompleteCb)(bool);
//typedef void (*BTAdvertisedDeviceCb)(BTAdvertisedDevice*);

bool BluetoothSerial_begin(char * localName, bool isMaster);
int BluetoothSerial_available(void);
int BluetoothSerial_peek(void);
bool BluetoothSerial_hasClient(void);
int BluetoothSerial_read(void);
size_t BluetoothSerial_write(const uint8_t *buffer, size_t size);
void BluetoothSerial_flush(void);
void BluetoothSerial_end(void);
void BluetoothSerial_onData(BluetoothSerialDataCb cb);
esp_err_t BluetoothSerial_register_callback(esp_spp_cb_t * callback);

void BluetoothSerial_onConfirmRequest(ConfirmRequestCb cb);
void BluetoothSerial_onAuthComplete(AuthCompleteCb cb);
void BluetoothSerial_confirmReply(bool confirm);

void BluetoothSerial_enableSSP();
bool BluetoothSerial_setPin(const char *pin);
bool BluetoothSerial_connect_name(char * remoteName);
bool BluetoothSerial_connect_addr(uint8_t remoteAddress[]);
bool BluetoothSerial_connect();
bool BluetoothSerial_connected(int timeout/*=0*/);
bool BluetoothSerial_isReady(bool checkMaster/*=false*/, int timeout/*=0*/);
bool BluetoothSerial_disconnect();
bool BluetoothSerial_unpairDevice(uint8_t remoteAddress[]);

char * BluetoothSerial_local_name;

#else
#error You must enable bluetooth classic in menuconfig and Bluetooth controler mode (BR/EDR Only)

#endif

#endif
kstribrnAmzn commented 2 years ago

I'm going to start looking into this. I hope to have an answer for you in the next few days.

kstribrnAmzn commented 1 year ago

A few things I noticed...

To use this library, I have to change the menuconfig and use these configurations:

This library being the esp-idf library?


Is Bluedroid being disabled by Amazon-FreeRTOS ? I am confused by this line.

I don't think so. This configuration looks to be set in an sdk configuration file provided by esp-idf. See this. You may need to set this value.


Can you provide a link to whatever you're basing your demo off of? Looking through your code I see where you create the Bluetooth task but I'm not seeing the scheduler being started anywhere. Is this being started somewhere else?


Near the very top of your stack trace points to this function in esp-idf. From there it spirals into the esp-idf framework a bit. Your post may be better answered by the Espressif/ESP32 forums as this might be as simple as a configuration issue.

taherrera commented 1 year ago

Hello,

This library being the esp-idf library?

I mean the library I translated from here into my project.

I don't think so. This configuration looks to be set in an sdk configuration file provided by esp-idf. See this. You may need to set this value.

I changed the configurations on the file you are mentioning to:

CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=n
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=y
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=y
CONFIG_BT_NIMBLE_ENABLED=n

But I still see the line: /tmp/confgen_tmptfuyjhj6:20 line was updated to CONFIG_BT_BLUEDROID_ENABLED=n

Can you provide a link to whatever you're basing your demo off of? Looking through your code I see where you create the Bluetooth task but I'm not seeing the scheduler being started anywhere. Is this being started somewhere else?

I am not sure how to start the scheduler, you mean vTaskStartScheduler()? I was not calling this function, so I added this to the main.c but it still fails, now with a slightly different error though. I uploaded the entire project to: https://github.com/taherrera/AFR-Bluedroid. This is the error:

Re-enable cpu cache.
Guru Meditation Error: Core  0 panic'ed (Cache disabled but cached memory region accessed). 

Core  0 register dump:
PC      : 0x400d3754  PS      : 0x00060034  A0      : 0x8008cf46  A1      : 0x3ffbe1f0  
0x400d3754: xQueueGenericSendFromISR at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/freertos_kernel/queue.c:987

A2      : 0x3ffbc404  A3      : 0x3ffbe210  A4      : 0x3ffbe218  A5      : 0x3ffce250  
A6      : 0x3ffbe68c  A7      : 0x3ffd37fc  A8      : 0x80080e25  A9      : 0x3ffbe1e0  
A10     : 0x3ffbc404  A11     : 0x3ffbe210  A12     : 0x3ffbe218  A13     : 0x00000000  
A14     : 0xfffff000  A15     : 0x00000100  SAR     : 0x00000020  EXCCAUSE: 0x00000007  
EXCVADDR: 0x00000000  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0xffffffff  
Core  0 was running in ISR context:
EPC1    : 0x40008544  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x400d3754
0x400d3754: xQueueGenericSendFromISR at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/freertos_kernel/queue.c:987

Backtrace:0x400d3751:0x3ffbe1f0 0x4008cf43:0x3ffbe210 0x4008d1ed:0x3ffbe240 0x400813ee:0x3ffbe260 0x40008541:0x3ffce180 0x400835ad:0x3ffce1a0 0x40091523:0x3ffce1c0 0x40091436:0x3ffce200 0x40091725:0x3ffce220 0x400834c6:0x3ffce250 0x40083539:0x3ffce2a0 0x401224c5:0x3ffce2c0 0x40121689:0x3ffce2e0 0x40121809:0x3ffce300 0x401201b6:0x3ffce370 0x401206f9:0x3ffce3f0 0x40120d2f:0x3ffce460 0x4011fe73:0x3ffce480 0x401007f2:0x3ffce4b0 0x400d6626:0x3ffce510 0x400d678d:0x3ffce530 0x40105692:0x3ffce580 0x400ff721:0x3ffce740 0x40101607:0x3ffce760
0x400d3751: prvInitialiseMutex at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/freertos_kernel/queue.c:509
 (inlined by) prvInitialiseMutex at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/freertos_kernel/queue.c:492
 (inlined by) xQueueCreateMutex at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/freertos_kernel/queue.c:528

0x4008cf43: btdm_task_post_from_isr at ??:?

0x4008d1ed: r_rwbtdm_isr_wrapper at intc.c:?

0x400813ee: _xt_lowint1 at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/freertos_kernel/portable/ThirdParty/GCC/Xtensa_ESP32/xtensa_vectors.S:1193

0x400835ad: delay_us at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/spi_flash/spi_flash_os_func_app.c:102

0x40091523: spi_flash_chip_generic_wait_idle at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/spi_flash/spi_flash_chip_generic.c:283

0x40091436: spi_flash_chip_generic_page_program at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/spi_flash/spi_flash_chip_generic.c:175
 (inlined by) spi_flash_chip_generic_page_program at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/spi_flash/spi_flash_chip_generic.c:165

0x40091725: spi_flash_chip_generic_write at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/spi_flash/spi_flash_chip_generic.c:195

0x400834c6: esp_flash_write at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/spi_flash/esp_flash_api.c:616

0x40083539: spi_flash_write at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/spi_flash/esp_flash_api.c:756

0x401224c5: nvs::nvs_flash_write(unsigned int, void const*, unsigned int) at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/nvs_flash/src/nvs_ops.cpp:72

0x40121689: nvs::Page::writeEntryData(unsigned char const*, unsigned int) at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/nvs_flash/src/nvs_page.cpp:152

0x40121809: nvs::Page::writeItem(unsigned char, nvs::ItemType, char const*, void const*, unsigned int, unsigned char) at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/nvs_flash/src/nvs_page.cpp:247

0x401201b6: nvs::Storage::writeMultiPageBlob(unsigned char, char const*, void const*, unsigned int, nvs::VerOffset) at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/nvs_flash/src/nvs_storage.cpp:213

0x401206f9: nvs::Storage::writeItem(unsigned char, nvs::ItemType, char const*, void const*, unsigned int) at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/nvs_flash/src/nvs_storage.cpp:310
 (inlined by) nvs::Storage::writeItem(unsigned char, nvs::ItemType, char const*, void const*, unsigned int) at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/nvs_flash/src/nvs_storage.cpp:266

0x40120d2f: nvs::NVSHandleSimple::set_blob(char const*, void const*, unsigned int) at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/nvs_flash/src/nvs_handle_simple.cpp:52
 (inlined by) nvs::NVSHandleSimple::set_blob(char const*, void const*, unsigned int) at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/nvs_flash/src/nvs_handle_simple.cpp:47

0x4011fe73: nvs_set_blob at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/nvs_flash/src/nvs_api.cpp:441

0x401007f2: config_save at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/bt/common/osi/config.c:462

0x400d6626: btc_config_flush at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/bt/host/bluedroid/btc/core/btc_config.c:314

0x400d678d: btc_storage_add_bonded_device at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/bt/host/bluedroid/btc/core/btc_storage.c:54

0x40105692: btc_dm_auth_cmpl_evt at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/bt/host/bluedroid/btc/core/btc_dm.c:348
 (inlined by) btc_dm_sec_cb_handler at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/bt/host/bluedroid/btc/core/btc_dm.c:656

0x400ff721: btc_thread_handler at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/bt/common/btc/core/btc_task.c:184

0x40101607: osi_thread_run at /home/tom/Documents/SLT/tecnocal/instacrop/fw/instacrop_test/build/../amazon-freertos/vendors/espressif/esp-idf/components/bt/common/osi/thread.c:68

Near the very top of your stack trace points to this function in esp-idf. From there it spirals into the esp-idf framework a bit. Your post may be better answered by the Espressif/ESP32 forums as this might be as simple as a configuration issue.

I will ask, but it is strange because this works on ESP-IDF, so there is something different going on with AFR, causing this error. The only difference in the implementation on ESP-IDF are these functions on my main.c which I do not know why I need them on AFR, but without them I cannot compile Amazon-FreeRTOS:

extern void esp_vApplicationTickHook();
void IRAM_ATTR vApplicationTickHook(){
    esp_vApplicationTickHook();
}

extern void esp_vApplicationIdleHook();
void vApplicationIdleHook(){
    esp_vApplicationIdleHook();
}

void vApplicationDaemonTaskStartupHook( void ){
}
Skptak commented 1 year ago

Hey, I've cloned down your repository and have started looking into your problem. I'll continue this effort to see if I can better assist you with your issue.

In the meantime I was wondering if you had tried starting with an existing bluetooth demo for the STM32 board and then from there adding your needed functionality? This could ensure that you have the board and device properly working by following our documentation, at which point you could begin adding in your functions for your personal use case? We have a doc for our bluetooth demos available here, as well as a GitHub link to some demos here.

If any of these resources help you solve your problem please let me know!

laukik-hase commented 1 year ago

Hello, @taherrera!

Currently, Amazon FreeRTOS uses ESP-IDF v4.2.2. Thus, there is a great chance that the code you have (tested in ESP-IDF v4.4) might not work with AFR. Could you please try out the PR https://github.com/aws/amazon-freertos/pull/3541 and revert here if your code is working as expected?

taherrera commented 1 year ago

Hello @laukik-hase ,

I tried PR #3541 , with these commands

git clone https://github.com/aws/amazon-freertos.git --recurse-submodules
cd amazon-freertos
git fetch origin pull/3541/head:afr_branch
git checkout afr_branch
git submodule update --init --recursive --checkout

But it fails on git submodule update --init --recursive --checkout with this error:

fatal: reference is not a tree: 3ae7e4abf19a00196106d6aa4cdda27ce40cf165
fatal: reference is not a tree: b967ca054f48a36f82d8fcdd32e54ec5144f2751
Unable to checkout 'b967ca054f48a36f82d8fcdd32e54ec5144f2751' in submodule path 'vendors/espressif/esp-idf/components/nghttp/nghttp2/third-party/neverbleed'
Failed to recurse into submodule path 'vendors/espressif/esp-idf/components/nghttp/nghttp2'
Unable to checkout '3ae7e4abf19a00196106d6aa4cdda27ce40cf165' in submodule path 'freertos_kernel'
Failed to recurse into submodule path 'vendors/espressif/esp-idf'

However, I tried ESP-IDF checkout release/v4.2 and I can pair successfully, so it works con ESP-IDF 4.2 and 4.4. Now I am pretty sure there is something not allowing me to run this code with Amazon-FreeRTOS and it is not an issue originating in ESP-IDF.

Hello @Skptak,

In the meantime I was wondering if you had tried starting with an existing bluetooth demo for the STM32 board and then from there adding your needed functionality? This could ensure that you have the board and device properly working by following our documentation, at which point you could begin adding in your functions for your personal use case? We have a doc for our bluetooth demos available here, as well as a GitHub link to some demos here.

I have not tried other bluetooth solutions, because I think there is an underlying issue behind this that causes us not only not be able to use this bluetooth code, but also we have not been able to use NVS storage and cannot use the ESP-IDF 4.2 OTA functions. So since there are 3 problems related somehow to the flash storage in Amazon-FreeRTOS, we have not tried it. I first published this NVS problem as a bug but it was rapidly dismissed (see #3531) . So I lifted this issue with this bluetooth code which is more reproducible.

Skptak commented 1 year ago

Hey again,

I have not tried other bluetooth solutions, because I think there is an underlying issue behind this that causes us not only not be able to use this bluetooth code

Sorry, my intention was not to tell you to use a different bluetooth solution. I was trying to offer that by starting with one of our bluetooth demos you could verify that everything in your build system and board is working correctly. For example if you take a look at this app_main() function from the demos. You can see that there are some additional checks that happen, and functions that are called when performing the BLE setup. I felt that it might relevant to look over some of this since you're running into several different issues, directly related to using the board.

Additionally, I can't speak to the error you're receiving on the update to that pull request. I was able to do the update to that PR and then perform the build. I don't currently have access to an ESP32 to run your code to further assist you, but I'm in the process of getting one so I can help you further.

If you have any updates while I work on getting a board, please let me know.

dachalco commented 1 year ago

@taherrera

To reaffirm, you changed the esp32 configs as such?

Bluetooth controller -> BR/EDR Only
Bluetooth Host -> Bluedroid - Dual-mode
Bluedroid options -> Classic Bluetooth
Bluedroid options -> Classic Bluetooth -> SPP

If so then the the Bluetooth controller is configured for Classic Bluetooth only, but the amazon-freertos bluetooth services are GATT services that require BLE. Can you try setting Bluetooth controller to Bluetooth Dual Mode instead? You should be able to use Bluedroid, but building with amazon-freertos, NimBLE is set as the default.

Also amazon-freertos BLE services also directly use the bluedroid/nimBLE APIs. There may be some collision/clobbering, for example amazon-freertos bluetooth middleware also configures GAP.

Additionally, to clarify amazon-freertos does not technically use any version of ESP-IDF, rather it uses a fork specifically maintained for amazon-freertos, by Espressif: espressif/esp-afr-sdk. The version of it currently used by amazon-freertos is seeded from ESP-IDF v4.2.2 with some patches applied.

@mahavirj May have additional info to add.

taherrera commented 1 year ago

Thanks @dachalco , I will try your suggested change and inform you asap.

Also, I forgot to mention, that when I do not initialize the nvs, the bluetooth implementation works (although I have to pair each time to the device before connecting).

dachalco commented 1 year ago

Having to pair every time, due to omitting NVS, is expected. The bond information is supposed to persist, but if it doesn't then devices need to negotiate and exchange key information again, since it wasn't saved.

taherrera commented 1 year ago

The thing I am trying to point out is that Bluetooth works as expected and does not panic if I do not initialize the nvs.

dachalco commented 1 year ago

How are you building this code in amazon-freertos? From what I understand you've modifed the aws_demos/application_code/main.c for the esp32? What's the full diff of changes made to main.c? As mentioned earlier there's setup being done there for BLE and related NVS that should be retained. Furthermore the Arduino API should be reviewed to ensure it doesn't clobber configurations made by amazon-freertos demo.

Additionally, as I understand your code was based on IDF v4.4, but as mentioned amazon-freertos uses a fork based on v4.2. Have you reviewed that functions and usage are the same for both?

taherrera commented 1 year ago

I set this in menuconfig: Component config → Bluetooth → Bluetooth controller → Bluetooth controller mode (BR/EDR/BLE/DUALMODE) but now this implementation cannot be compiled due missing reference to this function: btsnd_hcic_ble_update_adv_report_flow_control

The application that throws these errors is here: https://github.com/taherrera/AFR-Bluedroid)

n9wxu commented 1 year ago

In the AFR demos, there are a number of conflicts with a bluedroid SPP configuration. These conflicts are in iot_ble_hal_common_gap.c. This file configures the bluetooth for BLE GAP and only does incomplete for bluedroid intialization if the bluedroid menu option is selected. Compiling with the IDF 4.2 SPP demo incorporated is possible but a lot of work is required to get SPP functioning.

n9wxu commented 1 year ago

The Amazon FreeRTOS product does not support bluetooth classic. It does support bluedroid in BLE mode.