1#ifndef ESP8266NDN_BLE_SERVER_TRANSPORT_HPP
2#define ESP8266NDN_BLE_SERVER_TRANSPORT_HPP
4#include "../port/port.hpp"
7#if defined(ARDUINO_ARCH_ESP32) && __has_include(<NimBLEDevice.h>)
8#include <NimBLEDevice.h>
9#elif defined(ARDUINO_ARCH_NRF52)
21 void handleReceive(
const uint8_t* pkt,
size_t pktLen, uint64_t endpointId);
27#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL
32 static size_t getMtu() {
37 : BleServerTransportBase(getMtu())
38 , m_csCallbackHandler(*this) {}
41 bool begin(
const char* deviceName) {
42 NimBLEDevice::init(deviceName);
43 NimBLEDevice::setMTU(517);
45 m_server = NimBLEDevice::createServer();
46 m_svc = m_server->createService(makeUuid(BLE_UUID_SVC));
47 m_cs = m_svc->createCharacteristic(makeUuid(BLE_UUID_CS),
48 NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::NOTIFY);
49 m_cs->setCallbacks(&m_csCallbackHandler);
50 m_sc = m_svc->createCharacteristic(makeUuid(BLE_UUID_SC),
51 NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);
54 auto adv = NimBLEDevice::getAdvertising();
55 adv->addServiceUUID(makeUuid(BLE_UUID_SVC));
56 adv->enableScanResponse(
true);
62 String getAddr()
const {
63 return String(NimBLEDevice::getAddress().toString().c_str()) +
" (addr-type=public)";
67 static ::BLEUUID makeUuid(
const uint8_t a[16]) {
68 return ::BLEUUID(a, 16);
71 bool doIsUp() const final {
72 return m_server !=
nullptr && m_server->getConnectedCount() > 0;
75 bool doSend(
const uint8_t* pkt,
size_t pktLen, uint64_t endpointId)
final {
76 if (m_sc ==
nullptr) {
79 m_sc->setValue(
const_cast<uint8_t*
>(pkt), pktLen);
85 class CsCallbacks :
public NimBLECharacteristicCallbacks {
87 explicit CsCallbacks(BleServerTransport& transport)
88 : m_transport(transport) {}
90 void onWrite(NimBLECharacteristic* chr, NimBLEConnInfo&)
final {
91 if (chr != m_transport.m_cs) {
94 auto value = chr->getValue();
95 m_transport.handleReceive(
reinterpret_cast<const uint8_t*
>(value.c_str()), value.length(), 0);
99 BleServerTransport& m_transport;
101 CsCallbacks m_csCallbackHandler;
103 NimBLEServer* m_server =
nullptr;
104 NimBLEService* m_svc =
nullptr;
105 NimBLECharacteristic* m_cs =
nullptr;
106 NimBLECharacteristic* m_sc =
nullptr;
109#elif defined(ARDUINO_ARCH_NRF52)
117class BleServerTransport
118 :
public BleServerTransportBase
119 ,
public ::BLEService {
121 static size_t getMtu() {
122 return BLE_GATT_ATT_MTU_MAX - 3;
126 : BleServerTransportBase(getMtu())
127 , ::BLEService(BLE_UUID_SVC)
129 , m_sc(BLE_UUID_SC) {}
132 bool begin(
const char* deviceName) {
133 Bluefruit.configPrphConn(BLE_GATT_ATT_MTU_MAX, BLE_GAP_EVENT_LENGTH_DEFAULT,
134 BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT,
135 BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT);
136 VERIFY(Bluefruit.begin(1, 0));
137 Bluefruit.setName(deviceName);
138 Bluefruit.setTxPower(4);
140 VERIFY_STATUS(begin(),
false);
142 VERIFY(Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE));
143 VERIFY(Bluefruit.Advertising.addTxPower());
144 VERIFY(Bluefruit.Advertising.addService(*
this));
145 VERIFY(Bluefruit.ScanResponse.addName());
146 Bluefruit.Advertising.restartOnDisconnect(
true);
147 Bluefruit.Advertising.setInterval(32, 244);
148 Bluefruit.Advertising.setFastTimeout(30);
149 VERIFY(Bluefruit.Advertising.start());
155 err_t begin() final {
156 VERIFY_STATUS(this->BLEService::begin());
158 uint16_t mtu = Bluefruit.getMaxMtu(CONN_CFG_PERIPHERAL);
159 m_cs.setProperties(CHR_PROPS_WRITE | CHR_PROPS_NOTIFY);
160 m_cs.setPermission(SECMODE_OPEN, SECMODE_OPEN);
162 m_cs.setWriteCallback(BleServerTransport::handleCsWrite);
163 VERIFY_STATUS(m_cs.begin());
165 m_sc.setProperties(CHR_PROPS_READ | CHR_PROPS_NOTIFY);
166 m_sc.setPermission(SECMODE_OPEN, SECMODE_NO_ACCESS);
168 VERIFY_STATUS(m_sc.begin());
174 String getAddr()
const {
176 uint8_t addrType = Bluefruit.getAddr(mac);
178 snprintf(addr,
sizeof(addr),
"%02X:%02X:%02X:%02X:%02X:%02X", mac[5], mac[4], mac[3], mac[2],
180 if (addrType == BLE_GAP_ADDR_TYPE_RANDOM_STATIC) {
181 return String(addr) +
" (addr-type=random-static)";
183 return String(addr) +
" (addr-type=" +
static_cast<int>(addrType) +
")";
187 bool doIsUp() const final {
188 return Bluefruit.connected() > 0;
191 bool doSend(
const uint8_t* pkt,
size_t pktLen, uint64_t endpointId)
final {
192 m_sc.write(pkt, pktLen);
193 return m_sc.notify(pkt, pktLen);
196 static void handleCsWrite(uint16_t connHdl, ::BLECharacteristic* chr, uint8_t* pkt,
198 BleServerTransport& self =
static_cast<BleServerTransport&
>(chr->parentService());
199 self.handleReceive(pkt, pktLen, connHdl);
202 ::BLECharacteristic m_cs;
203 ::BLECharacteristic m_sc;
Definition ble-server-transport.hpp:17
void handleReceive(const uint8_t *pkt, size_t pktLen, uint64_t endpointId)
BleServerTransportBase(size_t mtu)
Mixin of RX queue in Transport, allocating buffers from DynamicRegion.
Definition transport-rxqueue.hpp:134
Base class of low-level transport.
Definition transport.hpp:10
Definition autoconfig.hpp:24