Closed makmorit closed 1 year ago
e05c081までの対応の結果、管理ツールから「ペアリング解除要求」機能が実行された場合、nRF5340アプリケーション側で、対応するペアリング情報が削除されるようになった事は確認できました。
[00:01:26.385,528] <inf> app_bluetooth: Advertising successfully started (Non-Pairing mode)
[00:02:04.422,851] <inf> app_bluetooth: Connected
[00:02:04.993,743] <inf> app_bluetooth: Connected 2C:33:58:FA:A9:B9 (public) with security level 4
[00:02:05.398,986] <inf> fido_ble_unpairing: Unpairing will process for peer_id=0x0000
Unpairing process for peer_id=0x0000 done
Entering system off; press BUTTON to restart...
以下のケースのように、複数端末でペアリングを実行させた場合に、ペアリング情報削除処理がハングしてしまう不具合が確認されています。
原因ですが、Zephyrのbt_unpair
というAPIの中に、コールバック関数を次々と呼び出すロジックがあり、それがハングの原因となっているのを確認しました。
具体的には、下記SYS_SLIST_FOR_EACH_CONTAINER_SAFE
というブロックが、Zephyr OSから延々と呼び出される動きとなりbt_unpair
が完了せず、結果ファームウェアがハングしてしまいます。
//
// zephyr/subsys/bluetooth/host/hci_core.c
//
int bt_unpair(uint8_t id, const bt_addr_le_t *addr)
{
:
unpair(id, addr);
return 0;
}
static void unpair(uint8_t id, const bt_addr_le_t *addr)
{
:
if (IS_ENABLED(CONFIG_BT_SMP)) {
if (!keys) {
keys = bt_keys_find_addr(id, addr);
}
if (keys) {
bt_keys_clear(keys);
}
}
bt_gatt_clear(id, addr);
#if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR)
struct bt_conn_auth_info_cb *listener, *next;
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&bt_auth_info_cbs, listener,
next, node) {
if (listener->bond_deleted) {
listener->bond_deleted(id, addr);
}
}
#endif /* defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR) */
}
対策ですが、nRF5340アプリケーションに、bt_unpair
と同等の処理(すなわち、オリジナルのコードからSYS_SLIST_FOR_EACH_CONTAINER_SAFE
ブロックを削除した処理)を実装する必要があると考えます。
具体的には以下のようになるかと思われます。
//
// for zephyr/subsys/bluetooth/host/keys.h [注1]
//
struct bt_keys;
struct bt_keys *bt_keys_find_addr(uint8_t id, const bt_addr_le_t *addr);
void bt_keys_clear(struct bt_keys *keys);
bool app_ble_unpairing_delete_peer_id(uint16_t peer_id_to_unpair)
{
// 接続の切断検知時点で、peer_id に対応するペアリング情報を削除
struct bt_keys *keys = bt_keys_find_addr(BT_ID_DEFAULT, &connected_addr_le);
if (keys == NULL) {
return false;
}
// ペアリング鍵情報を削除
bt_keys_clear(keys);
bt_gatt_clear(BT_ID_DEFAULT, &connected_addr_le);
return true;
}
[注1] ヘッダーファイルzephyr/subsys/bluetooth/host/keys.h
が公開されていない為、同ファイルに記述されているプロトタイプを、コードの前方に記述します。
以下のケースのように、複数端末でペアリングを実行させた場合に、ペアリング情報削除処理がハングしてしまう不具合が確認されています。
0b59c69の対応により、不具合が解消された事を確認いたしました。
複数端末によるペアリング解除要求時、最後のペアリング解除要求処理で発生していたハングが解消された事を確認しております。
*** Booting Zephyr OS build v3.2.99-ncs1 ***
:
[00:00:00.544,311] <inf> app_ble_pairing: Already bonded peer is exist (count=2).
[00:00:00.546,539] <inf> app_bluetooth: Advertising successfully started (Non-Pairing mode)
:
[00:00:32.750,976] <inf> app_bluetooth: Connected
[00:00:33.942,871] <inf> app_bluetooth: Connected 2C:33:58:FA:A9:B9 (public) with security level 4
[00:00:36.508,209] <inf> fido_ble_unpairing: Unpairing will process for peer_id=0x0001
Unpairing process for peer_id=0x0001 done
Entering system off; press BUTTON to restart...
*** Booting Zephyr OS build v3.2.99-ncs1 ***
:
[00:00:00.546,752] <inf> app_ble_pairing: Already bonded peer is exist (count=1).
[00:00:00.548,980] <inf> app_bluetooth: Advertising successfully started (Non-Pairing mode)
:
[00:00:16.869,506] <inf> app_bluetooth: Connected
[00:00:16.962,829] <inf> app_bluetooth: Connected 3C:22:FB:87:13:5E (public) with security level 4
[00:00:17.041,320] <wrn> bt_l2cap: Ignoring data for unknown channel ID 0x003a
[00:00:17.165,588] <inf> fido_ble_unpairing: Unpairing will process for peer_id=0x0000
Unpairing process for peer_id=0x0000 done
Entering system off; press BUTTON to restart...
*** Booting Zephyr OS build v3.2.99-ncs1 ***
:
[00:00:00.546,325] <inf> app_ble_pairing: Already bonded peer is not exist.
[00:00:00.548,553] <inf> app_bluetooth: Advertising successfully started (Pairing mode)
:
[00:00:01.642,456] <inf> app_func: Secure device application (PCA10095_01) version 0.4.8 (107)
:
概要
管理ツールから「ペアリング解除要求」機能が実行された場合、nRF5340アプリケーション側で、対応するペアリング情報を削除するためのコマンドを制作します。 (#692、#693 ご参照)