nkolban / esp32-snippets

Sample ESP32 snippets and code fragments
https://leanpub.com/kolban-ESP32
Apache License 2.0
2.35k stars 710 forks source link

Cant connect more than 3 BLE Servers to a BLE Client #775

Open victorChB opened 5 years ago

victorChB commented 5 years ago

Im using the latest esp-idf release (v3.1.2) and have a setup with 7 Servers flashed with the example from https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLETests/SampleNotify.cpp

The client code starts by creating a multi_server::scanTask() where a BLEScan object is created. This task checks wether the maximum number of servers defined are connected, if they aren´t it continues scanning by intervals. This task is suspended if all the servers are connected.

When the scan completes I call multi_server::scanCompleteCB() which starts connecting each server that has the same name as BLEServer_name.

The problem is that when I connect the 4th server it detects it and tries to connect to it but from what I have debugged it stays in BLEClient::connect() waiting for the gatt event ESP_GATTC_OPEN_EVT which never occurs.

I based my CLient example from https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLETests/SampleClient_Notify.cpp and modified it like this:

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <esp_log.h>
#include <string>
#include "Task.h"
#include "BLEDevice.h"
#include "BLEAdvertisedDevice.h"
#include "BLEClient.h"
#include "BLEScan.h"

#define MAX_SERVERS 4 //Number of max. BLE servers the Client will attempt to connect
std::string BLEServer_name = "MYDEVICE"; //Name of Server we are looking for
/*------------------------
Scanning Task for servers
-------------------------
*/
#define SCANNING_TIME_MS 10//Time to scan for servers
#define SCANNING_DELAY_MS 10000 //Delay before scanning again
TaskHandle_t scanningTaskHandle;

/*------------------------
UUIDs of server
-------------------------
*/
static BLEUUID serviceUUID("4fafc201-1fb5-459e-8fcc-c5c9c331914b");
// The characteristic of the remote service we are interested in.
static BLEUUID    charUUID("beb5483e-36e1-4688-b7f5-ea07361b26a8");

uint8_t connectedServers=0; //Count how many servers are currently connected

SemaphoreHandle_t connectionSemaphore = NULL;//Used to connect only one client at a time

static const char* LOG_TAG = "Multi_server";

class MyClientCB: public BLEClientCallbacks {
  public:
    void onConnect(BLEClient *pClient) {
    }
    void onDisconnect(BLEClient *pClient) {
      connectedServers--;
      ESP_LOGI(LOG_TAG, "****** BLE Server Disconnected with Conn Id %d ******", pClient->getConnId());
      vTaskResume( scanningTaskHandle ); //Resume scanning task if a sensor is disconnected
    }
};
MyClientCB sensorServerCB;

void serverNotifyCB( BLERemoteCharacteristic* pBLERemoteCharacteristic,  uint8_t* pData, size_t length, bool isNotify) {

}

static const char* CONNECTION_TASK_TAG = "*ConnectionTask";

class connectionTask: public Task {
  public:
    void run(void* data) {
      xSemaphoreTake(connectionSemaphore, portMAX_DELAY); //Handle only one connectionTask at a time
      BLEAddress* pAddress = (BLEAddress*)data;
      BLEClient* pClient = BLEDevice::createClient();
      ESP_LOGI(CONNECTION_TASK_TAG, "BLE Client Assigned [%s]", pAddress->toString().c_str());
      pClient->setClientCallbacks(&sensorServerCB);
      ESP_LOGI(CONNECTION_TASK_TAG, "Client callbacks set [%s]", pAddress->toString().c_str());
      // Connect to the remove BLE Server.
      pClient->connect(*pAddress);
      ESP_LOGI(CONNECTION_TASK_TAG, "Client finished connecting [%s]", pAddress->toString().c_str());
      BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
      ESP_LOGI(CONNECTION_TASK_TAG, "Client got services [%s]", pAddress->toString().c_str());
      if (pRemoteService == nullptr) {
        ESP_LOGE(CONNECTION_TASK_TAG, "Failed to find our service UUID: %s", serviceUUID.toString().c_str());
        return;
      }
      BLERemoteCharacteristic* pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
      if (pRemoteCharacteristic == nullptr) {
        ESP_LOGE(CONNECTION_TASK_TAG, "Failed to find our characteristic UUID: %s", charUUID.toString().c_str());
        return;
      }
      ESP_LOGI(CONNECTION_TASK_TAG, "Client got characteristic [%s]", pAddress->toString().c_str());
      pRemoteCharacteristic->registerForNotify(serverNotifyCB);
      ESP_LOGI(CONNECTION_TASK_TAG, "Client registered for notify [%s]", pAddress->toString().c_str());
      ESP_LOGI(CONNECTION_TASK_TAG, "----------BLE Server %s connected ----------", pAddress->toString().c_str());
      connectedServers++;
      xSemaphoreGive( connectionSemaphore );
    } // run
}; // connectionTask

