Hello.
I keep trying to control my GoPro camera via BLE. At first I tried to do it using the old sdk, but it didn't work (devzone.nordicsemi.com/.../gopro-control-over-ble-write-char-issue).
I decided to try to do it using the new sdk. I also used the NUS Central example as a base.
My board - nrf52dk/nrf52832 (PCA10040)
Full project code - https://github.com/Sergey1560/nrf52_gopro_zephyr
There is a problem connecting to the camera. More precisely, with changing the security level. Here is the log:
** Booting nRF Connect SDK v3.0.2-89ba1294ac9b *** *** Using Zephyr OS v4.0.99-f791c49f492c *** [00:00:00.847,473] <inf> fs_nvs: 2 Sectors of 4096 bytes [00:00:00.847,473] <inf> fs_nvs: alloc wra: 0, fc8 [00:00:00.847,473] <inf> fs_nvs: data wra: 0, 2c [00:00:00.847,625] <inf> bt_sdc_hci_driver: SoftDevice Controller build revision: 89 9a 50 8a 95 01 9c 58 fc 39 d2 c1 10 04 ee 02 |..P....X .9...... 64 ce 25 be |d.%. [00:00:00.851,409] <inf> bt_hci_core: HW Platform: Nordic Semiconductor (0x0002) [00:00:00.851,440] <inf> bt_hci_core: HW Variant: nRF52x (0x0002) [00:00:00.851,470] <inf> bt_hci_core: Firmware: Standard Bluetooth controller (0x00) Version 137.20634 Build 2617349514 [00:00:00.851,837] <inf> bt_hci_core: No ID address. App must call settings_load() [00:00:00.851,867] <inf> central_gopro: Bluetooth initialized [00:00:00.852,600] <inf> bt_hci_core: Identity: DB:76:0F:4C:9A:35 (random) [00:00:00.852,630] <inf> bt_hci_core: HCI: version 6.0 (0x0e) revision 0x10f3, manufacturer 0x0059 [00:00:00.852,661] <inf> bt_hci_core: LMP: version 6.0 (0x0e) subver 0x10f3 [00:00:00.853,485] <inf> central_gopro: NUS Client module initialized [00:00:00.853,515] <inf> central_gopro: Scan module initialized [00:00:00.854,492] <inf> central_gopro: Scan started [00:00:00.854,492] <inf> central_gopro: Starting Bluetooth Central sample [00:00:01.049,041] <inf> central_gopro: Filters matched. Address: C0:3D:0B:EF:2F:77 (random) connectable: 1 [00:00:01.210,968] <inf> central_gopro: Connected: C0:3D:0B:EF:2F:77 (random) [00:00:01.211,059] <inf> central_gopro: Change security to L2 [00:00:01.211,578] <err> central_gopro: Stop LE scan failed (err 0) [00:00:01.362,579] <inf> central_gopro: MTU exchange done [00:00:01.462,554] <err> bt_smp: pairing failed (peer reason 0x9) [00:00:01.462,768] <wrn> central_gopro: Security failed: C0:3D:0B:EF:2F:77 (random) level 1 err 6 BT_SECURITY_ERR_PAIR_NOT_ALLOWED [00:00:01.462,768] <inf> central_gopro: Start discovery [00:00:01.462,982] <wrn> central_gopro: Pairing failed conn: C0:3D:0B:EF:2F:77 (random), reason 6 BT_SECURITY_ERR_PAIR_NOT_ALLOWED [00:00:01.562,316] <inf> central_gopro: Service not found [00:00:01.562,500] <inf> central_gopro: Disconnected: C0:3D:0B:EF:2F:77 (random), reason 0x13 [00:00:01.563,446] <inf> central_gopro: Scan started
While the camera is not in pairing mode, I get an error BT_SECURITY_ERR_PAIR_NOT_ALLOWED. As you can see, scanning works, a device with the required service is found.
I turn on pairing mode on the camera:
00:00:13.547,943] <inf> central_gopro: Scan started [00:00:13.564,514] <inf> central_gopro: Filters matched. Address: C0:3D:0B:EF:2F:77 (random) connectable: 1 [00:00:13.641,876] <inf> central_gopro: Connected: C0:3D:0B:EF:2F:77 (random) [00:00:13.641,967] <inf> central_gopro: Change security to L2 [00:00:13.642,608] <err> central_gopro: Stop LE scan failed (err 0) [00:00:13.793,487] <inf> central_gopro: MTU exchange done [00:00:13.893,707] <wrn> central_gopro: Security failed: C0:3D:0B:EF:2F:77 (random) level 1 err 4 BT_SECURITY_ERR_AUTH_REQUIREMENT [00:00:13.893,737] <inf> central_gopro: Start discovery [00:00:13.893,920] <wrn> central_gopro: Pairing failed conn: C0:3D:0B:EF:2F:77 (random), reason 4 BT_SECURITY_ERR_AUTH_REQUIREMENT [00:00:14.193,237] <inf> central_gopro: Service discovery completed [00:00:14.193,237] <inf> central_gopro: Assign handles [00:00:14.193,267] <err> nus_c: Missing NUS TX characteristic. [00:00:14.193,298] <inf> central_gopro: Release data [00:00:14.193,481] <inf> central_gopro: Disconnected: C0:3D:0B:EF:2F:77 (random), reason 0x13
Why "Security failed level 1 err 4 BT_SECURITY_ERR_AUTH_REQUIREMENT" ?
In the sniffer it looks like this:
(Full log from wireshark - gopro13_connection_fail.pcapng)
As far as I understand, the process starts with the packet highlighted in blue. The Master sends an AuthReq, the Client responds AuthReq, but then the master sends "Paiting Failed" with reason:
Opcode: Pairing Failed (0x05)
Reason: Authentication Requirements (0x03)
To change the security level, I use the code from the NUS example:
static void connected(struct bt_conn *conn, uint8_t conn_err) { char addr[BT_ADDR_LE_STR_LEN]; int err; bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); if (conn_err) { LOG_INF("Failed to connect to %s, 0x%02x %s", addr, conn_err, bt_hci_err_to_str(conn_err)); if (default_conn == conn) { bt_conn_unref(default_conn); default_conn = NULL; (void)k_work_submit(&scan_work); } return; } LOG_INF("Connected: %s", addr); static struct bt_gatt_exchange_params exchange_params; exchange_params.func = exchange_func; err = bt_gatt_exchange_mtu(conn, &exchange_params); if (err) { LOG_WRN("MTU exchange failed (err %d)", err); } LOG_INF("Change security to L2"); err = bt_conn_set_security(conn, BT_SECURITY_L2); if (err) { LOG_WRN("Failed to set security: %d", err); gatt_discover(conn); } err = bt_scan_stop(); if ((!err) && (err != -EALREADY)) { LOG_ERR("Stop LE scan failed (err %d)", err); } }