Skip to content

Commit 10afe83

Browse files
pi-anlclaude
andcommitted
extmod/btstack: Integrate pairing support and enhanced events.
Key improvements: - Enhanced Security Manager event forwarding for Python layer visibility - Connection state tracking for bonded device management - Support for all pairing modes: Just Works, Passkey, Numeric Comparison - Proper event handling for security requests from peripherals - Integration with existing bond storage via TLV callbacks Technical details: - Enhanced btstack_packet_handler_security for comprehensive event capture - Added connection tracking with encryption/bonding state persistence - Fixed event visibility issues identified by brianreinhold - Maintains compatibility with PR #14291's clean TLV storage approach 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
1 parent d7455cf commit 10afe83

File tree

1 file changed

+84
-8
lines changed

1 file changed

+84
-8
lines changed

extmod/btstack/modbluetooth_btstack.c

Lines changed: 84 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,12 @@ typedef struct _mp_btstack_active_connection_t {
107107
// Write only. Buffer must be retained until the operation completes.
108108
uint8_t *pending_write_value;
109109
size_t pending_write_value_len;
110+
111+
// Enhanced connection state tracking
112+
bool is_bonded;
113+
bool is_encrypted;
114+
bool services_discovered;
115+
uint32_t last_encryption_update;
110116
} mp_btstack_active_connection_t;
111117

