From 8a7a737a146787a3d31fd451da8ad0058e7dbe87 Mon Sep 17 00:00:00 2001 From: Hakan Jansson Date: Wed, 21 Aug 2024 13:52:19 +0200 Subject: [PATCH] samples: bluetooth: Fix PAwR null dereference on disconnection If an involuntary disconnection happened it could set default_conn to NULL while it was still being used in the main while loop. Signed-off-by: Hakan Jansson --- samples/bluetooth/periodic_adv_rsp/src/main.c | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/samples/bluetooth/periodic_adv_rsp/src/main.c b/samples/bluetooth/periodic_adv_rsp/src/main.c index a139487a27c..5ec3f32379a 100644 --- a/samples/bluetooth/periodic_adv_rsp/src/main.c +++ b/samples/bluetooth/periodic_adv_rsp/src/main.c @@ -20,6 +20,13 @@ static K_SEM_DEFINE(sem_discovered, 0, 1); static K_SEM_DEFINE(sem_written, 0, 1); static K_SEM_DEFINE(sem_disconnected, 0, 1); +struct k_poll_event events[] = { + K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, + &sem_connected, 0), + K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, + &sem_disconnected, 0), +}; + static struct bt_uuid_128 pawr_char_uuid = BT_UUID_INIT_128(BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef1)); static uint16_t pawr_attr_handle; @@ -116,9 +123,6 @@ void disconnected_cb(struct bt_conn *conn, uint8_t reason) { printk("Disconnected, reason 0x%02X %s\n", reason, bt_hci_err_to_str(reason)); - bt_conn_unref(default_conn); - default_conn = NULL; - k_sem_give(&sem_disconnected); } @@ -303,7 +307,14 @@ int main(void) printk("Scanning successfully started\n"); - k_sem_take(&sem_connected, K_FOREVER); + /* Wait for either remote info available or involuntary disconnect */ + k_poll(events, ARRAY_SIZE(events), K_FOREVER); + err = k_sem_take(&sem_connected, K_NO_WAIT); + if (err) { + printk("Disconnected before remote info available\n"); + + goto disconnected; + } err = bt_le_per_adv_set_info_transfer(pawr_adv, default_conn, 0); if (err) { @@ -373,11 +384,15 @@ disconnect: k_sleep(K_MSEC(per_adv_params.interval_max * 2)); err = bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); - if (err) { + if (err != 0 && err != -ENOTCONN) { return 0; } +disconnected: k_sem_take(&sem_disconnected, K_FOREVER); + + bt_conn_unref(default_conn); + default_conn = NULL; } printk("Maximum numnber of syncs onboarded\n");