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