esp8266ndn
NDN Arduino library for ESP8266 and more
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ble-server-transport.hpp
Go to the documentation of this file.
1#ifndef ESP8266NDN_BLE_SERVER_TRANSPORT_HPP
2#define ESP8266NDN_BLE_SERVER_TRANSPORT_HPP
3
4#include "../port/port.hpp"
5#include "ble-uuid.hpp"
6
7#if defined(ARDUINO_ARCH_ESP32) && __has_include(<NimBLEDevice.h>)
8#include <NimBLEDevice.h>
9#elif defined(ARDUINO_ARCH_NRF52)
10#include <bluefruit.h>
11#endif
12
13namespace esp8266ndn {
14
16 : public virtual ndnph::Transport
18protected:
19 explicit BleServerTransportBase(size_t mtu);
20
21 void handleReceive(const uint8_t* pkt, size_t pktLen, uint64_t endpointId);
22
23private:
24 void doLoop() override;
25};
26
27#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL
28
30class BleServerTransport : public BleServerTransportBase {
31public:
32 static size_t getMtu() {
33 return 512;
34 }
35
36 BleServerTransport()
37 : BleServerTransportBase(getMtu())
38 , m_csCallbackHandler(*this) {}
39
41 bool begin(const char* deviceName) {
42 NimBLEDevice::init(deviceName);
43 NimBLEDevice::setMTU(517);
44
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);
52 m_svc->start();
53
54 auto adv = NimBLEDevice::getAdvertising();
55 adv->addServiceUUID(makeUuid(BLE_UUID_SVC));
56 adv->enableScanResponse(true);
57 adv->start();
58 return true;
59 }
60
62 String getAddr() const {
63 return String(NimBLEDevice::getAddress().toString().c_str()) + " (addr-type=public)";
64 }
65
66private:
67 static ::BLEUUID makeUuid(const uint8_t a[16]) {
68 return ::BLEUUID(a, 16);
69 }
70
71 bool doIsUp() const final {
72 return m_server != nullptr && m_server->getConnectedCount() > 0;
73 }
74
75 bool doSend(const uint8_t* pkt, size_t pktLen, uint64_t endpointId) final {
76 if (m_sc == nullptr) {
77 return false;
78 }
79 m_sc->setValue(const_cast<uint8_t*>(pkt), pktLen);
80 m_sc->notify();
81 return true;
82 }
83
84private:
85 class CsCallbacks : public NimBLECharacteristicCallbacks {
86 public:
87 explicit CsCallbacks(BleServerTransport& transport)
88 : m_transport(transport) {}
89
90 void onWrite(NimBLECharacteristic* chr, NimBLEConnInfo&) final {
91 if (chr != m_transport.m_cs) {
92 return;
93 }
94 auto value = chr->getValue();
95 m_transport.handleReceive(reinterpret_cast<const uint8_t*>(value.c_str()), value.length(), 0);
96 }
97
98 private:
99 BleServerTransport& m_transport;
100 };
101 CsCallbacks m_csCallbackHandler;
102
103 NimBLEServer* m_server = nullptr;
104 NimBLEService* m_svc = nullptr;
105 NimBLECharacteristic* m_cs = nullptr;
106 NimBLECharacteristic* m_sc = nullptr;
107};
108
109#elif defined(ARDUINO_ARCH_NRF52)
110
117class BleServerTransport
118 : public BleServerTransportBase
119 , public ::BLEService {
120public:
121 static size_t getMtu() {
122 return BLE_GATT_ATT_MTU_MAX - 3;
123 }
124
125 BleServerTransport()
126 : BleServerTransportBase(getMtu())
127 , ::BLEService(BLE_UUID_SVC)
128 , m_cs(BLE_UUID_CS)
129 , m_sc(BLE_UUID_SC) {}
130
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);
139
140 VERIFY_STATUS(begin(), false);
141
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());
150
151 return true;
152 }
153
155 err_t begin() final {
156 VERIFY_STATUS(this->BLEService::begin());
157
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);
161 m_cs.setMaxLen(mtu);
162 m_cs.setWriteCallback(BleServerTransport::handleCsWrite);
163 VERIFY_STATUS(m_cs.begin());
164
165 m_sc.setProperties(CHR_PROPS_READ | CHR_PROPS_NOTIFY);
166 m_sc.setPermission(SECMODE_OPEN, SECMODE_NO_ACCESS);
167 m_sc.setMaxLen(mtu);
168 VERIFY_STATUS(m_sc.begin());
169
170 return 0;
171 }
172
174 String getAddr() const {
175 uint8_t mac[6]; // reversed
176 uint8_t addrType = Bluefruit.getAddr(mac);
177 char addr[18];
178 snprintf(addr, sizeof(addr), "%02X:%02X:%02X:%02X:%02X:%02X", mac[5], mac[4], mac[3], mac[2],
179 mac[1], mac[0]);
180 if (addrType == BLE_GAP_ADDR_TYPE_RANDOM_STATIC) {
181 return String(addr) + " (addr-type=random-static)";
182 }
183 return String(addr) + " (addr-type=" + static_cast<int>(addrType) + ")";
184 }
185
186private:
187 bool doIsUp() const final {
188 return Bluefruit.connected() > 0;
189 }
190
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);
194 }
195
196 static void handleCsWrite(uint16_t connHdl, ::BLECharacteristic* chr, uint8_t* pkt,
197 uint16_t pktLen) {
198 BleServerTransport& self = static_cast<BleServerTransport&>(chr->parentService());
199 self.handleReceive(pkt, pktLen, connHdl);
200 }
201
202 ::BLECharacteristic m_cs;
203 ::BLECharacteristic m_sc;
204};
205
206#endif // ARDUINO_ARCH_*
207
208} // namespace esp8266ndn
209
210#endif // ESP8266NDN_BLE_SERVER_TRANSPORT_HPP
Definition ble-server-transport.hpp:17
void handleReceive(const uint8_t *pkt, size_t pktLen, uint64_t endpointId)
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