I have a XIAO ESP32C3 board,
I’m using Nimble-Arduino and I’m trying to disconnect all the connected peers but I get flaky results: My disconnect routine doesn’t work most of the time but sometimes the connection drops.
My results:
23:54:47.695 -> Connected
23:54:49.686 -> Disconnected
23:54:51.677 -> Connected
23:54:53.703 -> Connected
23:54:55.695 -> Connected
23:54:57.718 -> Connected
23:54:59.707 -> Connected
23:55:01.730 -> Connected
23:55:03.719 -> Connected
23:55:05.739 -> Connected
23:55:07.729 -> Connected
23:55:09.750 -> Connected
23:55:11.742 -> Connected
23:55:13.734 -> Disconnected
23:55:15.756 -> Connected
23:55:17.743 -> Connected
23:55:19.763 -> Connected
23:55:21.784 -> Connected
23:55:23.772 -> Connected
Any help would be appreciated.
The sketch
#include "HIDKeyboardTypes.h"
#include "HIDTypes.h"
#include "sdkconfig.h"
#include "nimconfig.h"
#include "NimBLECharacteristic.h"
#include "NimBLEHIDDevice.h"
#include <NimBLEDevice.h>
#include <NimBLEServer.h>
#include <NimBLEUtils.h>
#include <driver/adc.h>
static const uint8_t BLE_CONSUMER_REPORT_ID = 0x01;
static const uint16_t BLE_HID_REMOTE_APPEARANCE = 0x0180;
static const uint16_t BLE_VEND_ID = 0x0000;
static const uint8_t BLE_VEND_SRC = 0x02;
static const uint16_t BLE_PROD_ID = 0x0000;
static const uint16_t BLE_PROD_VER = 0x0001;
static const uint8_t _hidReportDescriptor[] = {
USAGE_PAGE(1), 0x0C, // USAGE_PAGE (Consumer)
USAGE(1), 0x01, // USAGE (Consumer Control)
COLLECTION(1), 0x01, // COLLECTION (Application)
REPORT_ID(1), BLE_CONSUMER_REPORT_ID, // REPORT_ID (1)
LOGICAL_MINIMUM(1), 0x00, // LOGICAL_MINIMUM (0)
LOGICAL_MAXIMUM(1), 0x01, // LOGICAL_MAXIMUM (1)
REPORT_SIZE(1), 0x01, // REPORT_SIZE (1)
REPORT_COUNT(1), 0x0B, // REPORT_COUNT (11)
USAGE(1), 0x30, // Power
USAGE(1), 0x41, // Menu Pick (Select)
USAGE(1), 0x46, // Menu Escape (Back)
USAGE(2), 0x23, 0x02, // Home
USAGE(1), 0xE9, // Volume Increase
USAGE(1), 0xEA, // Volume Decrease
USAGE(1), 0xE2, // Volume Mute
USAGE(1), 0x42, // Menu Up
USAGE(1), 0x43, // Menu Down
USAGE(1), 0x44, // Menu Left
USAGE(1), 0x45, // Menu Right
HIDINPUT(1), 0x02, // INPUT (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
REPORT_SIZE(1), 0x05, // REPORT_SIZE (5) - Padding 5 bit
REPORT_COUNT(1), 0x01, // REPORT_COUNT (1)
HIDINPUT(1), 0x03, // INPUT
END_COLLECTION(0) // END COLLECTION
};
// ************ STATUS
class BLEStatus : public NimBLEServerCallbacks {
public:
bool connected = false;
BLEStatus(void) {};
void onConnect(NimBLEServer* pServer, ble_gap_conn_desc* desc) {
this->connected = true;
};
void onDisconnect(NimBLEServer* pServer) {
this->connected = false;
};
NimBLECharacteristic* inputConsumer;
};
// *********** BLE
class BLERemote {
private:
NimBLEServer* bleServer;
BLEStatus* connectionStatus;
NimBLEHIDDevice* hid;
NimBLECharacteristic* inputConsumer;
std::string deviceManufacturer;
std::string deviceName;
static void taskServer(void* pvParameter) {
BLERemote* BLERemoteInstance = (BLERemote*)pvParameter;
NimBLEDevice::init(BLERemoteInstance->deviceName);
NimBLEServer* pServer = NimBLEDevice::createServer();
pServer->setCallbacks(BLERemoteInstance->connectionStatus);
pServer->advertiseOnDisconnect(true);
BLERemoteInstance->bleServer = pServer;
BLERemoteInstance->hid = new NimBLEHIDDevice(pServer);
BLERemoteInstance->inputConsumer = BLERemoteInstance->hid->inputReport(BLE_CONSUMER_REPORT_ID);
BLERemoteInstance->connectionStatus->inputConsumer = BLERemoteInstance->inputConsumer;
BLERemoteInstance->hid->manufacturer()->setValue(BLERemoteInstance->deviceManufacturer);
BLERemoteInstance->hid->pnp(BLE_VEND_SRC, BLE_VEND_ID, BLE_PROD_ID, BLE_PROD_VER);
BLERemoteInstance->hid->hidInfo(0x00, 0x01);
NimBLEDevice::setSecurityAuth(true, false, false);
BLERemoteInstance->hid->reportMap((uint8_t*)_hidReportDescriptor, sizeof(_hidReportDescriptor));
BLERemoteInstance->hid->startServices();
BLERemoteInstance->onStarted(pServer);
NimBLEAdvertising* pAdvertising = pServer->getAdvertising();
pAdvertising->setAppearance(BLE_HID_REMOTE_APPEARANCE);
pAdvertising->addServiceUUID(BLERemoteInstance->hid->hidService()->getUUID());
pAdvertising->start();
BLERemoteInstance->hid->setBatteryLevel(100);
vTaskDelay(portMAX_DELAY);
};
public:
BLERemote(void) {};
void setup(std::string deviceName, std::string deviceManufacturer) {
this->hid = 0;
this->deviceName = deviceName;
this->deviceManufacturer = deviceManufacturer;
this->connectionStatus = new BLEStatus();
xTaskCreate(this->taskServer, "server", 20000, (void*)this, 1, NULL);
};
bool isConnected(void) {
return this->connectionStatus->connected;
};
void disconnect(void) {
size_t peersNum = this->bleServer->getConnectedCount();
for (int i = 0; i < peersNum; i++) {
uint16_t connID = this->bleServer->getPeerInfo(i).getConnHandle();
this->bleServer->disconnect(connID);
}
};
protected:
virtual void onStarted(NimBLEServer* pServer) {};
};
// ********* SKETCH
BLERemote blRemote;
void setup() {
Serial.begin(115200);
delay(1000);
blRemote.setup("Test", "Test");
}
void loop() {
if (!blRemote.isConnected()) {
Serial.println("Disconnected");
delay(2000);
return;
}
Serial.println("Connected");
delay(2000);
blRemote.disconnect();
}