class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
    void onResult(BLEAdvertisedDevice advertisedDevice) {
      ESP_LOGI(LOG_TAG, "Advertised Device: %s", advertisedDevice.toString().c_str());
    } 
};

class multi_server {
  public:
    static void start(void);
  private:
    static void scanTask(void *parameter);
    static void scanCompleteCB(BLEScanResults scanResults);
};

void multi_server::start(void) {
  connectionSemaphore = xSemaphoreCreateMutex(); //Create semaphore for connectionTask
  xTaskCreate( scanTask, "Scanning Task", 20000, NULL, 1, &scanningTaskHandle );
}

void multi_server::scanCompleteCB(BLEScanResults scanResults) {
  ESP_LOGI(LOG_TAG, "Scan got %d Servers", scanResults.getCount());
  for (int i = 0; i < scanResults.getCount(); i++) {
    if (BLEServer_name==scanResults.getDevice(i).getName()) {
        ESP_LOGI(LOG_TAG, "Starting Connection..");
        connectionTask* pconnectionTask = new connectionTask();
        pconnectionTask->setStackSize(18000);
        pconnectionTask->start(new BLEAddress(*scanResults.getDevice(i).getAddress().getNative()));
    }
   }
 }

void multi_server::scanTask(void * parameter) {
  ESP_LOGI(LOG_TAG, "Scanning Task Started");
  BLEDevice::init("");
  BLEScan *pBLEScan = BLEDevice::getScan();
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setActiveScan(true);
  bool scanStarted = false;
  while (1) {
    if (!scanStarted && connectedServers < MAX_SERVERS) {
      ESP_LOGI("Scanning Task", "will scan for %.2f seconds.", SCANNING_TIME_MS / 1000.0);
      pBLEScan->start(SCANNING_TIME_MS / portTICK_RATE_MS, multi_server::scanCompleteCB);
      scanStarted = true;
      vTaskDelay(SCANNING_TIME_MS / portTICK_RATE_MS);
    }
    else if (scanStarted) {
      ESP_LOGI("Scanning Task", "will scan again in %.2f seconds.", SCANNING_DELAY_MS / 1000.0);
      scanStarted = false;
      vTaskDelay(SCANNING_DELAY_MS / portTICK_RATE_MS);
    }
    else if (connectedServers== MAX_SERVERS) {
      ESP_LOGI("Scanning Task", "All Servers are connected...Going to sleep");
      vTaskSuspend(NULL);
    }
  }
}

extern "C" {
  void app_main(void);
}

void app_main(void)
{
  multi_server::start();
}

My sdkconfig file for bluetooth is as follows

#
# Bluetooth
#
CONFIG_BT_ENABLED=y

