hbldh / bleak

A cross platform Bluetooth Low Energy Client for Python using asyncio
MIT License
1.64k stars 282 forks source link

Pairing without passkey failed with Nordic nRF5340 device #1474

Open snowuyl opened 7 months ago

snowuyl commented 7 months ago

Description

I would like to implement pairing without passkey. But it failed to pair with Nordic nRF5340 device. The following are Python code for pairing without passkey. async with BleakClient(device, disconnected_callback=handle_disconnect) as client: paired = await client.pair(protection_level=2)

What I Did

Unzipping pairing.zip python3 pairing.py

Logs

The following are log messages of RTT Viewer. 00> Booting Zephyr OS build v3.3.99-ncs1-1 00> Starting BT test 00> [00:00:00.000,885] bt_gatt: Unable to register handle 0x0016 00> [00:00:00.030,212] bt_hci_core: HW Platform: Nordic Semiconductor (0x0002) 00> [00:00:00.030,242] bt_hci_core: HW Variant: nRF53x (0x0003) 00> [00:00:00.030,242] bt_hci_core: Firmware: Standard Bluetooth controller (0x00) Version 224.11902 Build 2231721665 00> [00:00:00.032,409] bt_hci_core: Identity: D7:D2:19:5F:4D:5D (random) 00> [00:00:00.032,440] bt_hci_core: HCI: version 5.4 (0x0d) revision 0x2077, manufacturer 0x0059 00> [00:00:00.032,440] bt_hci_core: LMP: version 5.4 (0x0d) subver 0x2077 00> [00:00:00.032,470] bt: Bluetooth initialized 00> [00:00:09.599,456] bt: Connected D8:F8:83:9F:72:1A (public) 00> [00:00:09.601,531] bt: MTU=20 00> [00:00:09.601,531] bt: connected 00> [00:00:10.583,404] bt_smp: Not connected! 00> [00:00:10.583,587] bt: Security failed: D8:F8:83:9F:72:1A (public) level 1 err 9 00> [00:00:10.583,709] bt: Pairing failed conn: D8:F8:83:9F:72:1A (public), reason 9 00> [00:00:10.583,984] bt: disconnected: D8:F8:83:9F:72:1A (public) (reason 19)

snowuyl commented 7 months ago

pairing.zip

snowuyl commented 7 months ago

The related source code of nRF5340 DK are listed below. And from log messages (Security failed: D8:F8:83:9F:72:1A (public) level 1 err 9). nRF5340 DK failed to change to BT_SECURITY_L2 (Encryption and no authentication (no MITM)). ret = bt_conn_set_security(conn, BT_SECURITY_L2); if (ret < 0) { LOG_ERR("Failed to set security (err %d)\n", ret); } / Security level. */ typedef enum __packed { /* Level 0: Only for BR/EDR special cases, like SDP / BT_SECURITY_L0, / Level 1: No encryption and no authentication. */ BT_SECURITY_L1, / Level 2: Encryption and no authentication (no MITM). */ BT_SECURITY_L2, /* Level 3: Encryption and authentication (MITM). / BT_SECURITY_L3, / Level 4: Authenticated Secure Connections and 128-bit key. */ BT_SECURITY_L4, /** Bit to force new pairing procedure, bit-wise OR with requested

snowuyl commented 7 months ago

And nRF5340 DK can pair successfully with Device enumeration and pairing sample (https://learn.microsoft.com/en-us/samples/microsoft/windows-universal-samples/deviceenumerationandpairing/). The following are log messages of RTT Viewer. 00> Booting Zephyr OS build v3.3.99-ncs1-1 00> Starting BT test 00> [00:00:00.000,885] bt_gatt: Unable to register handle 0x0016 00> [00:00:00.030,212] bt_hci_core: HW Platform: Nordic Semiconductor (0x0002) 00> [00:00:00.030,242] bt_hci_core: HW Variant: nRF53x (0x0003) 00> [00:00:00.030,273] bt_hci_core: Firmware: Standard Bluetooth controller (0x00) Version 224.11902 Build 2231721665 00> [00:00:00.032,409] bt_hci_core: Identity: D7:D2:19:5F:4D:5D (random) 00> [00:00:00.032,440] bt_hci_core: HCI: version 5.4 (0x0d) revision 0x2077, manufacturer 0x0059 00> [00:00:00.032,470] bt_hci_core: LMP: version 5.4 (0x0d) subver 0x2077 00> [00:00:00.032,470] bt: Bluetooth initialized 00> [00:00:39.298,339] bt: Connected D8:F8:83:9F:72:1A (public) 00> [00:00:39.299,957] bt: MTU=20 00> [00:00:39.299,957] bt: connected 00> [00:00:40.115,325] bt: Pairing completed: D8:F8:83:9F:72:1A (public), bonded: 0 00> [00:00:40.115,509] bt: Security changed: D8:F8:83:9F:72:1A (public) level 2

bojanpotocnik commented 6 months ago

In the pairing.py file you provided, you try to write to the CCCD before initiating pairing:

    async with BleakClient(device, disconnected_callback=handle_disconnect) as client:
        await client.start_notify(UART_TX_CHAR_UUID, handle_rx)
        paired = await client.pair(protection_level=2)
        print(f"Paired: {paired}")

This probably causes the pairing procedure to start implicitly (Just Works) using default protection level 1, as indicated in RTT logs

00> [00:00:10.583,404] bt_smp: Not connected!
00> [00:00:10.583,587] bt: Security failed: D8:F8:83:9F:72:1A (public) level 1 err 9
00> [00:00:10.583,709] bt: Pairing failed conn: D8:F8:83:9F:72:1A (public), reason 9
00> [00:00:10.583,984] bt: disconnected: D8:F8:83:9F:72:1A (public) (reason 19)

(relates to: https://github.com/hbldh/bleak/issues/1465)