Add opt-in NimBLE Full Companion trials for V4 and XIAO S3
This commit is contained in:
1 parent
7ff11a2d64
commit
7f1bd8b1d2
11 files changed
+789
-27
No files matched your search
@@ -3,10 +3,10 @@
|
||||
#include "../CompanionFrameQueue.h"
|
||||
#include "esp_mac.h"
|
||||
#include <stdlib.h>
|
||||
#if defined(CONFIG_BLUEDROID_ENABLED)
|
||||
#if defined(CONFIG_BLUEDROID_ENABLED) && !defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
#include "esp_gap_ble_api.h"
|
||||
#endif
|
||||
#if defined(CONFIG_NIMBLE_ENABLED)
|
||||
#if MESH_BLE_USES_NIMBLE && !defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
#include <host/ble_store.h>
|
||||
#endif
|
||||
|
||||
@@ -29,8 +29,17 @@ extern "C" bool bleInUse(void) {
|
||||
#define ADVERT_RESTART_DELAY 1000 // millis
|
||||
#define BLE_BOND_PERSIST_TIMEOUT_MS 15000
|
||||
|
||||
static void cleanupFailedBluetoothStart() {
|
||||
#if defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
BLEDevice::deinit(true);
|
||||
#else
|
||||
BLEDevice::deinit(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
static void clearStoredBluetoothBonds() {
|
||||
#if defined(CONFIG_NIMBLE_ENABLED)
|
||||
#if MESH_BLE_USES_NIMBLE
|
||||
const int result = ble_store_clear();
|
||||
if (result != 0) {
|
||||
BLE_DEBUG_PRINTLN("Could not clear NimBLE bonds: %d", result);
|
||||
@@ -59,6 +68,8 @@ static void clearStoredBluetoothBonds() {
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static bool bluetoothPeersEqual(
|
||||
const mesh::companion::BluetoothPeerIdentity& lhs,
|
||||
const mesh::companion::BluetoothPeerIdentity& rhs) {
|
||||
@@ -81,7 +92,7 @@ void SerialBLEInterface::noteSuccessfulConnection(
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NIMBLE_ENABLED)
|
||||
#if MESH_BLE_USES_NIMBLE
|
||||
static void bluetoothPeerFromNimbleAddress(
|
||||
const ble_addr_t& address,
|
||||
mesh::companion::BluetoothPeerIdentity& peer) {
|
||||
@@ -110,6 +121,9 @@ static ble_addr_t nimbleAddressFromBluetoothPeer(
|
||||
|
||||
static bool nimbleBondExistsForPeer(
|
||||
const mesh::companion::BluetoothPeerIdentity& peer) {
|
||||
#if defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
return BLEDevice::isBonded(BLEAddress(nimbleAddressFromBluetoothPeer(peer)));
|
||||
#else
|
||||
ble_addr_t bonded_peers[8];
|
||||
int count = 0;
|
||||
if (ble_store_util_bonded_peers(
|
||||
@@ -123,6 +137,7 @@ static bool nimbleBondExistsForPeer(
|
||||
if (bluetoothPeersEqual(candidate, peer)) return true;
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
static void bluetoothPeerFromBluedroidBond(
|
||||
@@ -181,7 +196,7 @@ static bool findBluedroidBondedPeer(
|
||||
|
||||
bool SerialBLEInterface::resolveSuccessfulPeer(
|
||||
mesh::companion::BluetoothPeerIdentity& peer) const {
|
||||
#if defined(CONFIG_NIMBLE_ENABLED)
|
||||
#if MESH_BLE_USES_NIMBLE
|
||||
if (!mesh::companion::isValidBluetoothPeerIdentity(_successfulPeer)
|
||||
|| !nimbleBondExistsForPeer(_successfulPeer)) {
|
||||
return false;
|
||||
@@ -204,7 +219,7 @@ bool SerialBLEInterface::configureBondedOnlyAdvertising(
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NIMBLE_ENABLED)
|
||||
#if MESH_BLE_USES_NIMBLE
|
||||
if (require_stored_bond && !nimbleBondExistsForPeer(peer)) {
|
||||
requestBondedOnlyRecovery("saved peer bond is unavailable");
|
||||
return false;
|
||||
@@ -250,8 +265,13 @@ bool SerialBLEInterface::configureBondedOnlyAdvertising(
|
||||
}
|
||||
advertising->stop();
|
||||
BLEAdvertisementData minimal_advertisement;
|
||||
#if defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
minimal_advertisement.setFlags(BLE_HS_ADV_F_BREDR_UNSUP);
|
||||
advertising->enableScanResponse(false);
|
||||
#else
|
||||
minimal_advertisement.setFlags(ESP_BLE_ADV_FLAG_BREDR_NOT_SPT);
|
||||
advertising->setScanResponse(false);
|
||||
#endif
|
||||
advertising->setScanFilter(true, true);
|
||||
advertising->setAdvertisementData(minimal_advertisement);
|
||||
|
||||
@@ -325,7 +345,7 @@ bool SerialBLEInterface::begin(const char* prefix, const char* name,
|
||||
}
|
||||
|
||||
// Create the BLE Device
|
||||
#if defined(CONFIG_NIMBLE_ENABLED)
|
||||
#if MESH_BLE_USES_NIMBLE
|
||||
if (!BLEDevice::init(dev_name)) {
|
||||
BLE_DEBUG_PRINTLN("BLEDevice::init failed");
|
||||
return false;
|
||||
@@ -336,9 +356,17 @@ bool SerialBLEInterface::begin(const char* prefix, const char* name,
|
||||
BLEDevice::init(dev_name);
|
||||
#endif
|
||||
|
||||
#if defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
if (clear_bonds && !BLEDevice::deleteAllBonds()) {
|
||||
BLE_DEBUG_PRINTLN("Could not clear NimBLE bonds for the new identity");
|
||||
cleanupFailedBluetoothStart();
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
if (clear_bonds) clearStoredBluetoothBonds();
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NIMBLE_ENABLED)
|
||||
#if MESH_BLE_USES_NIMBLE
|
||||
if (custom_address != nullptr) {
|
||||
uint8_t native_address[mesh::companion::BLUETOOTH_MAC_BYTES];
|
||||
for (size_t i = 0; i < mesh::companion::BLUETOOTH_MAC_BYTES; i++) {
|
||||
@@ -348,19 +376,32 @@ bool SerialBLEInterface::begin(const char* prefix, const char* name,
|
||||
if (!BLEDevice::setOwnAddr(native_address)
|
||||
|| !BLEDevice::setOwnAddrType(BLE_OWN_ADDR_RANDOM)) {
|
||||
BLE_DEBUG_PRINTLN("Custom Bluetooth MAC setup failed");
|
||||
BLEDevice::deinit(false);
|
||||
cleanupFailedBluetoothStart();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#if defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
else if (!BLEDevice::setOwnAddrType(BLE_OWN_ADDR_PUBLIC)) {
|
||||
cleanupFailedBluetoothStart();
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
BLEDevice::setSecurityCallbacks(this);
|
||||
#endif
|
||||
// ATT notifications consume three bytes of the negotiated MTU. Reserve
|
||||
// that overhead so a MAX_FRAME_SIZE protocol frame fits without truncation.
|
||||
BLEDevice::setMTU(MAX_FRAME_SIZE + 3);
|
||||
|
||||
#if defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
BLEDevice::setSecurityPasskey(pin_code);
|
||||
BLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY);
|
||||
BLEDevice::setSecurityAuth(true, true, true);
|
||||
#else
|
||||
BLESecurity sec;
|
||||
#if defined(CONFIG_NIMBLE_ENABLED)
|
||||
#if MESH_BLE_USES_NIMBLE
|
||||
sec.setPassKey(true, pin_code);
|
||||
// A passkey alone does not provide MITM protection when the controller's
|
||||
// default capability is NoInputNoOutput: the peers can silently fall back
|
||||
@@ -373,6 +414,7 @@ bool SerialBLEInterface::begin(const char* prefix, const char* name,
|
||||
sec.setStaticPIN(pin_code);
|
||||
sec.setCapability(ESP_IO_CAP_OUT);
|
||||
sec.setAuthenticationMode(ESP_LE_AUTH_REQ_SC_MITM_BOND);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//BLEDevice::setPower(ESP_PWR_LVL_N8);
|
||||
@@ -381,12 +423,18 @@ bool SerialBLEInterface::begin(const char* prefix, const char* name,
|
||||
pServer = BLEDevice::createServer();
|
||||
if (pServer == NULL) {
|
||||
BLE_DEBUG_PRINTLN("BLEDevice::createServer failed");
|
||||
BLEDevice::deinit(false);
|
||||
cleanupFailedBluetoothStart();
|
||||
return false;
|
||||
}
|
||||
#if defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
// The interface is owned by the application, not by the NimBLE server.
|
||||
pServer->setCallbacks(this, false);
|
||||
pServer->advertiseOnDisconnect(false);
|
||||
#else
|
||||
pServer->setCallbacks(this);
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_NIMBLE_ENABLED)
|
||||
#if !MESH_BLE_USES_NIMBLE
|
||||
if (custom_address != nullptr) {
|
||||
esp_bd_addr_t native_address;
|
||||
memcpy(native_address, custom_address, sizeof(native_address));
|
||||
@@ -402,33 +450,41 @@ bool SerialBLEInterface::begin(const char* prefix, const char* name,
|
||||
pService = pServer->createService(SERVICE_UUID);
|
||||
if (pService == NULL) {
|
||||
BLE_DEBUG_PRINTLN("BLEServer::createService failed");
|
||||
BLEDevice::deinit(false);
|
||||
cleanupFailedBluetoothStart();
|
||||
pServer = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create a BLE Characteristic
|
||||
#if defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
uint32_t tx_properties = NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY |
|
||||
NIMBLE_PROPERTY::READ_AUTHEN;
|
||||
uint32_t rx_properties = NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_AUTHEN;
|
||||
#else
|
||||
uint32_t tx_properties = BLECharacteristic::PROPERTY_READ |
|
||||
BLECharacteristic::PROPERTY_NOTIFY;
|
||||
uint32_t rx_properties = BLECharacteristic::PROPERTY_WRITE;
|
||||
#if defined(CONFIG_NIMBLE_ENABLED)
|
||||
#if MESH_BLE_USES_NIMBLE
|
||||
// NimBLE ignores setAccessPermissions(). Authentication requirements must
|
||||
// be part of the characteristic properties instead.
|
||||
tx_properties |= BLECharacteristic::PROPERTY_READ_AUTHEN;
|
||||
rx_properties |= BLECharacteristic::PROPERTY_WRITE_AUTHEN;
|
||||
#endif
|
||||
#endif
|
||||
pTxCharacteristic = pService->createCharacteristic(
|
||||
CHARACTERISTIC_UUID_TX, tx_properties);
|
||||
if (pTxCharacteristic == NULL) {
|
||||
BLE_DEBUG_PRINTLN("BLEService::createCharacteristic(TX) failed");
|
||||
BLEDevice::deinit(false);
|
||||
cleanupFailedBluetoothStart();
|
||||
pServer = NULL;
|
||||
pService = NULL;
|
||||
return false;
|
||||
}
|
||||
#if !defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
pTxCharacteristic->setAccessPermissions(ESP_GATT_PERM_READ_ENC_MITM);
|
||||
#endif
|
||||
pTxCharacteristic->setCallbacks(this);
|
||||
#if !defined(CONFIG_NIMBLE_ENABLED)
|
||||
#if !MESH_BLE_USES_NIMBLE
|
||||
// NimBLE creates and owns the 0x2902 descriptor automatically.
|
||||
pTxDescriptor = new BLE2902();
|
||||
// Make notification setup start/finish pairing before the client begins its
|
||||
@@ -444,16 +500,24 @@ bool SerialBLEInterface::begin(const char* prefix, const char* name,
|
||||
CHARACTERISTIC_UUID_RX, rx_properties);
|
||||
if (pRxCharacteristic == NULL) {
|
||||
BLE_DEBUG_PRINTLN("BLEService::createCharacteristic(RX) failed");
|
||||
BLEDevice::deinit(false);
|
||||
cleanupFailedBluetoothStart();
|
||||
pServer = NULL;
|
||||
pService = NULL;
|
||||
pTxCharacteristic = NULL;
|
||||
#if !defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
pTxDescriptor = NULL;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
#if !defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
pRxCharacteristic->setAccessPermissions(ESP_GATT_PERM_WRITE_ENC_MITM);
|
||||
#endif
|
||||
pRxCharacteristic->setCallbacks(this);
|
||||
|
||||
#if defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
pServer->getAdvertising()->setName(dev_name);
|
||||
pServer->getAdvertising()->enableScanResponse(true);
|
||||
#endif
|
||||
pServer->getAdvertising()->addServiceUUID(SERVICE_UUID);
|
||||
if (bonded_only_peer != nullptr) {
|
||||
configureBondedOnlyAdvertising(*bonded_only_peer, true);
|
||||
@@ -463,6 +527,27 @@ bool SerialBLEInterface::begin(const char* prefix, const char* name,
|
||||
|
||||
// -------- BLESecurityCallbacks methods
|
||||
|
||||
#if defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
uint32_t SerialBLEInterface::onPassKeyDisplay() {
|
||||
_pairingRequestPending.store(true, std::memory_order_release);
|
||||
return _pin_code;
|
||||
}
|
||||
|
||||
void SerialBLEInterface::onAuthenticationComplete(NimBLEConnInfo& info) {
|
||||
if (info.isEncrypted() && info.isAuthenticated() && info.isBonded()) {
|
||||
deviceConnected = true;
|
||||
mesh::companion::BluetoothPeerIdentity peer;
|
||||
bluetoothPeerFromNimbleAddress(*info.getIdAddress().getBase(), peer);
|
||||
noteSuccessfulConnection(peer);
|
||||
} else {
|
||||
BLEDevice::deleteBond(info.getIdAddress());
|
||||
deviceConnected = false;
|
||||
if (_bonded_only) requestBondedOnlyRecovery("bond authentication failed");
|
||||
pServer->disconnect(info.getConnHandle());
|
||||
if (advertisingAllowed()) scheduleAdvertisingRestart((uint32_t)millis());
|
||||
}
|
||||
}
|
||||
#else
|
||||
uint32_t SerialBLEInterface::onPassKeyRequest() {
|
||||
BLE_DEBUG_PRINTLN("onPassKeyRequest()");
|
||||
_pairingRequestPending.store(true, std::memory_order_release);
|
||||
@@ -485,7 +570,7 @@ bool SerialBLEInterface::onSecurityRequest() {
|
||||
return true; // allow
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NIMBLE_ENABLED)
|
||||
#if MESH_BLE_USES_NIMBLE
|
||||
void SerialBLEInterface::onAuthenticationComplete(ble_gap_conn_desc* desc) {
|
||||
const bool success = desc != NULL && desc->sec_state.encrypted &&
|
||||
desc->sec_state.authenticated
|
||||
@@ -558,12 +643,31 @@ void SerialBLEInterface::onAuthenticationComplete(esp_ble_auth_cmpl_t cmpl) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// -------- BLEServerCallbacks methods
|
||||
|
||||
#if defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
void SerialBLEInterface::onConnect(BLEServer* pServer, NimBLEConnInfo& info) {
|
||||
last_conn_id = info.getConnHandle();
|
||||
deviceConnected = false;
|
||||
oldDeviceConnected = false;
|
||||
notifySucceeded = false;
|
||||
notificationsEnabled.store(false, std::memory_order_release);
|
||||
xQueueReset(recv_queue);
|
||||
_tx_reset_pending.store(true, std::memory_order_release);
|
||||
_adv_restart_pending = false;
|
||||
}
|
||||
|
||||
void SerialBLEInterface::onMTUChange(uint16_t mtu, NimBLEConnInfo& info) {
|
||||
(void)info;
|
||||
BLE_DEBUG_PRINTLN("onMtuChanged(), mtu=%d", mtu);
|
||||
}
|
||||
#else
|
||||
void SerialBLEInterface::onConnect(BLEServer* pServer) {
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NIMBLE_ENABLED)
|
||||
#if MESH_BLE_USES_NIMBLE
|
||||
void SerialBLEInterface::onConnect(BLEServer* pServer, ble_gap_conn_desc* desc) {
|
||||
BLE_DEBUG_PRINTLN("onConnect(), conn_id=%d, mtu=%d", desc->conn_handle,
|
||||
pServer->getPeerMTU(desc->conn_handle));
|
||||
@@ -597,7 +701,9 @@ void SerialBLEInterface::onConnect(BLEServer* pServer, esp_ble_gatts_cb_param_t
|
||||
xQueueReset(recv_queue);
|
||||
_tx_reset_pending.store(true, std::memory_order_release);
|
||||
_adv_restart_pending = false;
|
||||
#if !defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
if (pTxDescriptor != NULL) pTxDescriptor->setNotifications(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SerialBLEInterface::onMtuChanged(BLEServer* pServer, esp_ble_gatts_cb_param_t* param) {
|
||||
@@ -605,14 +711,25 @@ void SerialBLEInterface::onMtuChanged(BLEServer* pServer, esp_ble_gatts_cb_param
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
void SerialBLEInterface::onDisconnect(BLEServer* pServer, NimBLEConnInfo& info,
|
||||
int reason) {
|
||||
(void)info;
|
||||
(void)reason;
|
||||
#else
|
||||
void SerialBLEInterface::onDisconnect(BLEServer* pServer) {
|
||||
#endif
|
||||
BLE_DEBUG_PRINTLN("onDisconnect()");
|
||||
deviceConnected = false;
|
||||
notifySucceeded = false;
|
||||
notificationsEnabled.store(false, std::memory_order_release);
|
||||
xQueueReset(recv_queue);
|
||||
_tx_reset_pending.store(true, std::memory_order_release);
|
||||
#if !defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
if (pTxDescriptor != NULL) pTxDescriptor->setNotifications(false);
|
||||
#endif
|
||||
if (advertisingAllowed()) {
|
||||
scheduleAdvertisingRestart((uint32_t)millis());
|
||||
}
|
||||
@@ -620,7 +737,11 @@ void SerialBLEInterface::onDisconnect(BLEServer* pServer) {
|
||||
|
||||
// -------- BLECharacteristicCallbacks methods
|
||||
|
||||
#if defined(CONFIG_NIMBLE_ENABLED)
|
||||
#if defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
void SerialBLEInterface::onWrite(BLECharacteristic* pCharacteristic,
|
||||
NimBLEConnInfo& info) {
|
||||
if (!info.isEncrypted() || !info.isAuthenticated() || !info.isBonded()) return;
|
||||
#elif MESH_BLE_USES_NIMBLE
|
||||
void SerialBLEInterface::onWrite(BLECharacteristic* pCharacteristic,
|
||||
ble_gap_conn_desc* desc) {
|
||||
(void)desc;
|
||||
@@ -634,8 +755,14 @@ void SerialBLEInterface::onWrite(BLECharacteristic* pCharacteristic,
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
const auto value = pCharacteristic->getValue();
|
||||
const uint8_t* rxValue = value.data();
|
||||
const int len = value.size();
|
||||
#else
|
||||
uint8_t* rxValue = pCharacteristic->getData();
|
||||
int len = pCharacteristic->getLength();
|
||||
#endif
|
||||
|
||||
if (len > MAX_FRAME_SIZE) {
|
||||
BLE_DEBUG_PRINTLN("ERROR: onWrite(), frame too big, len=%d", len);
|
||||
@@ -650,11 +777,17 @@ void SerialBLEInterface::onWrite(BLECharacteristic* pCharacteristic,
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NIMBLE_ENABLED)
|
||||
#if defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
void SerialBLEInterface::onSubscribe(BLECharacteristic* pCharacteristic,
|
||||
NimBLEConnInfo& info, uint16_t subValue) {
|
||||
(void)info;
|
||||
#elif MESH_BLE_USES_NIMBLE
|
||||
void SerialBLEInterface::onSubscribe(BLECharacteristic* pCharacteristic,
|
||||
ble_gap_conn_desc* desc,
|
||||
uint16_t subValue) {
|
||||
(void)desc;
|
||||
#endif
|
||||
#if MESH_BLE_USES_NIMBLE
|
||||
if (pCharacteristic == pTxCharacteristic) {
|
||||
// NimBLE uses bit 0 for notification subscriptions.
|
||||
notificationsEnabled.store((subValue & 0x0001u) != 0,
|
||||
@@ -663,6 +796,7 @@ void SerialBLEInterface::onSubscribe(BLECharacteristic* pCharacteristic,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
void SerialBLEInterface::onStatus(BLECharacteristic* pCharacteristic, Status status, uint32_t code) {
|
||||
(void)pCharacteristic;
|
||||
notifySucceeded = status == SUCCESS_NOTIFY;
|
||||
@@ -672,6 +806,8 @@ void SerialBLEInterface::onStatus(BLECharacteristic* pCharacteristic, Status sta
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ---------- public methods
|
||||
|
||||
bool SerialBLEInterface::takeSuccessfulConnection(
|
||||
@@ -784,7 +920,14 @@ void SerialBLEInterface::enable() {
|
||||
clearBuffers();
|
||||
|
||||
// Start the service
|
||||
#if defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
if (!pServer->start()) {
|
||||
_isEnabled = false;
|
||||
return;
|
||||
}
|
||||
#else
|
||||
pService->start();
|
||||
#endif
|
||||
|
||||
// Start advertising
|
||||
|
||||
@@ -804,7 +947,9 @@ void SerialBLEInterface::disable() {
|
||||
|
||||
pServer->getAdvertising()->stop();
|
||||
pServer->disconnect(last_conn_id);
|
||||
#if !defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
pService->stop();
|
||||
#endif
|
||||
oldDeviceConnected = deviceConnected = false;
|
||||
clearBuffers();
|
||||
_adv_restart_pending = false;
|
||||
@@ -852,7 +997,7 @@ size_t SerialBLEInterface::checkRecvFrame(uint8_t dest[]) {
|
||||
BLE_WRITE_MIN_INTERVAL) // space the writes apart
|
||||
) {
|
||||
const uint16_t peer_mtu = pServer->getPeerMTU(last_conn_id);
|
||||
#if defined(CONFIG_NIMBLE_ENABLED)
|
||||
#if MESH_BLE_USES_NIMBLE
|
||||
const bool notifications_ready =
|
||||
notificationsEnabled.load(std::memory_order_acquire);
|
||||
#else
|
||||
@@ -870,7 +1015,13 @@ size_t SerialBLEInterface::checkRecvFrame(uint8_t dest[]) {
|
||||
_last_write = now;
|
||||
notifySucceeded = false;
|
||||
pTxCharacteristic->setValue(send_queue[0].buf, send_queue[0].len);
|
||||
#if defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
// NimBLE reports queue acceptance directly. Its status callback may run
|
||||
// later; do not retain or duplicate an already accepted frame awaiting it.
|
||||
notifySucceeded = pTxCharacteristic->notify(last_conn_id);
|
||||
#else
|
||||
pTxCharacteristic->notify();
|
||||
#endif
|
||||
|
||||
if (notifySucceeded) {
|
||||
BLE_DEBUG_PRINTLN("writeBytes: sz=%d, hdr=%d", (uint32_t)send_queue[0].len, (uint32_t) send_queue[0].buf[0]);
|
||||
|
||||
@@ -4,19 +4,34 @@
|
||||
#include "../BluetoothMac.h"
|
||||
#include "../BleTxStallWatchdog.h"
|
||||
#include "../UsbLogging.h"
|
||||
#include <BLEDevice.h>
|
||||
#include <BLEServer.h>
|
||||
#include <BLEUtils.h>
|
||||
#include <BLE2902.h>
|
||||
#if defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
#include <NimBLEDevice.h>
|
||||
#else
|
||||
#include <BLEDevice.h>
|
||||
#include <BLEServer.h>
|
||||
#include <BLEUtils.h>
|
||||
#include <BLE2902.h>
|
||||
#endif
|
||||
#if defined(MESH_USE_NIMBLE_ARDUINO) || defined(CONFIG_NIMBLE_ENABLED)
|
||||
#define MESH_BLE_USES_NIMBLE 1
|
||||
#else
|
||||
#define MESH_BLE_USES_NIMBLE 0
|
||||
#endif
|
||||
#include <atomic>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/queue.h>
|
||||
|
||||
class SerialBLEInterface : public BaseSerialInterface, BLESecurityCallbacks, BLEServerCallbacks, BLECharacteristicCallbacks {
|
||||
class SerialBLEInterface : public BaseSerialInterface,
|
||||
#if !defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
public BLESecurityCallbacks,
|
||||
#endif
|
||||
public BLEServerCallbacks, public BLECharacteristicCallbacks {
|
||||
BLEServer *pServer;
|
||||
BLEService *pService;
|
||||
BLECharacteristic * pTxCharacteristic;
|
||||
#if !defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
BLE2902 *pTxDescriptor;
|
||||
#endif
|
||||
bool deviceConnected;
|
||||
bool oldDeviceConnected;
|
||||
bool notifySucceeded;
|
||||
@@ -67,6 +82,16 @@ class SerialBLEInterface : public BaseSerialInterface, BLESecurityCallbacks, BLE
|
||||
bool advertisingAllowed() const;
|
||||
|
||||
protected:
|
||||
#if defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
uint32_t onPassKeyDisplay() override;
|
||||
void onAuthenticationComplete(NimBLEConnInfo& info) override;
|
||||
void onConnect(BLEServer* server, NimBLEConnInfo& info) override;
|
||||
void onDisconnect(BLEServer* server, NimBLEConnInfo& info, int reason) override;
|
||||
void onMTUChange(uint16_t mtu, NimBLEConnInfo& info) override;
|
||||
void onWrite(BLECharacteristic* characteristic, NimBLEConnInfo& info) override;
|
||||
void onSubscribe(BLECharacteristic* characteristic, NimBLEConnInfo& info,
|
||||
uint16_t value) override;
|
||||
#else
|
||||
// BLESecurityCallbacks methods
|
||||
uint32_t onPassKeyRequest() override;
|
||||
void onPassKeyNotify(uint32_t pass_key) override;
|
||||
@@ -98,13 +123,16 @@ protected:
|
||||
void onWrite(BLECharacteristic* pCharacteristic, esp_ble_gatts_cb_param_t* param) override;
|
||||
#endif
|
||||
void onStatus(BLECharacteristic* pCharacteristic, Status status, uint32_t code) override;
|
||||
#endif
|
||||
|
||||
public:
|
||||
SerialBLEInterface() {
|
||||
pServer = NULL;
|
||||
pService = NULL;
|
||||
pTxCharacteristic = NULL;
|
||||
#if !defined(MESH_USE_NIMBLE_ARDUINO)
|
||||
pTxDescriptor = NULL;
|
||||
#endif
|
||||
deviceConnected = false;
|
||||
oldDeviceConnected = false;
|
||||
notifySucceeded = false;
|
||||
|
||||
Reference in new issue
Block a user