Skip to content

Commit 52194a5

Browse files
committed
Bluetooth: CSIP: Fix ntf issue to clients on reboot
On reboot, client list to notify is not updated properly. Fix is to check and add the reconnected clients on security changed cb. Subscription check is added before notify to clients. BT Enable check is added in the register function before adding bonded devices to client list. Also typo is corrected in add_bonded_addr_to_client_list in the second loop. Signed-off-by: Nithin Ramesh Myliattil <[email protected]>
1 parent 7abda99 commit 52194a5

File tree

1 file changed

+83
-14
lines changed

1 file changed

+83
-14
lines changed

subsys/bluetooth/audio/csip_set_member.c

+83-14
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939

4040
#include "../host/conn_internal.h"
4141
#include "../host/keys.h"
42+
#include "../host/settings.h"
4243

4344
#include "common/bt_str.h"
4445
#include "audio_internal.h"
@@ -81,8 +82,23 @@ struct bt_csip_set_member_svc_inst {
8182
};
8283

8384
static struct bt_csip_set_member_svc_inst svc_insts[CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT];
85+
static struct k_mutex svc_inst_lock;
8486

8587
static void deferred_nfy_work_handler(struct k_work *work);
88+
static void add_bonded_addr_to_client_list(const struct bt_bond_info *info, void *data);
89+
90+
#if defined(CONFIG_BT_SETTINGS)
91+
static int csip_settings_commit(void)
92+
{
93+
bt_foreach_bond(BT_ID_DEFAULT, add_bonded_addr_to_client_list, NULL);
94+
95+
LOG_DBG("Restored CSIP client list from bonded devices");
96+
97+
return 0;
98+
}
99+
100+
BT_SETTINGS_DEFINE(csip_set_member, "csip", NULL, csip_settings_commit);
101+
#endif /* CONFIG_BT_SETTINGS */
86102

87103
static K_WORK_DELAYABLE_DEFINE(deferred_nfy_work, deferred_nfy_work_handler);
88104

