Skip to content

Commit

Permalink
Bluetooth: Host: add unregister connection callback function
Browse files Browse the repository at this point in the history
[Description]
tests: shell: Restart bt will register the same connection callback twice.
Callback next node point to itself, when link established callback function
loop infinitely.
[Fix]
Unregister the previous callback to avoid register repeatedly.
[Test]
After bt init/disable times, create connection successfully.

Signed-off-by: huajiang zheng <[email protected]>
  • Loading branch information
huajiang zheng authored and Huajiang Zheng committed Jan 31, 2024
1 parent 69787da commit e857483
Show file tree
Hide file tree
Showing 10 changed files with 421 additions and 0 deletions.
13 changes: 13 additions & 0 deletions include/zephyr/bluetooth/conn.h
Original file line number Diff line number Diff line change
Expand Up @@ -1151,6 +1151,19 @@ struct bt_conn_cb {
*/
void bt_conn_cb_register(struct bt_conn_cb *cb);

/**
* @brief Unregister connection callbacks.
*
* Unregister the state of connections callbacks.
*
* @param cb Callback struct point to memory that remains valid.
*
* @retval 0 Success
* @retval -EINVAL If @p cb is NULL
* @retval -ENOENT if @p cb was not registered
*/
int bt_conn_cb_unregister(struct bt_conn_cb *cb);

/**
* @brief Register a callback structure for connection events.
*
Expand Down
27 changes: 27 additions & 0 deletions subsys/bluetooth/host/conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -2339,6 +2339,33 @@ void bt_conn_cb_register(struct bt_conn_cb *cb)
callback_list = cb;
}

int bt_conn_cb_unregister(struct bt_conn_cb *cb)
{
struct bt_conn_cb *previous_callback;

CHECKIF(cb == NULL) {
return -EINVAL;
}

if (callback_list == cb) {
callback_list = callback_list->_next;
return 0;
}

previous_callback = callback_list;

while (previous_callback->_next) {
if (previous_callback->_next == cb) {
previous_callback->_next = previous_callback->_next->_next;
return 0;
}

previous_callback = previous_callback->_next;
}

return -ENOENT;
}

bool bt_conn_exists_le(uint8_t id, const bt_addr_le_t *peer)
{
struct bt_conn *conn = bt_conn_lookup_addr_le(id, peer);
Expand Down
2 changes: 2 additions & 0 deletions subsys/bluetooth/shell/bt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1061,6 +1061,8 @@ static void bt_ready(int err)
#if defined(CONFIG_BT_CONN)
default_conn = NULL;

/* Unregister to avoid register repeatedly */
bt_conn_cb_unregister(&conn_callbacks);
bt_conn_cb_register(&conn_callbacks);
#endif /* CONFIG_BT_CONN */

Expand Down
14 changes: 14 additions & 0 deletions tests/bsim/bluetooth/host/misc/unregister_conn_cb/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(bsim_test_unregister_conn_cb)

FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources} )

zephyr_include_directories(
${BSIM_COMPONENTS_PATH}/libUtilv1/src/
${BSIM_COMPONENTS_PATH}/libPhyComv1/src/
)
4 changes: 4 additions & 0 deletions tests/bsim/bluetooth/host/misc/unregister_conn_cb/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
CONFIG_BT=y
CONFIG_BT_DEVICE_NAME="conn tester"
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_CENTRAL=y
20 changes: 20 additions & 0 deletions tests/bsim/bluetooth/host/misc/unregister_conn_cb/src/common.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#include "common.h"

void test_tick(bs_time_t HW_device_time)
{
if (bst_result != Passed) {
FAIL("test failed (not passed after %i seconds)\n", WAIT_TIME);
}
}

void test_init(void)
{
bst_ticker_set_next_tick_absolute(WAIT_TIME);
bst_result = In_progress;
}
55 changes: 55 additions & 0 deletions tests/bsim/bluetooth/host/misc/unregister_conn_cb/src/common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* Common functions and helpers for unregister connection callback tests
*
* Copyright (c) 2024 NXP
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/kernel.h>

#include "bs_types.h"
#include "bs_tracing.h"
#include "time_machine.h"
#include "bstests.h"

#include <zephyr/types.h>
#include <stddef.h>
#include <errno.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/conn.h>

extern enum bst_result_t bst_result;

#define WAIT_SECONDS (30) /*seconds*/
#define WAIT_TIME (WAIT_SECONDS * USEC_PER_SEC) /* microseconds*/

#define CREATE_FLAG(flag) static atomic_t flag = (atomic_t) false
#define SET_FLAG(flag) (void)atomic_set(&flag, (atomic_t) true)
#define UNSET_FLAG(flag) (void)atomic_set(&flag, (atomic_t) false)
#define WAIT_FOR_FLAG(flag) \
while (!(bool)atomic_get(&flag)) { \
(void)k_sleep(K_MSEC(1)); \
}
#define WAIT_FOR_FLAG_UNSET(flag) \
while ((bool)atomic_get(&flag)) { \
(void)k_sleep(K_MSEC(1)); \
}

#define FAIL(...) \
do { \
bst_result = Failed; \
bs_trace_error_time_line(__VA_ARGS__); \
} while (0)

#define PASS(...) \
do { \
bst_result = Passed; \
bs_trace_info_time(1, __VA_ARGS__); \
} while (0)

void test_tick(bs_time_t HW_device_time);
void test_init(void);
Loading

0 comments on commit e857483

Please sign in to comment.