1 /* Copyright (c) 2023 Nordic Semiconductor ASA
2  * SPDX-License-Identifier: Apache-2.0
3  */
4 
5 #include <stddef.h>
6 
7 #include <zephyr/bluetooth/conn.h>
8 #include <zephyr/sys/atomic_builtin.h>
9 
10 #include <testlib/conn.h>
11 
12 /**
13  * @file
14  * @brief Reified connection reference counting.
15  * @ingroup testlib conn ref
16  *
17  * This file provides functions to reify the moving and cloning of @ref
18  * bt_conn references for increased safety.
19  *
20  * Reifying means that the existence of a reference is always tied
21  * one-to-one with a non-NULL value in a owning pointer variable.
22  *
23  * The functions in this file will trigger an assert if they attempt to
24  * overwrite a non-NULL value in a owning pointer variable. This is to
25  * prevent leaking the reference that presumable is tied the value that
26  * would be overwritten.
27  *
28  * The functions in this file are intended to guard against undefined
29  * behavor due to NULL pointer dereferencing. They will assert on any
30  * relevant pointers.
31  */
32 
bt_testlib_conn_unref(struct bt_conn ** connp)33 void bt_testlib_conn_unref(struct bt_conn **connp)
34 {
35 	struct bt_conn *conn;
36 
37 	__ASSERT_NO_MSG(connp);
38 	conn = atomic_ptr_set((void **)connp, NULL);
39 	__ASSERT_NO_MSG(conn);
40 	bt_conn_unref(conn);
41 }
42 
43 struct find_by_index_data {
44 	uint8_t wanted_index;
45 	struct bt_conn *found_conn;
46 };
47 
find_by_index(struct bt_conn * conn,void * user_data)48 static void find_by_index(struct bt_conn *conn, void *user_data)
49 {
50 	struct find_by_index_data *data = user_data;
51 	uint8_t index = bt_conn_index(conn);
52 
53 	if (index == data->wanted_index) {
54 		data->found_conn = bt_conn_ref(conn);
55 	}
56 }
57 
bt_testlib_conn_unindex(enum bt_conn_type conn_type,uint8_t conn_index)58 struct bt_conn *bt_testlib_conn_unindex(enum bt_conn_type conn_type, uint8_t conn_index)
59 {
60 	struct find_by_index_data data = {
61 		.wanted_index = conn_index,
62 	};
63 
64 	bt_conn_foreach(conn_type, find_by_index, &data);
65 
66 	return data.found_conn;
67 }
68