@@ -460,28 +476,49 @@ static void set_lock_timer_handler(struct k_work *work)
460476
static void csip_security_changed(struct bt_conn *conn, bt_security_t level,
461477
enum bt_security_err err)
462478
{
479+
const bt_addr_le_t *peer_addr;
480+
463481
if (err != 0 || conn->encrypt == 0) {
464482
return;
465483
}
466484

485+
peer_addr = bt_conn_get_dst(conn);
486+
467487
if (!bt_le_bond_exists(conn->id, &conn->le.dst)) {
468488
return;
469489
}
470490

471491
for (size_t i = 0U; i < ARRAY_SIZE(svc_insts); i++) {
472492
struct bt_csip_set_member_svc_inst *svc_inst = &svc_insts[i];
493+
struct csip_client *client;
494+
bool found = false;
473495

496+
/* Check if client is already in the active list */
474497
for (size_t j = 0U; j < ARRAY_SIZE(svc_inst->clients); j++) {
475-
struct csip_client *client;
476-
477-
client = &svc_inst->clients[i];
498+
client = &svc_inst->clients[j];
478499

479-
if (atomic_test_bit(client->flags, FLAG_NOTIFY_LOCK) &&
480-
bt_addr_le_eq(bt_conn_get_dst(conn), &client->addr)) {
481-
notify_work_reschedule(K_NO_WAIT);
500+
if (atomic_test_bit(client->flags, FLAG_ACTIVE) &&
501+
bt_addr_le_eq(peer_addr, &client->addr)) {
502+
found = true;
482503
break;
483504
}
484505
}
506+
507+
/* If not found, add the bonded address to the client list */
508+
if (!found) {
509+
const struct bt_bond_info bond_info = {
510+
.addr = *peer_addr
511+
};
512+
513+
add_bonded_addr_to_client_list(&bond_info, NULL);
514+
return;
515+
}
516+
517+
/* Check if client is set with FLAG_NOTIFY_LOCK */
518+
if (atomic_test_bit(client->flags, FLAG_NOTIFY_LOCK)) {
519+
notify_work_reschedule(K_NO_WAIT);
520+
break;
521+
}
485522
}
486523
}
487524

@@ -736,19 +773,36 @@ static void notify(struct bt_csip_set_member_svc_inst *svc_inst, struct bt_conn
736773
const struct bt_uuid *uuid, const void *data, uint16_t len)
737774
{
738775
int err;
776+
const struct bt_gatt_attr *attr;
777+
778+
k_mutex_lock(&svc_inst_lock, K_FOREVER);
739779

740-
if (svc_inst->service_p == NULL) {
780+
attr = bt_gatt_find_by_uuid(
781+
svc_inst->service_p->attrs,
782+
svc_inst->service_p->attr_count,
783+
uuid);
784+
785+
if (!attr) {
786+
LOG_WRN("Attribute for UUID %p not found", uuid);
787+
k_mutex_unlock(&svc_inst_lock);
741788
return;
742789
}
743790

744-
err = bt_gatt_notify_uuid(conn, uuid, svc_inst->service_p->attrs, data, len);
791+
if (!bt_gatt_is_subscribed(conn, attr, BT_GATT_CCC_NOTIFY)) {
792+
LOG_DBG("Connection not subscribed to UUID %p", uuid);
793+
k_mutex_unlock(&svc_inst_lock);
794+
return;
795+
}
796+
797+
err = bt_gatt_notify(conn, attr, data, len);
745798
if (err) {
746799
if (err == -ENOTCONN) {
747800
LOG_DBG("Notification error: ENOTCONN (%d)", err);
748801
} else {
749802
LOG_ERR("Notification error: %d", err);
750803
}
751804
}
805+
k_mutex_unlock(&svc_inst_lock);
752806
}
753807

754808
static void notify_cb(struct bt_conn *conn, void *data)
@@ -769,7 +823,22 @@ static void notify_cb(struct bt_conn *conn, void *data)
769823

770824
for (size_t i = 0U; i < ARRAY_SIZE(svc_insts); i++) {
771825
struct bt_csip_set_member_svc_inst *svc_inst = &svc_insts[i];
772-
struct csip_client *client = &svc_inst->clients[bt_conn_index(conn)];
826+
827+
if (svc_inst->service_p == NULL || svc_inst->service_p->attrs == NULL) {
828+
return;
829+
}
830+
831+
struct csip_client *client;
832+
/* find the client object for the connection */
833+
for (size_t j = 0U; j < ARRAY_SIZE(svc_inst->clients); j++) {
834+
835+
client = &svc_inst->clients[j];
836+
837+
if (atomic_test_bit(client->flags, FLAG_ACTIVE) &&
838+
bt_addr_le_eq(bt_conn_get_dst(conn), &client->addr)) {
839+
break;
840+
}
841+
}
773842

774843
if (atomic_test_and_clear_bit(client->flags, FLAG_NOTIFY_LOCK)) {
775844
notify(svc_inst, conn, BT_UUID_CSIS_SET_LOCK, &svc_inst->set_lock,
@@ -801,7 +870,7 @@ static void add_bonded_addr_to_client_list(const struct bt_bond_info *info, void
801870
for (size_t i = 0U; i < ARRAY_SIZE(svc_insts); i++) {
802871
struct bt_csip_set_member_svc_inst *svc_inst = &svc_insts[i];
803872

804-
for (size_t j = 1U; j < ARRAY_SIZE(svc_inst->clients); i++) {
873+
for (size_t j = 0U; j < ARRAY_SIZE(svc_inst->clients); j++) {
805874
/* Check if device is registered, it not, add it */
806875
if (!atomic_test_bit(svc_inst->clients[j].flags, FLAG_ACTIVE)) {
807876
char addr_str[BT_ADDR_LE_STR_LEN];
@@ -841,17 +910,14 @@ int bt_csip_set_member_register(const struct bt_csip_set_member_register_param *
841910
return -EINVAL;
842911
}
843912

913+
k_mutex_init(&svc_inst_lock);
844914
inst = &svc_insts[instance_cnt];
845915
inst->service_p = &csip_set_member_service_list[instance_cnt];
846916
instance_cnt++;
847917

848918
if (!first_register) {
849919
bt_conn_cb_register(&conn_callbacks);
850920
bt_conn_auth_info_cb_register(&auth_callbacks);
851-
852-
/* Restore bonding list */
853-
bt_foreach_bond(BT_ID_DEFAULT, add_bonded_addr_to_client_list, NULL);
854-
855921
first_register = true;
856922
}
857923

@@ -912,6 +978,8 @@ int bt_csip_set_member_unregister(struct bt_csip_set_member_svc_inst *svc_inst)
912978
return -EINVAL;
913979
}
914980

981+
k_mutex_lock(&svc_inst_lock, K_FOREVER);
982+
915983
err = bt_gatt_service_unregister(svc_inst->service_p);
916984
if (err != 0) {
917985
LOG_DBG("CSIS service unregister failed: %d", err);
@@ -921,6 +989,7 @@ int bt_csip_set_member_unregister(struct bt_csip_set_member_svc_inst *svc_inst)
921989
(void)k_work_cancel_delayable(&svc_inst->set_lock_timer);
922990
memset(svc_inst, 0, sizeof(*svc_inst));
923991

992+
k_mutex_unlock(&svc_inst_lock);
924993
return 0;
925994
}
926995

0 commit comments

Comments
 (0)