#
# Bluetooth controller
#
CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y
CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=
CONFIG_BTDM_CONTROLLER_MODE_BTDM=
CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN=5
CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=5
CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=0
CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=0
CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE_0=y
CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE_1=
CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0
CONFIG_BTDM_CONTROLLER_HCI_MODE_VHCI=y
CONFIG_BTDM_CONTROLLER_HCI_MODE_UART_H4=
#
# MODEM SLEEP Options
#
CONFIG_BTDM_CONTROLLER_MODEM_SLEEP=y
CONFIG_BTDM_MODEM_SLEEP_MODE_ORIG=y
CONFIG_BTDM_MODEM_SLEEP_MODE_EVED=
CONFIG_BTDM_LPCLK_SEL_MAIN_XTAL=y
CONFIG_BLE_SCAN_DUPLICATE=y
CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR=y
CONFIG_SCAN_DUPLICATE_BY_ADV_DATA=
CONFIG_SCAN_DUPLICATE_BY_ADV_DATA_AND_DEVICE_ADDR=
CONFIG_SCAN_DUPLICATE_TYPE=0
CONFIG_DUPLICATE_SCAN_CACHE_SIZE=50
CONFIG_BLE_MESH_SCAN_DUPLICATE_EN=y
CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE=200
CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y
CONFIG_BLUEDROID_ENABLED=y
CONFIG_BLUEDROID_PINNED_TO_CORE_0=y
CONFIG_BLUEDROID_PINNED_TO_CORE_1=
CONFIG_BLUEDROID_PINNED_TO_CORE=0
CONFIG_BTC_TASK_STACK_SIZE=10000
CONFIG_BTU_TASK_STACK_SIZE=8000
CONFIG_BLUEDROID_MEM_DEBUG=
CONFIG_CLASSIC_BT_ENABLED=
CONFIG_GATTS_ENABLE=y
CONFIG_GATTS_SEND_SERVICE_CHANGE_MANUAL=
CONFIG_GATTS_SEND_SERVICE_CHANGE_AUTO=y
CONFIG_GATTS_SEND_SERVICE_CHANGE_MODE=0
CONFIG_GATTC_ENABLE=y
CONFIG_GATTC_CACHE_NVS_FLASH=
CONFIG_BLE_SMP_ENABLE=y
CONFIG_BT_STACK_NO_LOG=

The log from my application

I (488) esp_image: segment 9: paddr=0x00105e8c vaddr=0x400c0000 size=0x00000 (     0) load
I (488) esp_image: segment 10: paddr=0x00105e94 vaddr=0x50000000 size=0x00000 (     0) load
I (495) esp_image: segment 11: paddr=0x00105e9c vaddr=0x50000000 size=0x00000 (     0) load
I (514) boot: Loaded app from partition at offset 0x10000
I (514) boot: Disabling RNG early entropy source...
I (516) cpu_start: Pro cpu up.
I (519) cpu_start: Application information:
I (524) cpu_start: Compile time:     16:04:37
I (529) cpu_start: Compile date:     Jan  8 2019
I (534) cpu_start: ESP-IDF:          v3.3-beta1-177-g456efd3d5
I (541) cpu_start: Starting app cpu, entry point is 0x40081044
0x40081044: call_start_cpu1 at E:/Documents/ESP32/toolchain-20181001/msys32/home/Victor/esp/esp-idf/components/esp32/cpu_start.c:265

