CDC Badge OS
Firmware for the CDC Badge v1.0 hardware security key
Loading...
Searching...
No Matches
IBluetoothController.h
Go to the documentation of this file.
1#pragma once
2
3#include "cdc_core/IService.h"
4#include <cstdint>
5#include <cstring>
6#include <functional>
7
8namespace cdc::hal {
9
14 char name[32];
15 uint8_t mac[6];
16 uint8_t addrType; // 0=public, 1=random
17 int8_t rssi;
18 uint8_t advData[31]; // Raw advertising data (AD structures)
19 uint8_t advDataLen;
20};
21
26 uint8_t addr[6]; // Identity address
27 uint8_t addrType; // 0=public, 1=random
28 bool connected; // Currently in an active connection
29};
30
34struct BleUuid {
35 enum Type : uint8_t { UUID_16 = 0, UUID_128 = 1 };
37 union {
38 uint16_t u16;
39 uint8_t u128[16];
40 };
41
42 static BleUuid from16(uint16_t v) {
43 BleUuid u;
44 u.type = UUID_16;
45 // u16 and u128 alias in the union: zero first, then set the value
46 std::memset(u.u128, 0, sizeof(u.u128));
47 u.u16 = v;
48 return u;
49 }
50
51 static BleUuid from128(const uint8_t v[16]) {
52 BleUuid u;
53 u.type = UUID_128;
54 std::memcpy(u.u128, v, 16);
55 return u;
56 }
57
58 bool operator==(const BleUuid& other) const {
59 if (type != other.type) return false;
60 if (type == UUID_16) return u16 == other.u16;
61 return std::memcmp(u128, other.u128, 16) == 0;
62 }
63};
64
69namespace GattProp {
70 constexpr uint8_t READ = 0x02;
71 constexpr uint8_t WRITE_NO_RSP = 0x04;
72 constexpr uint8_t WRITE = 0x08;
73 constexpr uint8_t NOTIFY = 0x10;
74 constexpr uint8_t INDICATE = 0x20;
75}
76
80namespace GattPerm {
81 constexpr uint8_t READ = 0x01;
82 constexpr uint8_t WRITE = 0x02;
83 constexpr uint8_t READ_ENC = 0x04; // Requires encryption (pairing)
84 constexpr uint8_t WRITE_ENC = 0x08; // Requires encryption (pairing)
85}
86
90using GattWriteCallback = std::function<int(uint16_t connHandle, uint16_t attrHandle,
91 const uint8_t* data, uint16_t len)>;
92
96using GattReadCallback = std::function<int(uint16_t connHandle, uint16_t attrHandle,
97 uint8_t* buf, uint16_t* len)>;
98
102enum class GattDescriptorKind : uint8_t {
103 NONE = 0,
104 REPORT_REFERENCE = 1, // 0x2908 - HID Report Reference (2 bytes: reportId, reportType)
105};
106
113 uint8_t data[4]; // Descriptor value bytes
114 uint8_t dataLen; // Number of valid bytes in data
115};
116
122 uint8_t properties; // GattProp flags
123 uint8_t permissions; // GattPerm flags
124 uint16_t* valueHandle; // Output: handle assigned by stack
127 const GattDescriptor* descriptors = nullptr; // Optional descriptor list
128 uint8_t numDescriptors = 0;
129};
130
139
145public:
146 virtual ~IBluetoothController() = default;
147
152 using ListenerToken = uint16_t;
153 static constexpr ListenerToken INVALID_LISTENER = 0xFFFF;
154
155 // GATT server limits (single source of truth for the controller and any
156 // caller validating a service before registerGattService()).
157 static constexpr uint8_t MAX_REGISTERED_SERVICES = 7;
158 static constexpr uint8_t MAX_CHARS_PER_SERVICE = 6;
159
160 // === Power Control ===
161
166 virtual bool enable() = 0;
167
171 virtual void disable() = 0;
172
176 virtual bool isEnabled() const = 0;
177
178 // === Device Info ===
179
185 virtual bool getMacAddress(uint8_t* mac) const = 0;
186
191 virtual void setDeviceName(const char* name) = 0;
192
196 virtual const char* getDeviceName() const = 0;
197
198 // === Connection ===
199
203 virtual bool isConnected() const = 0;
204
208 virtual void disconnect() = 0;
209
214 virtual int8_t getRssi() const = 0;
215
222 virtual bool getConnectedDeviceName(char* buf, size_t bufLen) const { (void)buf; (void)bufLen; return false; }
223
228 static constexpr uint8_t MAX_BONDED_DEVICES = 5;
229
233 virtual uint8_t getBondedDeviceCount() const { return 0; }
234
241 virtual uint8_t getBondedDevices(BleBondInfo* out, uint8_t maxCount) const {
242 (void)out; (void)maxCount;
243 return 0;
244 }
245
246 // === Advertising ===
247
251 virtual void startAdvertising() {}
252
256 virtual void stopAdvertising() {}
257
261 virtual bool isAdvertising() const { return false; }
262
269 virtual bool addAdvertisingUuid(const BleUuid& uuid) { (void)uuid; return false; }
270
275 virtual void removeAdvertisingUuid(const BleUuid& uuid) { (void)uuid; }
276
285 virtual bool setAdvertisingManufacturerData(uint16_t companyId,
286 const uint8_t* data, uint16_t len) {
287 (void)companyId; (void)data; (void)len;
288 return false;
289 }
290
295
301 virtual void setAppearance(uint16_t appearance) { (void)appearance; }
302
303 // === Scanning ===
304
309 static constexpr uint8_t MAX_SCAN_RESULTS = 64;
310
318 virtual bool startScan(uint32_t durationMs = 5000, bool keepAdvertising = false) {
319 (void)durationMs; (void)keepAdvertising; return false;
320 }
321
325 virtual void stopScan() {}
326
330 virtual bool isScanComplete() const { return true; }
331
338 virtual uint8_t getScanResults(BleScanResult* results, uint8_t maxResults) { (void)results; (void)maxResults; return 0; }
339
340 // === Pairing Callbacks ===
341
342 using PasskeyCallback = std::function<void(uint32_t passkey)>;
343 using AuthCompleteCallback = std::function<void(bool success)>;
344
348 virtual void setPasskeyCallback(PasskeyCallback cb) { (void)cb; }
349
353 virtual void setAuthCompleteCallback(AuthCompleteCallback cb) { (void)cb; }
354
360 using NumericComparisonCallback = std::function<void(uint16_t connHandle, uint32_t passkey)>;
361
372
376 virtual void removeNumericComparisonCallback(ListenerToken token) { (void)token; }
377
383
389 virtual void respondToNumericComparison(uint16_t connHandle, bool accept) {
390 (void)connHandle; (void)accept;
391 }
392
397 using EncChangeCallback = std::function<void(uint16_t connHandle, int status)>;
398
406
410 virtual void removeEncryptionChangeCallback(ListenerToken token) { (void)token; }
411
419 virtual bool initiateSecurity(uint16_t connHandle) { (void)connHandle; return false; }
420
428 virtual bool getPeerIdAddr(uint16_t connHandle, uint8_t addr[6], uint8_t* addrType) const {
429 (void)connHandle; (void)addr; (void)addrType; return false;
430 }
431
432 // === Connection Callbacks (multi-listener) ===
433
434 using ConnectionCallback = std::function<void(uint16_t connHandle)>;
435 using DisconnectionCallback = std::function<void(uint16_t connHandle, int reason)>;
436
443
450
454 virtual void removeConnectionCallback(ListenerToken token) { (void)token; }
455
459 virtual void removeDisconnectionCallback(ListenerToken token) { (void)token; }
460
461 // === Bond Management ===
462
466 virtual void clearAllBonds() {}
467
474 virtual void forgetBond(const uint8_t addr[6], uint8_t addrType) {
475 (void)addr; (void)addrType;
476 }
477
478 // === GATT Server ===
479
489 virtual bool registerGattService(const GattServiceDef& service,
490 bool pluginReserved = false) {
491 (void)service; (void)pluginReserved;
492 return false;
493 }
494
502 virtual bool unregisterGattService(const BleUuid& serviceUuid) {
503 (void)serviceUuid;
504 return false;
505 }
506
515 virtual bool sendNotification(uint16_t connHandle, uint16_t attrHandle,
516 const uint8_t* data, uint16_t len) {
517 (void)connHandle; (void)attrHandle; (void)data; (void)len;
518 return false;
519 }
520
529 virtual bool sendIndication(uint16_t connHandle, uint16_t attrHandle,
530 const uint8_t* data, uint16_t len) {
531 (void)connHandle; (void)attrHandle; (void)data; (void)len;
532 return false;
533 }
534
539 virtual uint16_t getMtu() const { return 20; }
540
541 // === Central Role (GATT Client) ===
542
549 virtual bool connect(const uint8_t* addr, uint8_t addrType = 0) {
550 (void)addr; (void)addrType;
551 return false;
552 }
553
558 virtual void cancelConnect() {}
559
567 virtual bool discoverServiceByUuid(uint16_t connHandle, const BleUuid& uuid) {
568 (void)connHandle; (void)uuid;
569 return false;
570 }
571
581 virtual bool writeCharacteristic(uint16_t connHandle, uint16_t attrHandle,
582 const uint8_t* data, uint16_t len,
583 bool withResponse = true) {
584 (void)connHandle; (void)attrHandle; (void)data; (void)len; (void)withResponse;
585 return false;
586 }
587
594 virtual bool readCharacteristic(uint16_t connHandle, uint16_t attrHandle) {
595 (void)connHandle; (void)attrHandle;
596 return false;
597 }
598
605 virtual bool enableNotifications(uint16_t connHandle, uint16_t cccdHandle) {
606 (void)connHandle; (void)cccdHandle;
607 return false;
608 }
609
614 virtual void disconnectHandle(uint16_t connHandle) { (void)connHandle; }
615
616 // === Central Role Callbacks ===
617
623 uint16_t valueHandle;
624 uint8_t properties; // GattProp flags
625 };
626
636
643 using ServiceDiscoveryCallback = std::function<void(uint16_t connHandle,
644 const DiscoveredService* service,
645 bool complete)>;
646
650 using CharacteristicReadCallback = std::function<void(uint16_t connHandle,
651 uint16_t attrHandle,
652 const uint8_t* data, uint16_t len)>;
653
657 using NotificationCallback = std::function<void(uint16_t connHandle,
658 uint16_t attrHandle,
659 const uint8_t* data, uint16_t len)>;
660
664 using WriteCompleteCallback = std::function<void(uint16_t connHandle,
665 uint16_t attrHandle,
666 int status)>;
667
685
686 virtual void removeServiceDiscoveryCallback(ListenerToken token) { (void)token; }
687 virtual void removeCharacteristicReadCallback(ListenerToken token) { (void)token; }
688 virtual void removeNotificationCallback(ListenerToken token) { (void)token; }
689 virtual void removeWriteCompleteCallback(ListenerToken token) { (void)token; }
690
697 virtual void setNotificationCallback(NotificationCallback cb) { (void)cb; }
698 virtual void setWriteCompleteCallback(WriteCompleteCallback cb) { (void)cb; }
699
704 virtual uint16_t getConnectionHandle() const { return 0xFFFF; }
705};
706
707// Namespace-level aliases for the multi-listener token type, so callers can
708// write cdc::hal::ListenerToken / cdc::hal::INVALID_LISTENER.
711
712// Factory function
714
719namespace BleAdvParser {
724 bool findManufacturerData(const uint8_t* advData, uint8_t len,
725 uint16_t* companyId, const uint8_t** data, uint8_t* dataLen);
726
731 bool findServiceUuid128(const uint8_t* advData, uint8_t len,
732 const uint8_t uuid128[16]);
733
738 bool findName(const uint8_t* advData, uint8_t len,
739 char* name, uint8_t nameMaxLen);
740}
741
742} // namespace cdc::hal
char name[cdc::hal::ISecureElement::RMEM_NAME_LEN]
std::function< void(uint16_t connHandle)> ConnectionCallback
virtual void setCharacteristicReadCallback(CharacteristicReadCallback cb)
virtual void removeNumericComparisonCallback(ListenerToken token)
virtual bool readCharacteristic(uint16_t connHandle, uint16_t attrHandle)
std::function< void(uint32_t passkey)> PasskeyCallback
virtual void disconnectHandle(uint16_t connHandle)
virtual bool connect(const uint8_t *addr, uint8_t addrType=0)
virtual void removeDisconnectionCallback(ListenerToken token)
virtual ListenerToken addDisconnectionCallback(DisconnectionCallback cb)
virtual ListenerToken addWriteCompleteCallback(WriteCompleteCallback cb)
virtual ListenerToken addCharacteristicReadCallback(CharacteristicReadCallback cb)
virtual void removeEncryptionChangeCallback(ListenerToken token)
virtual bool enableNotifications(uint16_t connHandle, uint16_t cccdHandle)
virtual const char * getDeviceName() const =0
virtual ListenerToken addServiceDiscoveryCallback(ServiceDiscoveryCallback cb)
virtual bool getMacAddress(uint8_t *mac) const =0
virtual bool addAdvertisingUuid(const BleUuid &uuid)
std::function< void(uint16_t connHandle, int status)> EncChangeCallback
static constexpr uint8_t MAX_SCAN_RESULTS
virtual ListenerToken addNotificationCallback(NotificationCallback cb)
std::function< void(uint16_t connHandle, uint16_t attrHandle, const uint8_t *data, uint16_t len)> CharacteristicReadCallback
virtual bool getPeerIdAddr(uint16_t connHandle, uint8_t addr[6], uint8_t *addrType) const
virtual void removeNotificationCallback(ListenerToken token)
virtual void removeCharacteristicReadCallback(ListenerToken token)
virtual bool setAdvertisingManufacturerData(uint16_t companyId, const uint8_t *data, uint16_t len)
virtual void removeAdvertisingUuid(const BleUuid &uuid)
virtual bool getConnectedDeviceName(char *buf, size_t bufLen) const
std::function< void(bool success)> AuthCompleteCallback
virtual bool unregisterGattService(const BleUuid &serviceUuid)
std::function< void(uint16_t connHandle, const DiscoveredService *service, bool complete)> ServiceDiscoveryCallback
virtual void removeServiceDiscoveryCallback(ListenerToken token)
virtual bool startScan(uint32_t durationMs=5000, bool keepAdvertising=false)
std::function< void(uint16_t connHandle, uint32_t passkey)> NumericComparisonCallback
virtual void forgetBond(const uint8_t addr[6], uint8_t addrType)
virtual uint8_t getBondedDeviceCount() const
virtual void removeWriteCompleteCallback(ListenerToken token)
virtual void setNumericComparisonCallback(NumericComparisonCallback cb)
virtual ListenerToken addConnectionCallback(ConnectionCallback cb)
static constexpr ListenerToken INVALID_LISTENER
virtual bool isEnabled() const =0
virtual void setWriteCompleteCallback(WriteCompleteCallback cb)
virtual bool isConnected() const =0
virtual void setNotificationCallback(NotificationCallback cb)
virtual void setDeviceName(const char *name)=0
virtual uint16_t getConnectionHandle() const
virtual void removeConnectionCallback(ListenerToken token)
static constexpr uint8_t MAX_BONDED_DEVICES
std::function< void(uint16_t connHandle, int reason)> DisconnectionCallback
virtual bool discoverServiceByUuid(uint16_t connHandle, const BleUuid &uuid)
virtual ListenerToken addEncryptionChangeCallback(EncChangeCallback cb)
virtual uint8_t getScanResults(BleScanResult *results, uint8_t maxResults)
virtual ListenerToken addNumericComparisonCallback(NumericComparisonCallback cb)
virtual bool sendIndication(uint16_t connHandle, uint16_t attrHandle, const uint8_t *data, uint16_t len)
virtual void respondToNumericComparison(uint16_t connHandle, bool accept)
virtual uint8_t getBondedDevices(BleBondInfo *out, uint8_t maxCount) const
virtual bool writeCharacteristic(uint16_t connHandle, uint16_t attrHandle, const uint8_t *data, uint16_t len, bool withResponse=true)
static constexpr uint8_t MAX_CHARS_PER_SERVICE
virtual void setAppearance(uint16_t appearance)
virtual void setServiceDiscoveryCallback(ServiceDiscoveryCallback cb)
virtual bool initiateSecurity(uint16_t connHandle)
virtual ~IBluetoothController()=default
virtual bool registerGattService(const GattServiceDef &service, bool pluginReserved=false)
std::function< void(uint16_t connHandle, uint16_t attrHandle, const uint8_t *data, uint16_t len)> NotificationCallback
virtual int8_t getRssi() const =0
virtual bool sendNotification(uint16_t connHandle, uint16_t attrHandle, const uint8_t *data, uint16_t len)
static constexpr uint8_t MAX_REGISTERED_SERVICES
std::function< void(uint16_t connHandle, uint16_t attrHandle, int status)> WriteCompleteCallback
virtual void setPasskeyCallback(PasskeyCallback cb)
virtual void setAuthCompleteCallback(AuthCompleteCallback cb)
bool findServiceUuid128(const uint8_t *advData, uint8_t len, const uint8_t uuid128[16])
Checks whether a specific 128-bit service UUID is present in AD structures.
bool findManufacturerData(const uint8_t *advData, uint8_t len, uint16_t *companyId, const uint8_t **data, uint8_t *dataLen)
Extracts manufacturer-specific AD payload and company identifier.
bool findName(const uint8_t *advData, uint8_t len, char *name, uint8_t nameMaxLen)
Extracts local device name from advertising data.
constexpr uint8_t READ_ENC
constexpr uint8_t WRITE_ENC
constexpr uint8_t WRITE
constexpr uint8_t READ
constexpr uint8_t INDICATE
constexpr uint8_t NOTIFY
constexpr uint8_t READ
constexpr uint8_t WRITE_NO_RSP
constexpr uint8_t WRITE
std::function< int(uint16_t connHandle, uint16_t attrHandle, uint8_t *buf, uint16_t *len)> GattReadCallback
constexpr ListenerToken INVALID_LISTENER
IBluetoothController * getBluetoothControllerInstance()
Returns singleton Bluetooth stub when NimBLE is unavailable.
std::function< int(uint16_t connHandle, uint16_t attrHandle, const uint8_t *data, uint16_t len)> GattWriteCallback
IBluetoothController::ListenerToken ListenerToken
static BleUuid from16(uint16_t v)
static BleUuid from128(const uint8_t v[16])
bool operator==(const BleUuid &other) const
const GattDescriptor * descriptors
GattCharacteristic * characteristics
DiscoveredCharacteristic characteristics[MAX_DISCOVERED_CHARS]