Skip to content

Commit b3c309a

Browse files
committed
Implement automatic pairing functionality
- Add new connection management methods that wrap BTstack callbacks - Implement internal handlers that automatically trigger pairing when enabled - Remove need for manual pairing requests in connection callbacks - Update examples to use new callback registration methods - Add comprehensive documentation with migration guide This update makes requestPairingOnConnect() work automatically without requiring manual checks of the flag or explicit pairing requests in user code.
1 parent e9688eb commit b3c309a

File tree

7 files changed

+184
-60
lines changed

7 files changed

+184
-60
lines changed

README.md

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ This library extends the functionality of the arduino-pico core's BTstack implem
3030
- Receive notifications for all pairing events
3131
- Display pairing codes
3232
- Confirm pairing with numeric comparison
33+
- Automatic pairing management through connection callbacks
3334

3435
## Installation
3536

@@ -81,6 +82,19 @@ lib_deps =
8182
#include <BTstackLib.h>
8283
#include <BLESecure.h>
8384

85+
// Callbacks for BLE events
86+
void bleDeviceConnected(BLEStatus status, BLEDevice* device) {
87+
if (status == BLE_STATUS_OK) {
88+
Serial.println("Device connected!");
89+
// No need to manually call BLESecure.requestPairing() here
90+
// It's automatically handled if requestPairingOnConnect is enabled
91+
}
92+
}
93+
94+
void bleDeviceDisconnected(BLEDevice* device) {
95+
Serial.println("Device disconnected!");
96+
}
97+
8498
void setup() {
8599
Serial.begin(115200);
86100

@@ -96,6 +110,10 @@ void setup() {
96110
// Request pairing automatically when a device connects
97111
BLESecure.requestPairingOnConnect(true);
98112

113+
// Register connection callbacks through BLESecure (not BTstack)
114+
BLESecure.setBLEDeviceConnectedCallback(bleDeviceConnected);
115+
BLESecure.setBLEDeviceDisconnectedCallback(bleDeviceDisconnected);
116+
99117
// Start advertising
100118
BTstack.startAdvertising();
101119
}
@@ -108,6 +126,18 @@ void loop() {
108126
}
109127
```
110128
129+
### Connection Management
130+
131+
Register connection and disconnection callbacks through BLESecure instead of directly through BTstack:
132+
133+
```cpp
134+
// Register callbacks through BLESecure for automatic pairing management
135+
BLESecure.setBLEDeviceConnectedCallback(bleDeviceConnected);
136+
BLESecure.setBLEDeviceDisconnectedCallback(bleDeviceDisconnected);
137+
```
138+
139+
This allows the BLESecure library to automatically handle pairing requests based on your `requestPairingOnConnect` setting.
140+
111141
### Setting Up Security Level
112142

113143
Choose the appropriate security level for your application:
@@ -170,6 +200,46 @@ void setup() {
170200
}
171201
```
172202
203+
## Migration Guide
204+
205+
### Version 1.X to 2.X
206+
207+
The 2.X version introduces a new way to handle connection events and automatic pairing. Here are the key changes:
208+
209+
1. **Connection Callbacks**: Register connection and disconnection callbacks through BLESecure instead of BTstack:
210+
```cpp
211+
// Old way:
212+
BTstack.setBLEDeviceConnectedCallback(bleDeviceConnected);
213+
BTstack.setBLEDeviceDisconnectedCallback(bleDeviceDisconnected);
214+
215+
// New way:
216+
BLESecure.setBLEDeviceConnectedCallback(bleDeviceConnected);
217+
BLESecure.setBLEDeviceDisconnectedCallback(bleDeviceDisconnected);
218+
```
219+
220+
2. **Automatic Pairing**: When `requestPairingOnConnect(true)` is set, pairing is now automatically initiated when a device connects. You no longer need to manually check the flag and call `requestPairing()` in your connection callback:
221+
```cpp
222+
// Old way:
223+
void bleDeviceConnected(BLEStatus status, BLEDevice* device) {
224+
if (status == BLE_STATUS_OK) {
225+
// Manually check and request pairing
226+
if (BLESecure._requestPairingOnConnect) {
227+
BLESecure.requestPairing(device);
228+
}
229+
}
230+
}
231+
232+
// New way:
233+
void bleDeviceConnected(BLEStatus status, BLEDevice* device) {
234+
if (status == BLE_STATUS_OK) {
235+
// Pairing is automatically handled if enabled
236+
// No manual check needed
237+
}
238+
}
239+
```
240+
241+
These changes simplify the code required to implement secure BLE connections and ensure consistent behavior across applications.
242+
173243
## Examples
174244
175245
The library includes several example platformIO projects demonstrating its usage:
@@ -210,12 +280,17 @@ The library includes several example platformIO projects demonstrating its usage
210280
211281
#### Pairing Control
212282
213-
- `void requestPairingOnConnect(bool enable)`: Request pairing when a device connects
283+
- `void requestPairingOnConnect(bool enable)`: Request pairing automatically when a device connects
214284
- `bool requestPairing(BLEDevice* device)`: Manually request pairing with a connected device
215285
- `bool bondWithDevice(BLEDevice* device)`: Bond with a device (store keys for reconnection)
216286
- `bool removeBonding(BLEDevice* device)`: Remove bonding information for a device
217287
- `void clearAllBondings()`: Remove all stored bonding information
218288
289+
#### Connection Management
290+
291+
- `void setBLEDeviceConnectedCallback(void (*callback)(BLEStatus status, BLEDevice* device))`: Register callback for device connection events
292+
- `void setBLEDeviceDisconnectedCallback(void (*callback)(BLEDevice* device))`: Register callback for device disconnection events
293+
219294
#### Callback Registration
220295
221296
- `void setPasskeyDisplayCallback(void (*callback)(uint32_t passkey))`: Callback for handling passkey display
@@ -248,5 +323,4 @@ When using this library, you must comply with the terms of both licenses.
248323
Contributions to improve the library are welcome! Please submit pull requests or open issues on the repository.
249324
250325
## Acknowledgements and Credits
251-
This library is based on the [BTstackLib](https://github.com/earlephilhower/arduino-pico/tree/master/libraries/BTstackLib) library for Arduino-Core and Raspberry Pi Pico. Special thanks to the BTstack developers for their work on BLE stack implementation and arduino-pico core maintainers.
252-
```
326+
This library is based on the [BTstackLib](https://github.com/earlephilhower/arduino-pico/tree/master/libraries/BTstackLib) library for Arduino-Core and Raspberry Pi Pico. Special thanks to the BTstack developers for their work on BLE stack implementation and arduino-pico core maintainers.

examples/SecurePairingHigh/src/main.cpp

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,20 @@
2525

2626
// Callbacks for BLE events
2727
void bleDeviceConnected(BLEStatus status, BLEDevice* device) {
28-
if (status == BLE_STATUS_OK) {
29-
Serial.println("Device connected!");
30-
deviceConnected = true;
31-
connectedDevice = device;
32-
33-
// Manually request pairing
34-
if (BLESecure._requestPairingOnConnect) {
35-
BLESecure.requestPairing(device);
36-
}
37-
} else {
38-
Serial.print("Connection failed with status: ");
39-
Serial.println(status);
40-
}
41-
}
28+
if (status == BLE_STATUS_OK) {
29+
Serial.println("Device connected!");
30+
deviceConnected = true;
31+
connectedDevice = device;
32+
33+
// No need to manually check BLESecure._requestPairingOnConnect
34+
// or call BLESecure.requestPairing() here
35+
// The BLESecure library now handles this automatically
36+
37+
} else {
38+
Serial.print("Connection failed with status: ");
39+
Serial.println(status);
40+
}
41+
}
4242

4343
void bleDeviceDisconnected(BLEDevice* device) {
4444
Serial.println("Device disconnected!");
@@ -144,8 +144,9 @@
144144
BLESecure.setNumericComparisonCallback(onNumericComparison);
145145

146146
// Register callbacks for BLE connection events
147-
BTstack.setBLEDeviceConnectedCallback(bleDeviceConnected);
148-
BTstack.setBLEDeviceDisconnectedCallback(bleDeviceDisconnected);
147+
BLESecure.setBLEDeviceConnectedCallback(bleDeviceConnected);
148+
BLESecure.setBLEDeviceDisconnectedCallback(bleDeviceDisconnected);
149+
149150

150151
// Register GATT write callback
151152
BTstack.setGATTCharacteristicWrite(gattWriteCallback);

examples/SecurePairingHighSC/src/main.cpp

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,24 +29,20 @@
2929

3030
// Callbacks for BLE events
3131
void bleDeviceConnected(BLEStatus status, BLEDevice* device) {
32-
if (status == BLE_STATUS_OK) {
33-
Serial.println("Device connected!");
34-
deviceConnected = true;
35-
connectedDevice = device;
36-
37-
// MTU exchange will happen automatically
38-
Serial.println("MTU exchange will happen automatically through BTstack");
39-
40-
// Manually request pairing
41-
if (BLESecure._requestPairingOnConnect) {
42-
Serial.println("Requesting secure pairing with Secure Connections...");
43-
BLESecure.requestPairing(device);
44-
}
45-
} else {
46-
Serial.print("Connection failed with status: ");
47-
Serial.println(status);
48-
}
49-
}
32+
if (status == BLE_STATUS_OK) {
33+
Serial.println("Device connected!");
34+
deviceConnected = true;
35+
connectedDevice = device;
36+
37+
// No need to manually check BLESecure._requestPairingOnConnect
38+
// or call BLESecure.requestPairing() here
39+
// The BLESecure library now handles this automatically
40+
41+
} else {
42+
Serial.print("Connection failed with status: ");
43+
Serial.println(status);
44+
}
45+
}
5046

5147
void bleDeviceDisconnected(BLEDevice* device) {
5248
Serial.println("Device disconnected!");
@@ -183,8 +179,8 @@
183179
BLESecure.setNumericComparisonCallback(onNumericComparison);
184180

185181
// Register callbacks for BLE connection events
186-
BTstack.setBLEDeviceConnectedCallback(bleDeviceConnected);
187-
BTstack.setBLEDeviceDisconnectedCallback(bleDeviceDisconnected);
182+
BLESecure.setBLEDeviceConnectedCallback(bleDeviceConnected);
183+
BLESecure.setBLEDeviceDisconnectedCallback(bleDeviceDisconnected);
188184

189185
// Register GATT write callback
190186
BTstack.setGATTCharacteristicWrite(gattWriteCallback);

examples/SecurePairingMedium/src/main.cpp

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,20 @@
2525

2626
// Callbacks for BLE events
2727
void bleDeviceConnected(BLEStatus status, BLEDevice* device) {
28-
if (status == BLE_STATUS_OK) {
29-
Serial.println("Device connected!");
30-
deviceConnected = true;
31-
connectedDevice = device;
32-
33-
// Manually request pairing if enabled
34-
if (BLESecure._requestPairingOnConnect) {
35-
Serial.println("Requesting secure pairing (MEDIUM - Just Works)...");
36-
BLESecure.requestPairing(device);
37-
}
38-
} else {
39-
Serial.print("Connection failed with status: ");
40-
Serial.println(status);
41-
}
42-
}
28+
if (status == BLE_STATUS_OK) {
29+
Serial.println("Device connected!");
30+
deviceConnected = true;
31+
connectedDevice = device;
32+
33+
// No need to manually check BLESecure._requestPairingOnConnect
34+
// or call BLESecure.requestPairing() here
35+
// The BLESecure library now handles this automatically
36+
37+
} else {
38+
Serial.print("Connection failed with status: ");
39+
Serial.println(status);
40+
}
41+
}
4342

4443
void bleDeviceDisconnected(BLEDevice* device) {
4544
Serial.println("Device disconnected!");
@@ -129,8 +128,8 @@
129128
BLESecure.setPairingStatusCallback(onPairingStatus);
130129

131130
// Register callbacks for BLE connection events
132-
BTstack.setBLEDeviceConnectedCallback(bleDeviceConnected);
133-
BTstack.setBLEDeviceDisconnectedCallback(bleDeviceDisconnected);
131+
BLESecure.setBLEDeviceConnectedCallback(bleDeviceConnected);
132+
BLESecure.setBLEDeviceDisconnectedCallback(bleDeviceDisconnected);
134133

135134
// Register GATT write callback
136135
BTstack.setGATTCharacteristicWrite(gattWriteCallback);

include/BLESecure.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@
9595
// Process security manager events - should be called from the main event handler
9696
void handleSMEvent(uint8_t packet_type, uint16_t channel, uint8_t* packet, uint16_t size);
9797

98+
// Method to register connection callback that also handles auto-pairing
99+
void setBLEDeviceConnectedCallback(void (*callback)(BLEStatus status, BLEDevice* device));
100+
101+
// Method to register disconnection callback
102+
void setBLEDeviceDisconnectedCallback(void (*callback)(BLEDevice* device));
103+
98104
// Flag to indicate if pairing should be automatically requested on connect
99105
bool _requestPairingOnConnect;
100106

@@ -112,11 +118,21 @@
112118
void (*_pairingStatusCallback)(BLEPairingStatus status, BLEDevice* device);
113119
void (*_numericComparisonCallback)(uint32_t passkey, BLEDevice* device);
114120

121+
// Connection and disconnection callbacks
122+
void (*_userConnectedCallback)(BLEStatus status, BLEDevice* device);
123+
void (*_userDisconnectedCallback)(BLEDevice* device);
124+
115125
// Store the current device handle for callbacks
116126
hci_con_handle_t _currentDeviceHandle;
117127

118128
// Register for Security Manager events
119129
void setupSMEventHandler();
130+
131+
// Internal connection callback that handles auto-pairing
132+
static void internalConnectionCallback(BLEStatus status, BLEDevice* device);
133+
134+
// Internal disconnection callback
135+
static void internalDisconnectionCallback(BLEDevice* device);
120136
};
121137

122138
extern BLESecureClass BLESecure;

library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "pico-ble-secure",
3-
"version": "1.0.1",
3+
"version": "2.0.0",
44
"description": "A library for implementing secure Bluetooth Low Energy (BLE) pairing and encryption on Raspberry Pi Pico using the arduino-pico core",
55
"keywords": "bluetooth, BLE, security, pairing, encryption, Pico, arduino-pico, secure connections, MITM protection",
66
"repository": {

src/BLESecure.cpp

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
_passkeyEntryCallback(nullptr),
2828
_pairingStatusCallback(nullptr),
2929
_numericComparisonCallback(nullptr),
30+
_userConnectedCallback(nullptr),
31+
_userDisconnectedCallback(nullptr),
3032
_currentDeviceHandle(HCI_CON_HANDLE_INVALID),
3133
_bondingEnabled(true)
3234
{
@@ -104,9 +106,6 @@
104106

105107
void BLESecureClass::requestPairingOnConnect(bool enable) {
106108
_requestPairingOnConnect = enable;
107-
108-
// Note: We can't directly access BluetoothHCI's protected method setPairOnMeta
109-
// The user will need to manually call requestPairing in the connection callback
110109
}
111110

112111
bool BLESecureClass::requestPairing(BLEDevice* device) {
@@ -243,6 +242,45 @@
243242
sm_event_callback_registration.callback = SMEVENTCB(BLESecureClass, handleSMEvent);
244243
sm_add_event_handler(&sm_event_callback_registration);
245244
}
245+
246+
// New methods for connection/disconnection handling with auto-pairing
247+
void BLESecureClass::setBLEDeviceConnectedCallback(void (*callback)(BLEStatus status, BLEDevice* device)) {
248+
_userConnectedCallback = callback;
249+
BTstack.setBLEDeviceConnectedCallback(internalConnectionCallback);
250+
}
251+
252+
void BLESecureClass::setBLEDeviceDisconnectedCallback(void (*callback)(BLEDevice* device)) {
253+
_userDisconnectedCallback = callback;
254+
BTstack.setBLEDeviceDisconnectedCallback(internalDisconnectionCallback);
255+
}
256+
257+
// Internal connection callback that handles auto-pairing
258+
void BLESecureClass::internalConnectionCallback(BLEStatus status, BLEDevice* device) {
259+
// Auto-request pairing if enabled
260+
if (status == BLE_STATUS_OK && BLESecure._requestPairingOnConnect) {
261+
Serial.println("Auto-requesting pairing as configured in BLESecure");
262+
BLESecure.requestPairing(device);
263+
}
264+
265+
// Call the user's callback if registered
266+
if (BLESecure._userConnectedCallback) {
267+
BLESecure._userConnectedCallback(status, device);
268+
}
269+
}
270+
271+
// Internal disconnection callback
272+
void BLESecureClass::internalDisconnectionCallback(BLEDevice* device) {
273+
// Reset pairing status if this was the device we were pairing with
274+
if (BLESecure._currentDeviceHandle == device->getHandle()) {
275+
BLESecure._pairingStatus = PAIRING_IDLE;
276+
BLESecure._currentDeviceHandle = HCI_CON_HANDLE_INVALID;
277+
}
278+
279+
// Call the user's callback if registered
280+
if (BLESecure._userDisconnectedCallback) {
281+
BLESecure._userDisconnectedCallback(device);
282+
}
283+
}
246284

247285
void BLESecureClass::handleSMEvent(uint8_t packet_type, uint16_t channel, uint8_t* packet, uint16_t size) {
248286
(void)channel;

0 commit comments

Comments
 (0)