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
181 virtual void notifySystemReady() {}
182
186 virtual bool isEnabled() const = 0;
187
188 // === Device Info ===
189
195 virtual bool getMacAddress(uint8_t* mac) const = 0;
196
201 virtual void setDeviceName(const char* name) = 0;
202
206 virtual const char* getDeviceName() const = 0;
207
208 // === Connection ===
209
213 virtual bool isConnected() const = 0;
214
218 virtual void disconnect() = 0;
219
224 virtual int8_t getRssi() const = 0;
225
232 virtual bool getConnectedDeviceName(char* buf, size_t bufLen) const { (void)buf; (void)bufLen; return false; }
233
238 static constexpr uint8_t MAX_BONDED_DEVICES = 5;
239
243 virtual uint8_t getBondedDeviceCount() const { return 0; }
244
251 virtual uint8_t getBondedDevices(BleBondInfo* out, uint8_t maxCount) const {
252 (void)out; (void)maxCount;
253 return 0;
254 }
255
256 // === Advertising ===
257
261 virtual void startAdvertising() {}
262
266 virtual void stopAdvertising() {}
267
271 virtual bool isAdvertising() const { return false; }
272
279 virtual bool addAdvertisingUuid(const BleUuid& uuid) { (void)uuid; return false; }
280
285 virtual void removeAdvertisingUuid(const BleUuid& uuid) { (void)uuid; }
286
295 virtual bool setAdvertisingManufacturerData(uint16_t companyId,
296 const uint8_t* data, uint16_t len) {
297 (void)companyId; (void)data; (void)len;
298 return false;
299 }
300
305
311 virtual void setAppearance(uint16_t appearance) { (void)appearance; }
312
313 // === Scanning ===
314
319 static constexpr uint8_t MAX_SCAN_RESULTS = 64;
320
328 virtual bool startScan(uint32_t durationMs = 5000, bool keepAdvertising = false) {
329 (void)durationMs; (void)keepAdvertising; return false;
330 }
331
335 virtual void stopScan() {}
336
340 virtual bool isScanComplete() const { return true; }
341
348 virtual uint8_t getScanResults(BleScanResult* results, uint8_t maxResults) { (void)results; (void)maxResults; return 0; }
349
350 // === Pairing Callbacks ===
351
352 using PasskeyCallback = std::function<void(uint32_t passkey)>;
353 using AuthCompleteCallback = std::function<void(bool success)>;
354
358 virtual void setPasskeyCallback(PasskeyCallback cb) { (void)cb; }
359
363 virtual void setAuthCompleteCallback(AuthCompleteCallback cb) { (void)cb; }
364
370 using NumericComparisonCallback = std::function<void(uint16_t connHandle, uint32_t passkey)>;
371
382
386 virtual void removeNumericComparisonCallback(ListenerToken token) { (void)token; }
387
393
399 virtual void respondToNumericComparison(uint16_t connHandle, bool accept) {
400 (void)connHandle; (void)accept;
401 }
402
407 using EncChangeCallback = std::function<void(uint16_t connHandle, int status)>;
408
416
420 virtual void removeEncryptionChangeCallback(ListenerToken token) { (void)token; }
421
429 virtual bool initiateSecurity(uint16_t connHandle) { (void)connHandle; return false; }
430
438 virtual bool getPeerIdAddr(uint16_t connHandle, uint8_t addr[6], uint8_t* addrType) const {
439 (void)connHandle; (void)addr; (void)addrType; return false;
440 }
441
442 // === Connection Callbacks (multi-listener) ===
443
444 using ConnectionCallback = std::function<void(uint16_t connHandle)>;
445 using DisconnectionCallback = std::function<void(uint16_t connHandle, int reason)>;
446
453
460
464 virtual void removeConnectionCallback(ListenerToken token) { (void)token; }
465
469 virtual void removeDisconnectionCallback(ListenerToken token) { (void)token; }
470
471 // === Bond Management ===
472
476 virtual void clearAllBonds() {}
477
484 virtual void forgetBond(const uint8_t addr[6], uint8_t addrType) {
485 (void)addr; (void)addrType;
486 }
487
488 // === GATT Server ===
489
499 virtual bool registerGattService(const GattServiceDef& service,
500 bool pluginReserved = false) {
501 (void)service; (void)pluginReserved;
502 return false;
503 }
504
512 virtual bool unregisterGattService(const BleUuid& serviceUuid) {
513 (void)serviceUuid;
514 return false;
515 }
516
525 virtual bool sendNotification(uint16_t connHandle, uint16_t attrHandle,
526 const uint8_t* data, uint16_t len) {
527 (void)connHandle; (void)attrHandle; (void)data; (void)len;
528 return false;
529 }
530
539 virtual bool sendIndication(uint16_t connHandle, uint16_t attrHandle,
540 const uint8_t* data, uint16_t len) {
541 (void)connHandle; (void)attrHandle; (void)data; (void)len;
542 return false;
543 }
544
549 virtual uint16_t getMtu() const { return 20; }
550
551 // === Central Role (GATT Client) ===
552
559 virtual bool connect(const uint8_t* addr, uint8_t addrType = 0) {
560 (void)addr; (void)addrType;
561 return false;
562 }
563
568 virtual void cancelConnect() {}
569
577 virtual bool discoverServiceByUuid(uint16_t connHandle, const BleUuid& uuid) {
578 (void)connHandle; (void)uuid;
579 return false;
580 }
581
591 virtual bool writeCharacteristic(uint16_t connHandle, uint16_t attrHandle,
592 const uint8_t* data, uint16_t len,
593 bool withResponse = true) {
594 (void)connHandle; (void)attrHandle; (void)data; (void)len; (void)withResponse;
595 return false;
596 }
597
604 virtual bool readCharacteristic(uint16_t connHandle, uint16_t attrHandle) {
605 (void)connHandle; (void)attrHandle;
606 return false;
607 }
608
615 virtual bool enableNotifications(uint16_t connHandle, uint16_t cccdHandle) {
616 (void)connHandle; (void)cccdHandle;
617 return false;
618 }
619
631 virtual bool subscribeToCharacteristic(uint16_t connHandle, uint16_t valueHandle) {
632 (void)connHandle; (void)valueHandle;
633 return false;
634 }
635
640 virtual void disconnectHandle(uint16_t connHandle) { (void)connHandle; }
641
642 // === Central Role Callbacks ===
643
649 uint16_t valueHandle;
650 uint8_t properties; // GattProp flags
651 };
652
662
669 using ServiceDiscoveryCallback = std::function<void(uint16_t connHandle,
670 const DiscoveredService* service,
671 bool complete)>;
672
676 using CharacteristicReadCallback = std::function<void(uint16_t connHandle,
677 uint16_t attrHandle,
678 const uint8_t* data, uint16_t len)>;
679
683 using NotificationCallback = std::function<void(uint16_t connHandle,
684 uint16_t attrHandle,
685 const uint8_t* data, uint16_t len)>;
686
690 using WriteCompleteCallback = std::function<void(uint16_t connHandle,
691 uint16_t attrHandle,
692 int status)>;
693
711
712 virtual void removeServiceDiscoveryCallback(ListenerToken token) { (void)token; }
713 virtual void removeCharacteristicReadCallback(ListenerToken token) { (void)token; }
714 virtual void removeNotificationCallback(ListenerToken token) { (void)token; }
715 virtual void removeWriteCompleteCallback(ListenerToken token) { (void)token; }
716
723 virtual void setNotificationCallback(NotificationCallback cb) { (void)cb; }
724 virtual void setWriteCompleteCallback(WriteCompleteCallback cb) { (void)cb; }
725
730 virtual uint16_t getConnectionHandle() const { return 0xFFFF; }
731};
732
733// Namespace-level aliases for the multi-listener token type, so callers can
734// write cdc::hal::ListenerToken / cdc::hal::INVALID_LISTENER.
737
738// Factory function
740
745namespace BleAdvParser {
750 bool findManufacturerData(const uint8_t* advData, uint8_t len,
751 uint16_t* companyId, const uint8_t** data, uint8_t* dataLen);
752
757 bool findServiceUuid128(const uint8_t* advData, uint8_t len,
758 const uint8_t uuid128[16]);
759
764 bool findName(const uint8_t* advData, uint8_t len,
765 char* name, uint8_t nameMaxLen);
766}
767
768} // 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 subscribeToCharacteristic(uint16_t connHandle, uint16_t valueHandle)
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 void notifySystemReady()
Signals that system startup is complete.
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]