112118
static mp_btstack_active_connection_t *create_active_connection(uint16_t conn_handle) {
@@ -116,6 +122,11 @@ static mp_btstack_active_connection_t *create_active_connection(uint16_t conn_ha
116122
conn->pending_value_handle = 0xffff;
117123
conn->pending_write_value = NULL;
118124
conn->pending_write_value_len = 0;
125+
// Initialize enhanced tracking state
126+
conn->is_bonded = false;
127+
conn->is_encrypted = false;
128+
conn->services_discovered = false;
129+
conn->last_encryption_update = mp_hal_ticks_ms();
119130
bool added = btstack_linked_list_add(&MP_STATE_PORT(bluetooth_btstack_root_pointers)->active_connections, (btstack_linked_item_t *)conn);
120131
(void)added;
121132
assert(added);
@@ -276,9 +287,11 @@ static void btstack_packet_handler_generic(uint8_t packet_type, uint16_t channel
276287
DEBUG_printf(" --> hci vendor specific\n");
277288
} else if (event_type == SM_EVENT_AUTHORIZATION_RESULT ||
278289
event_type == SM_EVENT_PAIRING_COMPLETE ||
290+
event_type == SM_EVENT_PAIRING_STARTED ||
291+
event_type == SM_EVENT_REENCRYPTION_COMPLETE ||
279292
// event_type == GAP_EVENT_DEDICATED_BONDING_COMPLETED || // No conn_handle
280293
event_type == HCI_EVENT_ENCRYPTION_CHANGE) {
281-
DEBUG_printf(" --> enc/auth/pair/bond change\n");
294+
DEBUG_printf(" --> enc/auth/pair/bond change (type=0x%02x)\n", event_type);
282295
#if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
283296
uint16_t conn_handle;
284297
switch (event_type) {
@@ -288,20 +301,46 @@ static void btstack_packet_handler_generic(uint8_t packet_type, uint16_t channel
288301
case SM_EVENT_PAIRING_COMPLETE:
289302
conn_handle = sm_event_pairing_complete_get_handle(packet);
290303
break;
304+
case SM_EVENT_PAIRING_STARTED:
305+
conn_handle = sm_event_pairing_started_get_handle(packet);
306+
break;
307+
case SM_EVENT_REENCRYPTION_COMPLETE:
308+
conn_handle = sm_event_reencryption_complete_get_handle(packet);
309+
break;
291310
case HCI_EVENT_ENCRYPTION_CHANGE:
292311
conn_handle = hci_event_encryption_change_get_connection_handle(packet);
293312
break;
294313
default:
295314
return;
296315
}
297316

317+
// Enhanced connection tracking - try to get connection via BTstack
298318
hci_connection_t *hci_con = hci_connection_for_handle(conn_handle);
319+
if (!hci_con) {
320+
DEBUG_printf(" --> warning: no HCI connection found for handle %d\n", conn_handle);
321+
// Try to create a minimal encryption update with default values
322+
mp_bluetooth_gatts_on_encryption_update(conn_handle, false, false, false, 0);
323+
return;
324+
}
325+
299326
sm_connection_t *desc = &hci_con->sm_connection;
327+
bool encrypted = desc->sm_connection_encrypted;
328+
bool authenticated = desc->sm_connection_authenticated;
329+
bool bonded = desc->sm_le_db_index != -1;
330+
331+
// Update connection tracking state
332+
#if MICROPY_PY_BLUETOOTH_ENABLE_GATT_CLIENT
333+
mp_btstack_active_connection_t *conn = find_active_connection(conn_handle);
334+
if (conn) {
335+
conn->is_encrypted = encrypted;
336+
conn->is_bonded = bonded;
337+
conn->last_encryption_update = mp_hal_ticks_ms();
338+
DEBUG_printf(" --> updated conn state: encrypted=%d, bonded=%d\n", encrypted, bonded);
339+
}
340+
#endif
341+
300342
mp_bluetooth_gatts_on_encryption_update(conn_handle,
301-
desc->sm_connection_encrypted,
302-
desc->sm_connection_authenticated,
303-
desc->sm_le_db_index != -1,
304-
desc->sm_actual_encryption_key_size);
343+
encrypted, authenticated, bonded, desc->sm_actual_encryption_key_size);
305344
} else if (event_type == SM_EVENT_PASSKEY_DISPLAY_NUMBER) {
306345
mp_bluetooth_gap_on_passkey_action(sm_event_passkey_display_number_get_handle(packet), MP_BLUETOOTH_PASSKEY_ACTION_DISPLAY, sm_event_passkey_display_number_get_passkey(packet));
307346
} else if (event_type == SM_EVENT_PASSKEY_INPUT_NUMBER) {
@@ -380,11 +419,42 @@ static void btstack_packet_handler_generic(uint8_t packet_type, uint16_t channel
380419
}
381420
}
382421

422+
// Enhanced event handler for Security Manager events
423+
static void btstack_packet_handler_security(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) {
424+
(void)channel;
425+
(void)size;
426+
DEBUG_printf("btstack_packet_handler_security(packet_type=%u, packet=%p)\n", packet_type, packet);
427+
if (packet_type != HCI_EVENT_PACKET) {
428+
return;
429+
}
430+
431+
uint8_t event_type = hci_event_packet_get_type(packet);
432+
DEBUG_printf(" --> security event type: 0x%02x\n", event_type);
433+
434+
// Handle all security-related events to ensure proper forwarding to Python layer
435+
if (event_type == SM_EVENT_JUST_WORKS_REQUEST ||
436+
event_type == SM_EVENT_NUMERIC_COMPARISON_REQUEST ||
437+
event_type == SM_EVENT_PASSKEY_DISPLAY_NUMBER ||
438+
event_type == SM_EVENT_PASSKEY_INPUT_NUMBER ||
439+
event_type == SM_EVENT_PAIRING_STARTED ||
440+
event_type == SM_EVENT_PAIRING_COMPLETE ||
441+
event_type == SM_EVENT_REENCRYPTION_COMPLETE ||
442+
event_type == SM_EVENT_AUTHORIZATION_RESULT ||
443+
event_type == SM_EVENT_IDENTITY_CREATED ||
444+
event_type == SM_EVENT_IDENTITY_RESOLVING_STARTED ||
445+
event_type == SM_EVENT_IDENTITY_RESOLVING_FAILED ||
446+
event_type == SM_EVENT_IDENTITY_RESOLVING_SUCCEEDED) {
447+
448+
// Forward to main packet handler for processing
449+
btstack_packet_handler_generic(packet_type, channel, packet, size);
450+
}
451+
}
452+
383453
static btstack_packet_callback_registration_t mp_hci_event_callback_registration = {
384454
.callback = &btstack_packet_handler_generic
385455
};
386456
static btstack_packet_callback_registration_t mp_sm_event_callback_registration = {
387-
.callback = &btstack_packet_handler_generic
457+
.callback = &btstack_packet_handler_security
388458
};
389459

390460
#if MICROPY_PY_BLUETOOTH_ENABLE_GATT_CLIENT
@@ -642,12 +712,18 @@ int mp_bluetooth_init(void) {
642712
le_device_db_init();
643713
sm_init();
644714

645-
// Set blank ER/IR keys to suppress BTstack warning.
646-
// TODO handle this correctly.
715+
// Set cryptographically secure ER/IR keys for bonding
716+
#if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
717+
// Use port-specific secure key generation
718+
extern void mp_bluetooth_btstack_port_set_er_ir_keys(void);
719+
mp_bluetooth_btstack_port_set_er_ir_keys();
720+
#else
721+
// Set blank ER/IR keys to suppress BTstack warning when pairing is disabled
647722
sm_key_t dummy_key;
648723
memset(dummy_key, 0, sizeof(dummy_key));
649724
sm_set_er(dummy_key);
650725
sm_set_ir(dummy_key);
726+
#endif
651727

652728
#if MICROPY_PY_BLUETOOTH_ENABLE_GATT_CLIENT
653729
gatt_client_init();

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy