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#define ESP8266NDN_BLE_NIMBLE
10#elif defined(ARDUINO_ARCH_NRF52)
12#define ESP8266NDN_BLE_BLUEFRUIT
23 void handleReceive(
const uint8_t* pkt,
size_t pktLen, uint64_t endpointId);
29#if defined(ESP8266NDN_BLE_NIMBLE)
34 static size_t getMtu() {
39 : BleServerTransportBase(getMtu())
40 , m_csCallbackHandler(*this) {}
43 bool begin(
const char* deviceName) {
44 NimBLEDevice::init(deviceName);
45 NimBLEDevice::setMTU(517);
47 m_server = NimBLEDevice::createServer();
48 m_svc = m_server->createService(makeUuid(BLE_UUID_SVC));
49 m_cs = m_svc->createCharacteristic(makeUuid(BLE_UUID_CS),
50 NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::NOTIFY);
51 m_cs->setCallbacks(&m_csCallbackHandler);
52 m_sc = m_svc->createCharacteristic(makeUuid(BLE_UUID_SC),
53 NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);
56 auto adv = NimBLEDevice::getAdvertising();
57 adv->addServiceUUID(makeUuid(BLE_UUID_SVC));
58 adv->enableScanResponse(
true);
64 String getAddr()
const {
65 return String(NimBLEDevice::getAddress().toString().c_str()) +
" (addr-type=public)";
69 static NimBLEUUID makeUuid(
const uint8_t a[16]) {
70 return NimBLEUUID(a, 16);
73 bool doIsUp() const final {
74 return m_server !=
nullptr && m_server->getConnectedCount() > 0;
77 bool doSend(
const uint8_t* pkt,
size_t pktLen, uint64_t endpointId)
final {
78 if (m_sc ==
nullptr) {
81 m_sc->setValue(
const_cast<uint8_t*
>(pkt), pktLen);
87 class CsCallbacks :
public NimBLECharacteristicCallbacks {
89 explicit CsCallbacks(BleServerTransport& transport)
90 : m_transport(transport) {}
92 void onWrite(NimBLECharacteristic* chr, NimBLEConnInfo&)
final {
93 if (chr != m_transport.m_cs) {
96 auto value = chr->getValue();
97 m_transport.handleReceive(
reinterpret_cast<const uint8_t*
>(value.c_str()), value.length(), 0);
101 BleServerTransport& m_transport;
103 CsCallbacks m_csCallbackHandler;
105 NimBLEServer* m_server =
nullptr;
106 NimBLEService* m_svc =
nullptr;
107 NimBLECharacteristic* m_cs =
nullptr;
108 NimBLECharacteristic* m_sc =
nullptr;
111#elif defined(ESP8266NDN_BLE_BLUEFRUIT)
119class BleServerTransport
120 :
public BleServerTransportBase
121 ,
public ::BLEService {
123 static size_t getMtu() {
124 return BLE_GATT_ATT_MTU_MAX - 3;
128 : BleServerTransportBase(getMtu())
129 , ::BLEService(BLE_UUID_SVC)
131 , m_sc(BLE_UUID_SC) {}
134 bool begin(
const char* deviceName) {
135 Bluefruit.configPrphConn(BLE_GATT_ATT_MTU_MAX, BLE_GAP_EVENT_LENGTH_DEFAULT,
136 BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT,
137 BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT);
138 VERIFY(Bluefruit.begin(1, 0));
139 Bluefruit.setName(deviceName);
140 Bluefruit.setTxPower(4);
142 VERIFY_STATUS(begin(),
false);
144 VERIFY(Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE));
145 VERIFY(Bluefruit.Advertising.addTxPower());
146 VERIFY(Bluefruit.Advertising.addService(*
this));
147 VERIFY(Bluefruit.ScanResponse.addName());
148 Bluefruit.Advertising.restartOnDisconnect(
true);
149 Bluefruit.Advertising.setInterval(32, 244);
150 Bluefruit.Advertising.setFastTimeout(30);
151 VERIFY(Bluefruit.Advertising.start());
157 err_t begin() final {
158 VERIFY_STATUS(this->BLEService::begin());
160 uint16_t mtu = Bluefruit.getMaxMtu(CONN_CFG_PERIPHERAL);
161 m_cs.setProperties(CHR_PROPS_WRITE | CHR_PROPS_NOTIFY);
162 m_cs.setPermission(SECMODE_OPEN, SECMODE_OPEN);
164 m_cs.setWriteCallback(BleServerTransport::handleCsWrite);
165 VERIFY_STATUS(m_cs.begin());
167 m_sc.setProperties(CHR_PROPS_READ | CHR_PROPS_NOTIFY);
168 m_sc.setPermission(SECMODE_OPEN, SECMODE_NO_ACCESS);
170 VERIFY_STATUS(m_sc.begin());
176 String getAddr()
const {
178 uint8_t addrType = Bluefruit.getAddr(mac);
180 snprintf(addr,
sizeof(addr),
"%02X:%02X:%02X:%02X:%02X:%02X", mac[5], mac[4], mac[3], mac[2],
182 if (addrType == BLE_GAP_ADDR_TYPE_RANDOM_STATIC) {
183 return String(addr) +
" (addr-type=random-static)";
185 return String(addr) +
" (addr-type=" +
static_cast<int>(addrType) +
")";
189 bool doIsUp() const final {
190 return Bluefruit.connected() > 0;
193 bool doSend(
const uint8_t* pkt,
size_t pktLen, uint64_t endpointId)
final {
194 m_sc.write(pkt, pktLen);
195 return m_sc.notify(pkt, pktLen);
198 static void handleCsWrite(uint16_t connHdl, ::BLECharacteristic* chr, uint8_t* pkt,
200 BleServerTransport& self =
static_cast<BleServerTransport&
>(chr->parentService());
201 self.handleReceive(pkt, pktLen, connHdl);
204 ::BLECharacteristic m_cs;
205 ::BLECharacteristic m_sc;
Definition ble-server-transport.hpp:19
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