I (0) cpu_start: App cpu up.
I (552) heap_init: Initializing. RAM available for dynamic allocation:
I (558) heap_init: At 3FFAFF10 len 000000F0 (0 KiB): DRAM
I (564) heap_init: At 3FFB6388 len 00001C78 (7 KiB): DRAM
I (570) heap_init: At 3FFB9A20 len 00004108 (16 KiB): DRAM
I (577) heap_init: At 3FFBDB5C len 00000004 (0 KiB): DRAM
I (583) heap_init: At 3FFC5290 len 0001AD70 (107 KiB): DRAM
I (589) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (595) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (602) heap_init: At 40091850 len 0000E7B0 (57 KiB): IRAM
I (608) cpu_start: Pro cpu start user code
I (291) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (0) Multi_server: Scanning Task Started
I (30) BTDM_INIT: BT controller compile version [0b60040]
I (370) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (440) phy: phy_version: 4006, e540b8e, Dec 17 2018, 11:53:06, 0, 0
I (990) Scanning Task: will scan for 0.01 seconds.
I (1000) Scanning Task: will scan again in 10.00 seconds.
I (1020) Multi_server: Advertised Device: Name: MYDEVICE, Address: 3c:71:bf:45:ab:96, txPower: 3
I (1020) Multi_server: Advertised Device: Name: MYDEVICE, Address: 3c:71:bf:42:15:0e, txPower: 3
I (1030) Multi_server: Advertised Device: Name: , Address: 76:68:5c:93:31:30, manufacturer data: 4c0010050a186f0565
I (1040) Multi_server: Advertised Device: Name: MYDEVICE, Address: 3c:71:bf:42:12:6a, txPower: 3
I (1050) Multi_server: Advertised Device: Name: MYDEVICE, Address: 80:7d:3a:f3:9f:b2, txPower: 3
I (1060) Multi_server: Advertised Device: Name: , Address: 13:63:81:fd:23:fa, manufacturer data: 0600010f20021c141fd6c512099a543b9f0bd7965da4b6a3aafd7a3ef0
I (1070) Multi_server: Advertised Device: Name: , Address: 5d:9a:4c:51:5a:57, manufacturer data: 4c0010050b1cafd11f
I (1100) Multi_server: Advertised Device: Name: , Address: 05:0d:4d:ef:1a:23, manufacturer data: 060001092002fc7348ec9f81fee57e5b0c8fb1031574dfc90ef970e892
I (1130) Multi_server: Advertised Device: Name: , Address: 28:24:27:03:70:59, manufacturer data: 060001092002f8542c02a733aaaa9b0def63a6cfad1b87539061db7881
I (1220) Multi_server: Advertised Device: Name: , Address: 71:67:ff:9d:0d:8b, manufacturer data: 4c001005031ce9e446
I (1350) Multi_server: Advertised Device: Name: , Address: 73:83:1d:40:25:e6, manufacturer data: 060001092002e6842ed87d756e9c0f12ca3b8540d4b210177916c19081
I (2020) Multi_server: Advertised Device: Name: , Address: 44:f2:e6:42:3d:c0, manufacturer data: 4c001005031cc92eaf
W (2550) BLEScan: ESP_GAP_SEARCH_INQ_CMPL_EVT
I (2550) Multi_server: Scan got 12 Servers
I (2550) Multi_server: Starting Connection..
I (2550) Multi_server: Starting Connection..
I (2550) *ConnectionTask: BLE Client Assigned [3c:71:bf:42:12:6a]
I (2550) Multi_server: Starting Connection..
I (2560) *ConnectionTask: Client callbacks set [3c:71:bf:42:12:6a]
I (2570) BLEDevice: add conn_id: 0, GATT role: client
I (2580) Multi_server: Starting Connection..
I (2670) *ConnectionTask: Client finished connecting [3c:71:bf:42:12:6a]
I (3170) *ConnectionTask: Client got services [3c:71:bf:42:12:6a]
I (3170) *ConnectionTask: Client got characteristic [3c:71:bf:42:12:6a]
I (3180) *ConnectionTask: Client registered for notify [3c:71:bf:42:12:6a]
I (3190) *ConnectionTask: ----------BLE Server 3c:71:bf:42:12:6a connected ----------
I (3190) *ConnectionTask: BLE Client Assigned [3c:71:bf:42:15:0e]
I (3200) *ConnectionTask: Client callbacks set [3c:71:bf:42:15:0e]
I (3200) BLEDevice: add conn_id: 1, GATT role: client
I (3300) *ConnectionTask: Client finished connecting [3c:71:bf:42:15:0e]
I (3800) *ConnectionTask: Client got services [3c:71:bf:42:15:0e]
I (3810) *ConnectionTask: Client got characteristic [3c:71:bf:42:15:0e]
I (3810) *ConnectionTask: Client registered for notify [3c:71:bf:42:15:0e]
I (3810) *ConnectionTask: ----------BLE Server 3c:71:bf:42:15:0e connected ----------
I (3820) *ConnectionTask: BLE Client Assigned [3c:71:bf:45:ab:96]
I (3830) *ConnectionTask: Client callbacks set [3c:71:bf:45:ab:96]
I (3840) BLEDevice: add conn_id: 2, GATT role: client
I (3910) *ConnectionTask: Client finished connecting [3c:71:bf:45:ab:96]
I (4420) *ConnectionTask: Client got services [3c:71:bf:45:ab:96]
I (4420) *ConnectionTask: Client got characteristic [3c:71:bf:45:ab:96]
I (4430) *ConnectionTask: Client registered for notify [3c:71:bf:45:ab:96]
I (4430) *ConnectionTask: ----------BLE Server 3c:71:bf:45:ab:96 connected ----------
I (4440) *ConnectionTask: BLE Client Assigned [80:7d:3a:f3:9f:b2]
I (4450) *ConnectionTask: Client callbacks set [80:7d:3a:f3:9f:b2]
I (4450) BLEDevice: add conn_id: 3, GATT role: client
I (11000) Scanning Task: will scan for 0.01 seconds.
I (11010) Scanning Task: will scan again in 10.00 seconds.
chegewara commented 5 years ago

https://gist.github.com/chegewara/9fed4a6fdc2678c4cd3f6a0bfba10093#file-sdkconfig-main-app-L338