Bluetooth: Audio: Use svc_inst instead of bt_csip for set_member

Use the service instance struct instead of the more generic
`bt_csip` for the CSIP set member API.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
Emil Gydesen 2022-10-13 11:46:26 +02:00 committed by Carles Cufí
commit 292db21a18
13 changed files with 246 additions and 235 deletions

View file

@ -39,14 +39,15 @@ extern "C" {
* @kconfig{BT_CAP_ACCEPTOR_SET_MEMBER}. If @kconfig{BT_CAP_ACCEPTOR_SET_MEMBER} * @kconfig{BT_CAP_ACCEPTOR_SET_MEMBER}. If @kconfig{BT_CAP_ACCEPTOR_SET_MEMBER}
* is not enabled, the Common Audio Service will by statically registered. * is not enabled, the Common Audio Service will by statically registered.
* *
* @param[in] param Coordinated Set Identification Service register parameters. * @param[in] param Coordinated Set Identification Service register
* @param[out] csip Pointer to the registered Coordinated Set Identification * parameters.
* Service. * @param[out] svc_inst Pointer to the registered Coordinated Set
* Identification Service.
* *
* @return 0 if success, errno on failure. * @return 0 if success, errno on failure.
*/ */
int bt_cap_acceptor_register(const struct bt_csip_set_member_register_param *param, int bt_cap_acceptor_register(const struct bt_csip_set_member_register_param *param,
struct bt_csip **csip); struct bt_csip_set_member_svc_inst **svc_inst);
/** Callback structure for CAP procedures */ /** Callback structure for CAP procedures */
struct bt_cap_initiator_cb { struct bt_cap_initiator_cb {

View file

@ -73,21 +73,23 @@ extern "C" {
#define BT_CSIP_DATA_RSI(_rsi) BT_DATA(BT_DATA_CSIS_RSI, _rsi, BT_CSIP_RSI_SIZE) #define BT_CSIP_DATA_RSI(_rsi) BT_DATA(BT_DATA_CSIS_RSI, _rsi, BT_CSIP_RSI_SIZE)
/** @brief Opaque Coordinated Set Identification Service instance. */ /** @brief Opaque Coordinated Set Identification Service instance. */
struct bt_csip; struct bt_csip_set_member_svc_inst;
/** Callback structure for the Coordinated Set Identification Service */ /** Callback structure for the Coordinated Set Identification Service */
struct bt_csip_set_member_cb { struct bt_csip_set_member_cb {
/** /**
* @brief Callback whenever the lock changes on the server. * @brief Callback whenever the lock changes on the server.
* *
* @param conn The connection to the client that changed the lock. * @param conn The connection to the client that changed the lock.
* NULL if server changed it, either by calling * NULL if server changed it, either by calling
* bt_csip_set_member_lock() or by timeout. * bt_csip_set_member_lock() or by timeout.
* @param csip Pointer to the Coordinated Set Identification Service. * @param svc_inst Pointer to the Coordinated Set Identification
* @param locked Whether the lock was locked or released. * Service.
* @param locked Whether the lock was locked or released.
* *
*/ */
void (*lock_changed)(struct bt_conn *conn, struct bt_csip *csip, void (*lock_changed)(struct bt_conn *conn,
struct bt_csip_set_member_svc_inst *svc_inst,
bool locked); bool locked);
/** /**
@ -96,13 +98,15 @@ struct bt_csip_set_member_cb {
* If this callback is not set, all clients will be allowed to read * If this callback is not set, all clients will be allowed to read
* the SIRK unencrypted. * the SIRK unencrypted.
* *
* @param conn The connection to the client that requested to read the * @param conn The connection to the client that requested to read
* SIRK. * the SIRK.
* @param csip Pointer to the Coordinated Set Identification Service. * @param svc_inst Pointer to the Coordinated Set Identification
* Service.
* *
* @return A BT_CSIP_READ_SIRK_REQ_RSP_* response code. * @return A BT_CSIP_READ_SIRK_REQ_RSP_* response code.
*/ */
uint8_t (*sirk_read_req)(struct bt_conn *conn, struct bt_csip *csip); uint8_t (*sirk_read_req)(struct bt_conn *conn,
struct bt_csip_set_member_svc_inst *svc_inst);
}; };
/** Register structure for Coordinated Set Identification Service */ /** Register structure for Coordinated Set Identification Service */
@ -160,11 +164,11 @@ struct bt_csip_set_member_register_param {
* *
* The first service attribute can be included in any other GATT service. * The first service attribute can be included in any other GATT service.
* *
* @param csip Pointer to the Coordinated Set Identification Service. * @param svc_inst Pointer to the Coordinated Set Identification Service.
* *
* @return The first CSIS attribute instance. * @return The first CSIS attribute instance.
*/ */
void *bt_csip_set_member_svc_decl_get(const struct bt_csip *csip); void *bt_csip_set_member_svc_decl_get(const struct bt_csip_set_member_svc_inst *svc_inst);
/** /**
* @brief Register a Coordinated Set Identification Service instance. * @brief Register a Coordinated Set Identification Service instance.
@ -174,47 +178,49 @@ void *bt_csip_set_member_svc_decl_get(const struct bt_csip *csip);
* *
* This shall only be done as a server. * This shall only be done as a server.
* *
* @param param Coordinated Set Identification Service register parameters. * @param param Coordinated Set Identification Service register
* @param[out] csip Pointer to the registered Coordinated Set Identification * parameters.
* Service. * @param[out] svc_inst Pointer to the registered Coordinated Set
* Identification Service.
* *
* @return 0 if success, errno on failure. * @return 0 if success, errno on failure.
*/ */
int bt_csip_set_member_register(const struct bt_csip_set_member_register_param *param, int bt_csip_set_member_register(const struct bt_csip_set_member_register_param *param,
struct bt_csip **csip); struct bt_csip_set_member_svc_inst **svc_inst);
/** /**
* @brief Print the SIRK to the debug output * @brief Print the SIRK to the debug output
* *
* @param csip Pointer to the Coordinated Set Identification Service. * @param svc_inst Pointer to the Coordinated Set Identification Service.
*/ */
void bt_csip_set_member_print_sirk(const struct bt_csip *csip); void bt_csip_set_member_print_sirk(const struct bt_csip_set_member_svc_inst *svc_inst);
/** /**
* @brief Generate the Resolvable Set Identifier (RSI) value. * @brief Generate the Resolvable Set Identifier (RSI) value.
* *
* This will generate RSI for given @p csip instance. * This will generate RSI for given @p svc_inst instance.
* *
* @param csip Pointer to the Coordinated Set Identification Service. * @param svc_inst Pointer to the Coordinated Set Identification Service.
* @param rsi Pointer to the 6-octet newly generated RSI data. * @param rsi Pointer to the 6-octet newly generated RSI data.
* *
* @return int 0 if on success, errno on error. * @return int 0 if on success, errno on error.
*/ */
int bt_csip_set_member_generate_rsi(const struct bt_csip *csip, int bt_csip_set_member_generate_rsi(const struct bt_csip_set_member_svc_inst *svc_inst,
uint8_t rsi[BT_CSIP_RSI_SIZE]); uint8_t rsi[BT_CSIP_RSI_SIZE]);
/** /**
* @brief Locks a specific Coordinated Set Identification Service instance on the server. * @brief Locks a specific Coordinated Set Identification Service instance on the server.
* *
* @param csip Pointer to the Coordinated Set Identification Service. * @param svc_inst Pointer to the Coordinated Set Identification Service.
* @param lock If true lock the set, if false release the set. * @param lock If true lock the set, if false release the set.
* @param force This argument only have meaning when @p lock is false * @param force This argument only have meaning when @p lock is false
* (release) and will force release the lock, regardless of who * (release) and will force release the lock, regardless of who
* took the lock. * took the lock.
* *
* @return 0 on success, GATT error on error. * @return 0 on success, GATT error on error.
*/ */
int bt_csip_set_member_lock(struct bt_csip *csip, bool lock, bool force); int bt_csip_set_member_lock(struct bt_csip_set_member_svc_inst *svc_inst,
bool lock, bool force);
/** Information about a specific set */ /** Information about a specific set */
struct bt_csip_set_coordinator_set_info { struct bt_csip_set_coordinator_set_info {

View file

@ -15,14 +15,17 @@
#define CSIP_SIRK_DEBUG { 0xcd, 0xcc, 0x72, 0xdd, 0x86, 0x8c, 0xcd, 0xce, \ #define CSIP_SIRK_DEBUG { 0xcd, 0xcc, 0x72, 0xdd, 0x86, 0x8c, 0xcd, 0xce, \
0x22, 0xfd, 0xa1, 0x21, 0x09, 0x7d, 0x7d, 0x45 } 0x22, 0xfd, 0xa1, 0x21, 0x09, 0x7d, 0x7d, 0x45 }
static struct bt_csip *csip; static struct bt_csip_set_member_svc_inst *svc_inst;
static void csip_lock_changed_cb(struct bt_conn *conn, struct bt_csip *csip, bool locked) static void csip_lock_changed_cb(struct bt_conn *conn,
struct bt_csip_set_member_svc_inst *svc_inst,
bool locked)
{ {
printk("Client %p %s the lock\n", conn, locked ? "locked" : "released"); printk("Client %p %s the lock\n", conn, locked ? "locked" : "released");
} }
static uint8_t sirk_read_req_cb(struct bt_conn *conn, struct bt_csip *csip) static uint8_t sirk_read_req_cb(struct bt_conn *conn,
struct bt_csip_set_member_svc_inst *svc_inst)
{ {
return BT_CSIP_READ_SIRK_REQ_RSP_ACCEPT; return BT_CSIP_READ_SIRK_REQ_RSP_ACCEPT;
} }
@ -42,18 +45,18 @@ int csip_set_member_init(void)
.cb = &csip_cb, .cb = &csip_cb,
}; };
return bt_cap_acceptor_register(&param, &csip); return bt_cap_acceptor_register(&param, &svc_inst);
} }
int csip_generate_rsi(uint8_t *rsi) int csip_generate_rsi(uint8_t *rsi)
{ {
int err; int err;
if (csip == NULL) { if (svc_inst == NULL) {
return -ENODEV; return -ENODEV;
} }
err = bt_csip_set_member_generate_rsi(csip, rsi); err = bt_csip_set_member_generate_rsi(svc_inst, rsi);
if (err) { if (err) {
printk("Failed to generate RSI (err %d)\n", err); printk("Failed to generate RSI (err %d)\n", err);
return err; return err;

View file

@ -22,12 +22,12 @@ static struct bt_gatt_attr svc_attrs[] = {
}; };
int bt_cap_acceptor_register(const struct bt_csip_set_member_register_param *param, int bt_cap_acceptor_register(const struct bt_csip_set_member_register_param *param,
struct bt_csip **csip) struct bt_csip_set_member_svc_inst **svc_inst)
{ {
static struct bt_gatt_service cas; static struct bt_gatt_service cas;
int err; int err;
err = bt_csip_set_member_register(param, csip); err = bt_csip_set_member_register(param, svc_inst);
if (err != 0) { if (err != 0) {
BT_DBG("Failed to register CSIP"); BT_DBG("Failed to register CSIP");
return err; return err;
@ -36,7 +36,7 @@ int bt_cap_acceptor_register(const struct bt_csip_set_member_register_param *par
cas = (struct bt_gatt_service)BT_GATT_SERVICE(svc_attrs); cas = (struct bt_gatt_service)BT_GATT_SERVICE(svc_attrs);
/* Overwrite the include definition with the CSIP */ /* Overwrite the include definition with the CSIP */
cas.attrs[1].user_data = bt_csip_set_member_svc_decl_get(*csip); cas.attrs[1].user_data = bt_csip_set_member_svc_decl_get(*svc_inst);
err = bt_gatt_service_register(&cas); err = bt_gatt_service_register(&cas);
if (err) { if (err) {

View file

@ -35,30 +35,5 @@ struct bt_csip_set_sirk {
uint8_t value[BT_CSIP_SET_SIRK_SIZE]; uint8_t value[BT_CSIP_SET_SIRK_SIZE];
} __packed; } __packed;
/* TODO: Rename to bt_csip_svc_inst */
struct bt_csip_set_member_server {
struct bt_csip_set_sirk set_sirk;
uint8_t set_size;
uint8_t set_lock;
uint8_t rank;
struct bt_csip_set_member_cb *cb;
struct k_work_delayable set_lock_timer;
bt_addr_le_t lock_client_addr;
struct bt_gatt_service *service_p;
struct csip_pending_notifications pend_notify[CONFIG_BT_MAX_PAIRED];
#if IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
uint32_t age_counter;
#endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
};
struct bt_csip {
bool client_instance;
union {
#if defined(CONFIG_BT_CSIP_SET_MEMBER)
struct bt_csip_set_member_server srv;
#endif /* CONFIG_BT_CSIP_SET_MEMBER */
};
};
struct bt_csip_set_coordinator_csis_inst *bt_csip_set_coordinator_csis_inst_by_handle( struct bt_csip_set_coordinator_csis_inst *bt_csip_set_coordinator_csis_inst_by_handle(
struct bt_conn *conn, uint16_t start_handle); struct bt_conn *conn, uint16_t start_handle);

View file

@ -555,27 +555,27 @@ static int csip_set_coordinator_write_set_lock(struct bt_csip_set_coordinator_sv
return bt_gatt_write(inst->conn, &write_params); return bt_gatt_write(inst->conn, &write_params);
} }
static int read_set_sirk(struct bt_csip_set_coordinator_svc_inst *csip) static int read_set_sirk(struct bt_csip_set_coordinator_svc_inst *svc_inst)
{ {
if (cur_inst != NULL) { if (cur_inst != NULL) {
if (cur_inst != csip) { if (cur_inst != svc_inst) {
return -EBUSY; return -EBUSY;
} }
} else { } else {
cur_inst = csip; cur_inst = svc_inst;
} }
if (csip->set_sirk_handle == 0) { if (svc_inst->set_sirk_handle == 0) {
BT_DBG("Handle not set"); BT_DBG("Handle not set");
return -EINVAL; return -EINVAL;
} }
read_params.func = csip_set_coordinator_discover_insts_read_set_sirk_cb; read_params.func = csip_set_coordinator_discover_insts_read_set_sirk_cb;
read_params.handle_count = 1; read_params.handle_count = 1;
read_params.single.handle = csip->set_sirk_handle; read_params.single.handle = svc_inst->set_sirk_handle;
read_params.single.offset = 0U; read_params.single.offset = 0U;
return bt_gatt_read(csip->conn, &read_params); return bt_gatt_read(svc_inst->conn, &read_params);
} }
static int csip_set_coordinator_read_set_size(struct bt_conn *conn, static int csip_set_coordinator_read_set_size(struct bt_conn *conn,

View file

@ -32,55 +32,71 @@
#define BT_CSIP_SIH_HASH_SIZE 3 #define BT_CSIP_SIH_HASH_SIZE 3
#define CSIP_SET_LOCK_TIMER_VALUE K_SECONDS(60) #define CSIP_SET_LOCK_TIMER_VALUE K_SECONDS(60)
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_CSIP) #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_CSIP_SET_MEMBER)
#define LOG_MODULE_NAME bt_csip #define LOG_MODULE_NAME bt_csip_set_member
#include "common/log.h" #include "common/log.h"
#include "common/bt_str.h" #include "common/bt_str.h"
static struct bt_csip csip_insts[CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT]; struct bt_csip_set_member_svc_inst {
struct bt_csip_set_sirk set_sirk;
uint8_t set_size;
uint8_t set_lock;
uint8_t rank;
struct bt_csip_set_member_cb *cb;
struct k_work_delayable set_lock_timer;
bt_addr_le_t lock_client_addr;
struct bt_gatt_service *service_p;
struct csip_pending_notifications pend_notify[CONFIG_BT_MAX_PAIRED];
#if IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
uint32_t age_counter;
#endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
};
static struct bt_csip_set_member_svc_inst svc_insts[CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT];
static bt_addr_le_t server_dummy_addr; /* 0'ed address */ static bt_addr_le_t server_dummy_addr; /* 0'ed address */
struct csip_notify_foreach { struct csip_notify_foreach {
struct bt_conn *excluded_client; struct bt_conn *excluded_client;
struct bt_csip *csip; struct bt_csip_set_member_svc_inst *svc_inst;
}; };
static bool is_last_client_to_write(const struct bt_csip *csip, static bool is_last_client_to_write(const struct bt_csip_set_member_svc_inst *svc_inst,
const struct bt_conn *conn) const struct bt_conn *conn)
{ {
if (conn != NULL) { if (conn != NULL) {
return bt_addr_le_eq(bt_conn_get_dst(conn), return bt_addr_le_eq(bt_conn_get_dst(conn),
&csip->srv.lock_client_addr); &svc_inst->lock_client_addr);
} else { } else {
return bt_addr_le_eq(&server_dummy_addr, return bt_addr_le_eq(&server_dummy_addr,
&csip->srv.lock_client_addr); &svc_inst->lock_client_addr);
} }
} }
static void notify_lock_value(const struct bt_csip *csip, struct bt_conn *conn) static void notify_lock_value(const struct bt_csip_set_member_svc_inst *svc_inst,
struct bt_conn *conn)
{ {
bt_gatt_notify_uuid(conn, BT_UUID_CSIS_SET_LOCK, bt_gatt_notify_uuid(conn, BT_UUID_CSIS_SET_LOCK,
csip->srv.service_p->attrs, svc_inst->service_p->attrs,
&csip->srv.set_lock, &svc_inst->set_lock,
sizeof(csip->srv.set_lock)); sizeof(svc_inst->set_lock));
} }
static void notify_client(struct bt_conn *conn, void *data) static void notify_client(struct bt_conn *conn, void *data)
{ {
struct csip_notify_foreach *csip_data = (struct csip_notify_foreach *)data; struct csip_notify_foreach *csip_data = (struct csip_notify_foreach *)data;
struct bt_csip *csip = csip_data->csip; struct bt_csip_set_member_svc_inst *svc_inst = csip_data->svc_inst;
struct bt_conn *excluded_conn = csip_data->excluded_client; struct bt_conn *excluded_conn = csip_data->excluded_client;
if (excluded_conn != NULL && conn == excluded_conn) { if (excluded_conn != NULL && conn == excluded_conn) {
return; return;
} }
notify_lock_value(csip, conn); notify_lock_value(svc_inst, conn);
for (int i = 0; i < ARRAY_SIZE(csip->srv.pend_notify); i++) { for (int i = 0; i < ARRAY_SIZE(svc_inst->pend_notify); i++) {
struct csip_pending_notifications *pend_notify; struct csip_pending_notifications *pend_notify;
pend_notify = &csip->srv.pend_notify[i]; pend_notify = &svc_inst->pend_notify[i];
if (pend_notify->pending && if (pend_notify->pending &&
bt_addr_le_eq(bt_conn_get_dst(conn), &pend_notify->addr)) { bt_addr_le_eq(bt_conn_get_dst(conn), &pend_notify->addr)) {
@ -90,21 +106,21 @@ static void notify_client(struct bt_conn *conn, void *data)
} }
} }
static void notify_clients(struct bt_csip *csip, static void notify_clients(struct bt_csip_set_member_svc_inst *svc_inst,
struct bt_conn *excluded_client) struct bt_conn *excluded_client)
{ {
struct csip_notify_foreach data = { struct csip_notify_foreach data = {
.excluded_client = excluded_client, .excluded_client = excluded_client,
.csip = csip, .svc_inst = svc_inst,
}; };
/* Mark all bonded devices as pending notifications, and clear those /* Mark all bonded devices as pending notifications, and clear those
* that are notified in `notify_client` * that are notified in `notify_client`
*/ */
for (int i = 0; i < ARRAY_SIZE(csip->srv.pend_notify); i++) { for (int i = 0; i < ARRAY_SIZE(svc_inst->pend_notify); i++) {
struct csip_pending_notifications *pend_notify; struct csip_pending_notifications *pend_notify;
pend_notify = &csip->srv.pend_notify[i]; pend_notify = &svc_inst->pend_notify[i];
if (pend_notify->active) { if (pend_notify->active) {
if (excluded_client != NULL && if (excluded_client != NULL &&
@ -181,7 +197,7 @@ static int generate_prand(uint32_t *dest)
return 0; return 0;
} }
int bt_csip_set_member_generate_rsi(const struct bt_csip *csip, int bt_csip_set_member_generate_rsi(const struct bt_csip_set_member_svc_inst *svc_inst,
uint8_t rsi[BT_CSIP_RSI_SIZE]) uint8_t rsi[BT_CSIP_RSI_SIZE])
{ {
int res = 0; int res = 0;
@ -200,7 +216,7 @@ int bt_csip_set_member_generate_rsi(const struct bt_csip *csip,
} }
} }
res = bt_csip_sih(csip->srv.set_sirk.value, prand, &hash); res = bt_csip_sih(svc_inst->set_sirk.value, prand, &hash);
if (res != 0) { if (res != 0) {
BT_WARN("Could not generate new RSI"); BT_WARN("Could not generate new RSI");
return res; return res;
@ -218,21 +234,21 @@ static ssize_t read_set_sirk(struct bt_conn *conn,
{ {
struct bt_csip_set_sirk enc_sirk; struct bt_csip_set_sirk enc_sirk;
struct bt_csip_set_sirk *sirk; struct bt_csip_set_sirk *sirk;
struct bt_csip *csip = BT_AUDIO_CHRC_USER_DATA(attr); struct bt_csip_set_member_svc_inst *svc_inst = BT_AUDIO_CHRC_USER_DATA(attr);
if (csip->srv.cb != NULL && csip->srv.cb->sirk_read_req != NULL) { if (svc_inst->cb != NULL && svc_inst->cb->sirk_read_req != NULL) {
uint8_t cb_rsp; uint8_t cb_rsp;
/* Ask higher layer for what SIRK to return, if any */ /* Ask higher layer for what SIRK to return, if any */
cb_rsp = csip->srv.cb->sirk_read_req(conn, &csip_insts[0]); cb_rsp = svc_inst->cb->sirk_read_req(conn, &svc_insts[0]);
if (cb_rsp == BT_CSIP_READ_SIRK_REQ_RSP_ACCEPT) { if (cb_rsp == BT_CSIP_READ_SIRK_REQ_RSP_ACCEPT) {
sirk = &csip->srv.set_sirk; sirk = &svc_inst->set_sirk;
} else if (IS_ENABLED(CONFIG_BT_CSIP_SET_MEMBER_ENC_SIRK_SUPPORT) && } else if (IS_ENABLED(CONFIG_BT_CSIP_SET_MEMBER_ENC_SIRK_SUPPORT) &&
cb_rsp == BT_CSIP_READ_SIRK_REQ_RSP_ACCEPT_ENC) { cb_rsp == BT_CSIP_READ_SIRK_REQ_RSP_ACCEPT_ENC) {
int err; int err;
err = sirk_encrypt(conn, &csip->srv.set_sirk, err = sirk_encrypt(conn, &svc_inst->set_sirk,
&enc_sirk); &enc_sirk);
if (err != 0) { if (err != 0) {
BT_ERR("Could not encrypt SIRK: %d", BT_ERR("Could not encrypt SIRK: %d",
@ -252,14 +268,14 @@ static ssize_t read_set_sirk(struct bt_conn *conn,
return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY); return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY);
} }
} else { } else {
sirk = &csip->srv.set_sirk; sirk = &svc_inst->set_sirk;
} }
BT_DBG("Set sirk %sencrypted", BT_DBG("Set sirk %sencrypted",
sirk->type == BT_CSIP_SIRK_TYPE_PLAIN ? "not " : ""); sirk->type == BT_CSIP_SIRK_TYPE_PLAIN ? "not " : "");
LOG_HEXDUMP_DBG(csip->srv.set_sirk.value, LOG_HEXDUMP_DBG(svc_inst->set_sirk.value,
sizeof(csip->srv.set_sirk.value), "Set SIRK"); sizeof(svc_inst->set_sirk.value), "Set SIRK");
return bt_gatt_attr_read(conn, attr, buf, len, offset, return bt_gatt_attr_read(conn, attr, buf, len, offset,
sirk, sizeof(*sirk)); sirk, sizeof(*sirk));
} }
@ -274,13 +290,13 @@ static ssize_t read_set_size(struct bt_conn *conn,
const struct bt_gatt_attr *attr, const struct bt_gatt_attr *attr,
void *buf, uint16_t len, uint16_t offset) void *buf, uint16_t len, uint16_t offset)
{ {
struct bt_csip *csip = BT_AUDIO_CHRC_USER_DATA(attr); struct bt_csip_set_member_svc_inst *svc_inst = BT_AUDIO_CHRC_USER_DATA(attr);
BT_DBG("%u", csip->srv.set_size); BT_DBG("%u", svc_inst->set_size);
return bt_gatt_attr_read(conn, attr, buf, len, offset, return bt_gatt_attr_read(conn, attr, buf, len, offset,
&csip->srv.set_size, &svc_inst->set_size,
sizeof(csip->srv.set_size)); sizeof(svc_inst->set_size));
} }
static void set_size_cfg_changed(const struct bt_gatt_attr *attr, static void set_size_cfg_changed(const struct bt_gatt_attr *attr,
@ -293,26 +309,28 @@ static ssize_t read_set_lock(struct bt_conn *conn,
const struct bt_gatt_attr *attr, const struct bt_gatt_attr *attr,
void *buf, uint16_t len, uint16_t offset) void *buf, uint16_t len, uint16_t offset)
{ {
struct bt_csip *csip = BT_AUDIO_CHRC_USER_DATA(attr); struct bt_csip_set_member_svc_inst *svc_inst = BT_AUDIO_CHRC_USER_DATA(attr);
BT_DBG("%u", csip->srv.set_lock); BT_DBG("%u", svc_inst->set_lock);
return bt_gatt_attr_read(conn, attr, buf, len, offset, return bt_gatt_attr_read(conn, attr, buf, len, offset,
&csip->srv.set_lock, &svc_inst->set_lock,
sizeof(csip->srv.set_lock)); sizeof(svc_inst->set_lock));
} }
/** /**
* @brief Set the lock value of a CSIP instance. * @brief Set the lock value of a CSIP instance.
* *
* @param conn The connection locking the instance. * @param conn The connection locking the instance.
* Will be NULL if the server locally sets the lock. * Will be NULL if the server locally sets the lock.
* @param csip The CSIP instance to change the lock value of * @param svc_inst The CSIP instance to change the lock value of
* @param val The lock value (BT_CSIP_LOCK_VALUE or BT_CSIP_RELEASE_VALUE) * @param val The lock value (BT_CSIP_LOCK_VALUE or BT_CSIP_RELEASE_VALUE)
* *
* @return BT_CSIP_ERROR_* on failure or 0 if success * @return BT_CSIP_ERROR_* on failure or 0 if success
*/ */
static uint8_t set_lock(struct bt_conn *conn, struct bt_csip *csip, uint8_t val) static uint8_t set_lock(struct bt_conn *conn,
struct bt_csip_set_member_svc_inst *svc_inst,
uint8_t val)
{ {
bool notify; bool notify;
@ -320,35 +338,35 @@ static uint8_t set_lock(struct bt_conn *conn, struct bt_csip *csip, uint8_t val)
return BT_CSIP_ERROR_LOCK_INVAL_VALUE; return BT_CSIP_ERROR_LOCK_INVAL_VALUE;
} }
if (csip->srv.set_lock == BT_CSIP_LOCK_VALUE) { if (svc_inst->set_lock == BT_CSIP_LOCK_VALUE) {
if (val == BT_CSIP_LOCK_VALUE) { if (val == BT_CSIP_LOCK_VALUE) {
if (is_last_client_to_write(csip, conn)) { if (is_last_client_to_write(svc_inst, conn)) {
return BT_CSIP_ERROR_LOCK_ALREADY_GRANTED; return BT_CSIP_ERROR_LOCK_ALREADY_GRANTED;
} else { } else {
return BT_CSIP_ERROR_LOCK_DENIED; return BT_CSIP_ERROR_LOCK_DENIED;
} }
} else if (!is_last_client_to_write(csip, conn)) { } else if (!is_last_client_to_write(svc_inst, conn)) {
return BT_CSIP_ERROR_LOCK_RELEASE_DENIED; return BT_CSIP_ERROR_LOCK_RELEASE_DENIED;
} }
} }
notify = csip->srv.set_lock != val; notify = svc_inst->set_lock != val;
csip->srv.set_lock = val; svc_inst->set_lock = val;
if (csip->srv.set_lock == BT_CSIP_LOCK_VALUE) { if (svc_inst->set_lock == BT_CSIP_LOCK_VALUE) {
if (conn != NULL) { if (conn != NULL) {
bt_addr_le_copy(&csip->srv.lock_client_addr, bt_addr_le_copy(&svc_inst->lock_client_addr,
bt_conn_get_dst(conn)); bt_conn_get_dst(conn));
} }
(void)k_work_reschedule(&csip->srv.set_lock_timer, (void)k_work_reschedule(&svc_inst->set_lock_timer,
CSIP_SET_LOCK_TIMER_VALUE); CSIP_SET_LOCK_TIMER_VALUE);
} else { } else {
(void)memset(&csip->srv.lock_client_addr, 0, (void)memset(&svc_inst->lock_client_addr, 0,
sizeof(csip->srv.lock_client_addr)); sizeof(svc_inst->lock_client_addr));
(void)k_work_cancel_delayable(&csip->srv.set_lock_timer); (void)k_work_cancel_delayable(&svc_inst->set_lock_timer);
} }
BT_DBG("%u", csip->srv.set_lock); BT_DBG("%u", svc_inst->set_lock);
if (notify) { if (notify) {
/* /*
@ -356,12 +374,12 @@ static uint8_t set_lock(struct bt_conn *conn, struct bt_csip *csip, uint8_t val)
* client writing the value, shall be notified * client writing the value, shall be notified
* (if subscribed) * (if subscribed)
*/ */
notify_clients(csip, conn); notify_clients(svc_inst, conn);
if (csip->srv.cb != NULL && csip->srv.cb->lock_changed != NULL) { if (svc_inst->cb != NULL && svc_inst->cb->lock_changed != NULL) {
bool locked = csip->srv.set_lock == BT_CSIP_LOCK_VALUE; bool locked = svc_inst->set_lock == BT_CSIP_LOCK_VALUE;
csip->srv.cb->lock_changed(conn, csip, locked); svc_inst->cb->lock_changed(conn, svc_inst, locked);
} }
} }
@ -375,7 +393,7 @@ static ssize_t write_set_lock(struct bt_conn *conn,
{ {
ssize_t res; ssize_t res;
uint8_t val; uint8_t val;
struct bt_csip *csip = BT_AUDIO_CHRC_USER_DATA(attr); struct bt_csip_set_member_svc_inst *svc_inst = BT_AUDIO_CHRC_USER_DATA(attr);
if (offset != 0) { if (offset != 0) {
return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET); return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
@ -385,7 +403,7 @@ static ssize_t write_set_lock(struct bt_conn *conn,
(void)memcpy(&val, buf, len); (void)memcpy(&val, buf, len);
res = set_lock(conn, csip, val); res = set_lock(conn, svc_inst, val);
if (res != BT_ATT_ERR_SUCCESS) { if (res != BT_ATT_ERR_SUCCESS) {
return BT_GATT_ERR(res); return BT_GATT_ERR(res);
} }
@ -402,35 +420,33 @@ static void set_lock_cfg_changed(const struct bt_gatt_attr *attr,
static ssize_t read_rank(struct bt_conn *conn, const struct bt_gatt_attr *attr, static ssize_t read_rank(struct bt_conn *conn, const struct bt_gatt_attr *attr,
void *buf, uint16_t len, uint16_t offset) void *buf, uint16_t len, uint16_t offset)
{ {
struct bt_csip *csip = BT_AUDIO_CHRC_USER_DATA(attr); struct bt_csip_set_member_svc_inst *svc_inst = BT_AUDIO_CHRC_USER_DATA(attr);
BT_DBG("%u", csip->srv.rank); BT_DBG("%u", svc_inst->rank);
return bt_gatt_attr_read(conn, attr, buf, len, offset, return bt_gatt_attr_read(conn, attr, buf, len, offset,
&csip->srv.rank, &svc_inst->rank,
sizeof(csip->srv.rank)); sizeof(svc_inst->rank));
} }
static void set_lock_timer_handler(struct k_work *work) static void set_lock_timer_handler(struct k_work *work)
{ {
struct k_work_delayable *delayable; struct k_work_delayable *delayable;
struct bt_csip_set_member_server *server; struct bt_csip_set_member_svc_inst *svc_inst;
struct bt_csip *csip;
delayable = CONTAINER_OF(work, struct k_work_delayable, work); delayable = CONTAINER_OF(work, struct k_work_delayable, work);
server = CONTAINER_OF(delayable, struct bt_csip_set_member_server, svc_inst = CONTAINER_OF(delayable, struct bt_csip_set_member_svc_inst,
set_lock_timer); set_lock_timer);
csip = CONTAINER_OF(server, struct bt_csip, srv);
BT_DBG("Lock timeout, releasing"); BT_DBG("Lock timeout, releasing");
csip->srv.set_lock = BT_CSIP_RELEASE_VALUE; svc_inst->set_lock = BT_CSIP_RELEASE_VALUE;
notify_clients(csip, NULL); notify_clients(svc_inst, NULL);
if (csip->srv.cb != NULL && csip->srv.cb->lock_changed != NULL) { if (svc_inst->cb != NULL && svc_inst->cb->lock_changed != NULL) {
bool locked = csip->srv.set_lock == BT_CSIP_LOCK_VALUE; bool locked = svc_inst->set_lock == BT_CSIP_LOCK_VALUE;
csip->srv.cb->lock_changed(NULL, csip, locked); svc_inst->cb->lock_changed(NULL, svc_inst, locked);
} }
} }
@ -445,17 +461,17 @@ static void csip_security_changed(struct bt_conn *conn, bt_security_t level,
return; return;
} }
for (int i = 0; i < ARRAY_SIZE(csip_insts); i++) { for (int i = 0; i < ARRAY_SIZE(svc_insts); i++) {
struct bt_csip *csip = &csip_insts[i]; struct bt_csip_set_member_svc_inst *svc_inst = &svc_insts[i];
for (int j = 0; j < ARRAY_SIZE(csip->srv.pend_notify); j++) { for (int j = 0; j < ARRAY_SIZE(svc_inst->pend_notify); j++) {
struct csip_pending_notifications *pend_notify; struct csip_pending_notifications *pend_notify;
pend_notify = &csip->srv.pend_notify[j]; pend_notify = &svc_inst->pend_notify[j];
if (pend_notify->pending && if (pend_notify->pending &&
bt_addr_le_eq(bt_conn_get_dst(conn), &pend_notify->addr)) { bt_addr_le_eq(bt_conn_get_dst(conn), &pend_notify->addr)) {
notify_lock_value(csip, conn); notify_lock_value(svc_inst, conn);
pend_notify->pending = false; pend_notify->pending = false;
break; break;
} }
@ -463,29 +479,30 @@ static void csip_security_changed(struct bt_conn *conn, bt_security_t level,
} }
} }
static void handle_csip_disconnect(struct bt_csip *csip, struct bt_conn *conn) static void handle_csip_disconnect(struct bt_csip_set_member_svc_inst *svc_inst,
struct bt_conn *conn)
{ {
BT_DBG("Non-bonded device"); BT_DBG("Non-bonded device");
if (is_last_client_to_write(csip, conn)) { if (is_last_client_to_write(svc_inst, conn)) {
(void)memset(&csip->srv.lock_client_addr, 0, (void)memset(&svc_inst->lock_client_addr, 0,
sizeof(csip->srv.lock_client_addr)); sizeof(svc_inst->lock_client_addr));
csip->srv.set_lock = BT_CSIP_RELEASE_VALUE; svc_inst->set_lock = BT_CSIP_RELEASE_VALUE;
notify_clients(csip, NULL); notify_clients(svc_inst, NULL);
if (csip->srv.cb != NULL && csip->srv.cb->lock_changed != NULL) { if (svc_inst->cb != NULL && svc_inst->cb->lock_changed != NULL) {
bool locked = csip->srv.set_lock == BT_CSIP_LOCK_VALUE; bool locked = svc_inst->set_lock == BT_CSIP_LOCK_VALUE;
csip->srv.cb->lock_changed(conn, csip, locked); svc_inst->cb->lock_changed(conn, svc_inst, locked);
} }
} }
/* Check if the disconnected device once was bonded and stored /* Check if the disconnected device once was bonded and stored
* here as a bonded device * here as a bonded device
*/ */
for (int i = 0; i < ARRAY_SIZE(csip->srv.pend_notify); i++) { for (int i = 0; i < ARRAY_SIZE(svc_inst->pend_notify); i++) {
struct csip_pending_notifications *pend_notify; struct csip_pending_notifications *pend_notify;
pend_notify = &csip->srv.pend_notify[i]; pend_notify = &svc_inst->pend_notify[i];
if (bt_addr_le_eq(bt_conn_get_dst(conn), &pend_notify->addr)) { if (bt_addr_le_eq(bt_conn_get_dst(conn), &pend_notify->addr)) {
(void)memset(pend_notify, 0, sizeof(*pend_notify)); (void)memset(pend_notify, 0, sizeof(*pend_notify));
@ -499,41 +516,41 @@ static void csip_disconnected(struct bt_conn *conn, uint8_t reason)
BT_DBG("Disconnected: %s (reason %u)", BT_DBG("Disconnected: %s (reason %u)",
bt_addr_le_str(bt_conn_get_dst(conn)), reason); bt_addr_le_str(bt_conn_get_dst(conn)), reason);
for (int i = 0; i < ARRAY_SIZE(csip_insts); i++) { for (int i = 0; i < ARRAY_SIZE(svc_insts); i++) {
handle_csip_disconnect(&csip_insts[i], conn); handle_csip_disconnect(&svc_insts[i], conn);
} }
} }
static void handle_csip_auth_complete(struct bt_csip *csip, static void handle_csip_auth_complete(struct bt_csip_set_member_svc_inst *svc_inst,
struct bt_conn *conn) struct bt_conn *conn)
{ {
/* Check if already in list, and do nothing if it is */ /* Check if already in list, and do nothing if it is */
for (int i = 0; i < ARRAY_SIZE(csip->srv.pend_notify); i++) { for (int i = 0; i < ARRAY_SIZE(svc_inst->pend_notify); i++) {
struct csip_pending_notifications *pend_notify; struct csip_pending_notifications *pend_notify;
pend_notify = &csip->srv.pend_notify[i]; pend_notify = &svc_inst->pend_notify[i];
if (pend_notify->active && if (pend_notify->active &&
bt_addr_le_eq(bt_conn_get_dst(conn), &pend_notify->addr)) { bt_addr_le_eq(bt_conn_get_dst(conn), &pend_notify->addr)) {
#if IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST) #if IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
pend_notify->age = csip->srv.age_counter++; pend_notify->age = svc_inst->age_counter++;
#endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */ #endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
return; return;
} }
} }
/* Copy addr to list over devices to save notifications for */ /* Copy addr to list over devices to save notifications for */
for (int i = 0; i < ARRAY_SIZE(csip->srv.pend_notify); i++) { for (int i = 0; i < ARRAY_SIZE(svc_inst->pend_notify); i++) {
struct csip_pending_notifications *pend_notify; struct csip_pending_notifications *pend_notify;
pend_notify = &csip->srv.pend_notify[i]; pend_notify = &svc_inst->pend_notify[i];
if (!pend_notify->active) { if (!pend_notify->active) {
bt_addr_le_copy(&pend_notify->addr, bt_addr_le_copy(&pend_notify->addr,
bt_conn_get_dst(conn)); bt_conn_get_dst(conn));
pend_notify->active = true; pend_notify->active = true;
#if IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST) #if IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
pend_notify->age = csip->srv.age_counter++; pend_notify->age = svc_inst->age_counter++;
#endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */ #endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
return; return;
} }
@ -542,12 +559,12 @@ static void handle_csip_auth_complete(struct bt_csip *csip,
#if IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST) #if IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
struct csip_pending_notifications *oldest; struct csip_pending_notifications *oldest;
oldest = &csip->srv.pend_notify[0]; oldest = &svc_inst->pend_notify[0];
for (int i = 1; i < ARRAY_SIZE(csip->srv.pend_notify); i++) { for (int i = 1; i < ARRAY_SIZE(svc_inst->pend_notify); i++) {
struct csip_pending_notifications *pend_notify; struct csip_pending_notifications *pend_notify;
pend_notify = &csip->srv.pend_notify[i]; pend_notify = &svc_inst->pend_notify[i];
if (pend_notify->age < oldest->age) { if (pend_notify->age < oldest->age) {
oldest = pend_notify; oldest = pend_notify;
@ -556,7 +573,7 @@ static void handle_csip_auth_complete(struct bt_csip *csip,
(void)memset(oldest, 0, sizeof(*oldest)); (void)memset(oldest, 0, sizeof(*oldest));
bt_addr_le_copy(&oldest->addr, &conn->le.dst); bt_addr_le_copy(&oldest->addr, &conn->le.dst);
oldest->active = true; oldest->active = true;
oldest->age = csip->srv.age_counter++; oldest->age = svc_inst->age_counter++;
#else #else
BT_WARN("Could not add device to pending notification list"); BT_WARN("Could not add device to pending notification list");
#endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */ #endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
@ -583,20 +600,20 @@ static void auth_pairing_complete(struct bt_conn *conn, bool bonded)
return; return;
} }
for (int i = 0; i < ARRAY_SIZE(csip_insts); i++) { for (int i = 0; i < ARRAY_SIZE(svc_insts); i++) {
handle_csip_auth_complete(&csip_insts[i], conn); handle_csip_auth_complete(&svc_insts[i], conn);
} }
} }
static void csip_bond_deleted(uint8_t id, const bt_addr_le_t *peer) static void csip_bond_deleted(uint8_t id, const bt_addr_le_t *peer)
{ {
for (int i = 0; i < ARRAY_SIZE(csip_insts); i++) { for (int i = 0; i < ARRAY_SIZE(svc_insts); i++) {
struct bt_csip *csip = &csip_insts[i]; struct bt_csip_set_member_svc_inst *svc_inst = &svc_insts[i];
for (int j = 0; j < ARRAY_SIZE(csip->srv.pend_notify); j++) { for (int j = 0; j < ARRAY_SIZE(svc_inst->pend_notify); j++) {
struct csip_pending_notifications *pend_notify; struct csip_pending_notifications *pend_notify;
pend_notify = &csip->srv.pend_notify[j]; pend_notify = &svc_inst->pend_notify[j];
if (pend_notify->active && if (pend_notify->active &&
bt_addr_le_eq(peer, &pend_notify->addr)) { bt_addr_le_eq(peer, &pend_notify->addr)) {
@ -641,14 +658,14 @@ static struct bt_conn_auth_info_cb auth_callbacks = {
read_rank, NULL, &_csip) \ read_rank, NULL, &_csip) \
} }
BT_GATT_SERVICE_INSTANCE_DEFINE(csip_service_list, csip_insts, BT_GATT_SERVICE_INSTANCE_DEFINE(csip_set_member_service_list, svc_insts,
CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT, CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT,
BT_CSIP_SERVICE_DEFINITION); BT_CSIP_SERVICE_DEFINITION);
/****************************** Public API ******************************/ /****************************** Public API ******************************/
void *bt_csip_set_member_svc_decl_get(const struct bt_csip *csip) void *bt_csip_set_member_svc_decl_get(const struct bt_csip_set_member_svc_inst *svc_inst)
{ {
return csip->srv.service_p->attrs; return svc_inst->service_p->attrs;
} }
static bool valid_register_param(const struct bt_csip_set_member_register_param *param) static bool valid_register_param(const struct bt_csip_set_member_register_param *param)
@ -675,13 +692,13 @@ static bool valid_register_param(const struct bt_csip_set_member_register_param
} }
int bt_csip_set_member_register(const struct bt_csip_set_member_register_param *param, int bt_csip_set_member_register(const struct bt_csip_set_member_register_param *param,
struct bt_csip **csip) struct bt_csip_set_member_svc_inst **svc_inst)
{ {
static uint8_t instance_cnt; static uint8_t instance_cnt;
struct bt_csip *inst; struct bt_csip_set_member_svc_inst *inst;
int err; int err;
if (instance_cnt == ARRAY_SIZE(csip_insts)) { if (instance_cnt == ARRAY_SIZE(svc_insts)) {
return -ENOMEM; return -ENOMEM;
} }
@ -695,26 +712,26 @@ int bt_csip_set_member_register(const struct bt_csip_set_member_register_param *
return -EINVAL; return -EINVAL;
} }
inst = &csip_insts[instance_cnt]; inst = &svc_insts[instance_cnt];
inst->srv.service_p = &csip_service_list[instance_cnt]; inst->service_p = &csip_set_member_service_list[instance_cnt];
instance_cnt++; instance_cnt++;
bt_conn_cb_register(&conn_callbacks); bt_conn_cb_register(&conn_callbacks);
bt_conn_auth_info_cb_register(&auth_callbacks); bt_conn_auth_info_cb_register(&auth_callbacks);
err = bt_gatt_service_register(inst->srv.service_p); err = bt_gatt_service_register(inst->service_p);
if (err != 0) { if (err != 0) {
BT_DBG("CSIS service register failed: %d", err); BT_DBG("CSIS service register failed: %d", err);
return err; return err;
} }
k_work_init_delayable(&inst->srv.set_lock_timer, k_work_init_delayable(&inst->set_lock_timer,
set_lock_timer_handler); set_lock_timer_handler);
inst->srv.rank = param->rank; inst->rank = param->rank;
inst->srv.set_size = param->set_size; inst->set_size = param->set_size;
inst->srv.set_lock = BT_CSIP_RELEASE_VALUE; inst->set_lock = BT_CSIP_RELEASE_VALUE;
inst->srv.set_sirk.type = BT_CSIP_SIRK_TYPE_PLAIN; inst->set_sirk.type = BT_CSIP_SIRK_TYPE_PLAIN;
inst->srv.cb = param->cb; inst->cb = param->cb;
if (IS_ENABLED(CONFIG_BT_CSIP_SET_MEMBER_TEST_SAMPLE_DATA)) { if (IS_ENABLED(CONFIG_BT_CSIP_SET_MEMBER_TEST_SAMPLE_DATA)) {
uint8_t test_sirk[] = { uint8_t test_sirk[] = {
@ -722,19 +739,20 @@ int bt_csip_set_member_register(const struct bt_csip_set_member_register_param *
0x22, 0xfd, 0xa1, 0x21, 0x09, 0x7d, 0x7d, 0x45, 0x22, 0xfd, 0xa1, 0x21, 0x09, 0x7d, 0x7d, 0x45,
}; };
(void)memcpy(inst->srv.set_sirk.value, test_sirk, (void)memcpy(inst->set_sirk.value, test_sirk,
sizeof(test_sirk)); sizeof(test_sirk));
BT_DBG("CSIP SIRK was overwritten by sample data SIRK"); BT_DBG("CSIP SIRK was overwritten by sample data SIRK");
} else { } else {
(void)memcpy(inst->srv.set_sirk.value, param->set_sirk, (void)memcpy(inst->set_sirk.value, param->set_sirk,
sizeof(inst->srv.set_sirk.value)); sizeof(inst->set_sirk.value));
} }
*csip = inst; *svc_inst = inst;
return 0; return 0;
} }
int bt_csip_set_member_lock(struct bt_csip *csip, bool lock, bool force) int bt_csip_set_member_lock(struct bt_csip_set_member_svc_inst *svc_inst,
bool lock, bool force)
{ {
uint8_t lock_val; uint8_t lock_val;
int err = 0; int err = 0;
@ -746,14 +764,14 @@ int bt_csip_set_member_lock(struct bt_csip *csip, bool lock, bool force)
} }
if (!lock && force) { if (!lock && force) {
csip->srv.set_lock = BT_CSIP_RELEASE_VALUE; svc_inst->set_lock = BT_CSIP_RELEASE_VALUE;
notify_clients(csip, NULL); notify_clients(svc_inst, NULL);
if (csip->srv.cb != NULL && csip->srv.cb->lock_changed != NULL) { if (svc_inst->cb != NULL && svc_inst->cb->lock_changed != NULL) {
csip->srv.cb->lock_changed(NULL, &csip_insts[0], false); svc_inst->cb->lock_changed(NULL, &svc_insts[0], false);
} }
} else { } else {
err = set_lock(NULL, csip, lock_val); err = set_lock(NULL, svc_inst, lock_val);
} }
if (err < 0) { if (err < 0) {
@ -763,8 +781,8 @@ int bt_csip_set_member_lock(struct bt_csip *csip, bool lock, bool force)
} }
} }
void bt_csip_set_member_print_sirk(const struct bt_csip *csip) void bt_csip_set_member_print_sirk(const struct bt_csip_set_member_svc_inst *svc_inst)
{ {
LOG_HEXDUMP_DBG(&csip->srv.set_sirk, sizeof(csip->srv.set_sirk), LOG_HEXDUMP_DBG(&svc_inst->set_sirk, sizeof(svc_inst->set_sirk),
"Set SIRK"); "Set SIRK");
} }

View file

@ -1247,7 +1247,7 @@ static ssize_t ad_init(struct bt_data *data_array, const size_t data_array_size,
*/ */
if (IS_ENABLED(CONFIG_BT_PRIVACY) && if (IS_ENABLED(CONFIG_BT_PRIVACY) &&
IS_ENABLED(CONFIG_BT_CSIP_SET_MEMBER) && IS_ENABLED(CONFIG_BT_CSIP_SET_MEMBER) &&
csip != NULL) { svc_inst != NULL) {
ad_flags |= BT_LE_AD_LIMITED; ad_flags |= BT_LE_AD_LIMITED;
} else { } else {
ad_flags |= BT_LE_AD_GENERAL; ad_flags |= BT_LE_AD_GENERAL;

View file

@ -18,7 +18,7 @@
extern const struct shell *ctx_shell; extern const struct shell *ctx_shell;
extern struct bt_conn *default_conn; extern struct bt_conn *default_conn;
extern struct bt_csip *csip; extern struct bt_csip_set_member_svc_inst *svc_inst;
#if defined(CONFIG_BT_ISO) #if defined(CONFIG_BT_ISO)
extern struct bt_iso_chan iso_chan; extern struct bt_iso_chan iso_chan;

View file

@ -16,10 +16,12 @@
#include "bt.h" #include "bt.h"
extern const struct shell *ctx_shell; extern const struct shell *ctx_shell;
static struct bt_csip *cap_csip_set_member; static struct bt_csip_set_member_svc_inst *cap_csip_svc_inst;
static uint8_t sirk_read_rsp = BT_CSIP_READ_SIRK_REQ_RSP_ACCEPT; static uint8_t sirk_read_rsp = BT_CSIP_READ_SIRK_REQ_RSP_ACCEPT;
static void locked_cb(struct bt_conn *conn, struct bt_csip *csip, bool locked) static void locked_cb(struct bt_conn *conn,
struct bt_csip_set_member_svc_inst *svc_inst,
bool locked)
{ {
if (conn == NULL) { if (conn == NULL) {
shell_error(ctx_shell, "Server %s the device", shell_error(ctx_shell, "Server %s the device",
@ -34,7 +36,8 @@ static void locked_cb(struct bt_conn *conn, struct bt_csip *csip, bool locked)
} }
} }
static uint8_t sirk_read_req_cb(struct bt_conn *conn, struct bt_csip *csip) static uint8_t sirk_read_req_cb(struct bt_conn *conn,
struct bt_csip_set_member_svc_inst *svc_inst)
{ {
char addr[BT_ADDR_LE_STR_LEN]; char addr[BT_ADDR_LE_STR_LEN];
static const char *const rsp_strings[] = { static const char *const rsp_strings[] = {
@ -95,7 +98,7 @@ static int cmd_cap_acceptor_init(const struct shell *sh, size_t argc,
} }
} }
err = bt_cap_acceptor_register(&param, &cap_csip_set_member); err = bt_cap_acceptor_register(&param, &cap_csip_svc_inst);
if (err != 0) { if (err != 0) {
shell_error(sh, "Could not register CAS: %d", err); shell_error(sh, "Could not register CAS: %d", err);
@ -108,7 +111,7 @@ static int cmd_cap_acceptor_init(const struct shell *sh, size_t argc,
static int cmd_cap_acceptor_print_sirk(const struct shell *sh, size_t argc, static int cmd_cap_acceptor_print_sirk(const struct shell *sh, size_t argc,
char *argv[]) char *argv[])
{ {
bt_csip_set_member_print_sirk(cap_csip_set_member); bt_csip_set_member_print_sirk(cap_csip_svc_inst);
return 0; return 0;
} }
@ -118,7 +121,7 @@ static int cmd_cap_acceptor_lock(const struct shell *sh, size_t argc,
{ {
int err; int err;
err = bt_csip_set_member_lock(cap_csip_set_member, true, false); err = bt_csip_set_member_lock(cap_csip_svc_inst, true, false);
if (err != 0) { if (err != 0) {
shell_error(sh, "Failed to set lock: %d", err); shell_error(sh, "Failed to set lock: %d", err);
@ -146,7 +149,7 @@ static int cmd_cap_acceptor_release(const struct shell *sh, size_t argc,
} }
} }
err = bt_csip_set_member_lock(cap_csip_set_member, false, force); err = bt_csip_set_member_lock(cap_csip_svc_inst, false, force);
if (err != 0) { if (err != 0) {
shell_error(sh, "Failed to release lock: %d", err); shell_error(sh, "Failed to release lock: %d", err);

View file

@ -3,7 +3,7 @@
* @brief Shell APIs for Bluetooth CSIP set member * @brief Shell APIs for Bluetooth CSIP set member
* *
* Copyright (c) 2020 Bose Corporation * Copyright (c) 2020 Bose Corporation
* Copyright (c) 2021 Nordic Semiconductor ASA * Copyright (c) 2021-2022 Nordic Semiconductor ASA
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -20,10 +20,12 @@
#include "bt.h" #include "bt.h"
extern const struct shell *ctx_shell; extern const struct shell *ctx_shell;
struct bt_csip *csip; struct bt_csip_set_member_svc_inst *svc_inst;
static uint8_t sirk_read_rsp = BT_CSIP_READ_SIRK_REQ_RSP_ACCEPT; static uint8_t sirk_read_rsp = BT_CSIP_READ_SIRK_REQ_RSP_ACCEPT;
static void locked_cb(struct bt_conn *conn, struct bt_csip *csip, bool locked) static void locked_cb(struct bt_conn *conn,
struct bt_csip_set_member_svc_inst *svc_inst,
bool locked)
{ {
if (conn == NULL) { if (conn == NULL) {
shell_error(ctx_shell, "Server %s the device", shell_error(ctx_shell, "Server %s the device",
@ -38,7 +40,8 @@ static void locked_cb(struct bt_conn *conn, struct bt_csip *csip, bool locked)
} }
} }
static uint8_t sirk_read_req_cb(struct bt_conn *conn, struct bt_csip *csip) static uint8_t sirk_read_req_cb(struct bt_conn *conn,
struct bt_csip_set_member_svc_inst *svc_inst)
{ {
char addr[BT_ADDR_LE_STR_LEN]; char addr[BT_ADDR_LE_STR_LEN];
static const char *const rsp_strings[] = { static const char *const rsp_strings[] = {
@ -96,7 +99,7 @@ static int cm_csip_set_member_register(const struct shell *sh, size_t argc, char
} }
} }
err = bt_csip_set_member_register(&param, &csip); err = bt_csip_set_member_register(&param, &svc_inst);
if (err != 0) { if (err != 0) {
shell_error(sh, "Could not register CSIP: %d", err); shell_error(sh, "Could not register CSIP: %d", err);
return err; return err;
@ -108,7 +111,7 @@ static int cm_csip_set_member_register(const struct shell *sh, size_t argc, char
static int cm_csip_set_member_print_sirk(const struct shell *sh, size_t argc, static int cm_csip_set_member_print_sirk(const struct shell *sh, size_t argc,
char *argv[]) char *argv[])
{ {
bt_csip_set_member_print_sirk(csip); bt_csip_set_member_print_sirk(svc_inst);
return 0; return 0;
} }
@ -116,7 +119,7 @@ static int cm_csip_set_member_lock(const struct shell *sh, size_t argc, char *ar
{ {
int err; int err;
err = bt_csip_set_member_lock(csip, true, false); err = bt_csip_set_member_lock(svc_inst, true, false);
if (err != 0) { if (err != 0) {
shell_error(sh, "Failed to set lock: %d", err); shell_error(sh, "Failed to set lock: %d", err);
return -ENOEXEC; return -ENOEXEC;
@ -142,7 +145,7 @@ static int cm_csip_set_member_release(const struct shell *sh, size_t argc,
} }
} }
err = bt_csip_set_member_lock(csip, false, force); err = bt_csip_set_member_lock(svc_inst, false, force);
if (err != 0) { if (err != 0) {
shell_error(sh, "Failed to release lock: %d", err); shell_error(sh, "Failed to release lock: %d", err);
@ -211,7 +214,7 @@ ssize_t csis_ad_data_add(struct bt_data *data_array, const size_t data_array_siz
size_t ad_len = 0; size_t ad_len = 0;
/* Advertise RSI in discoverable mode only */ /* Advertise RSI in discoverable mode only */
if (csip != NULL && discoverable) { if (svc_inst != NULL && discoverable) {
static uint8_t ad_rsi[BT_CSIP_RSI_SIZE]; static uint8_t ad_rsi[BT_CSIP_RSI_SIZE];
int err; int err;
@ -223,7 +226,7 @@ ssize_t csis_ad_data_add(struct bt_data *data_array, const size_t data_array_siz
shell_warn(ctx_shell, "RSI derived from unencrypted SIRK"); shell_warn(ctx_shell, "RSI derived from unencrypted SIRK");
} }
err = bt_csip_set_member_generate_rsi(csip, ad_rsi); err = bt_csip_set_member_generate_rsi(svc_inst, ad_rsi);
if (err != 0) { if (err != 0) {
shell_error(ctx_shell, "Failed to generate RSI (err %d)", err); shell_error(ctx_shell, "Failed to generate RSI (err %d)", err);
return err; return err;

View file

@ -19,7 +19,7 @@ static const struct bt_data cap_acceptor_ad[] = {
BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_CAS_VAL)), BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_CAS_VAL)),
}; };
static struct bt_csip *csip_set_member; static struct bt_csip_set_member_svc_inst *csip_set_member;
CREATE_FLAG(flag_connected); CREATE_FLAG(flag_connected);

View file

@ -9,7 +9,7 @@
#include "common.h" #include "common.h"
static struct bt_csip *csip; static struct bt_csip_set_member_svc_inst *svc_inst;
static struct bt_conn_cb conn_callbacks; static struct bt_conn_cb conn_callbacks;
extern enum bst_result_t bst_result; extern enum bst_result_t bst_result;
static volatile bool g_locked; static volatile bool g_locked;
@ -47,14 +47,16 @@ static void csip_disconnected(struct bt_conn *conn, uint8_t reason)
} }
} }
static void csip_lock_changed_cb(struct bt_conn *conn, struct bt_csip *csip, static void csip_lock_changed_cb(struct bt_conn *conn,
struct bt_csip_set_member_svc_inst *svc_inst,
bool locked) bool locked)
{ {
printk("Client %p %s the lock\n", conn, locked ? "locked" : "released"); printk("Client %p %s the lock\n", conn, locked ? "locked" : "released");
g_locked = locked; g_locked = locked;
} }
static uint8_t sirk_read_req_cb(struct bt_conn *conn, struct bt_csip *csip) static uint8_t sirk_read_req_cb(struct bt_conn *conn,
struct bt_csip_set_member_svc_inst *svc_inst)
{ {
return sirk_read_req_rsp; return sirk_read_req_rsp;
} }
@ -81,13 +83,13 @@ static void bt_ready(int err)
param.cb = &csip_cbs; param.cb = &csip_cbs;
err = bt_csip_set_member_register(&param, &csip); err = bt_csip_set_member_register(&param, &svc_inst);
if (err != 0) { if (err != 0) {
FAIL("Could not register CSIP (err %d)\n", err); FAIL("Could not register CSIP (err %d)\n", err);
return; return;
} }
err = bt_csip_set_member_generate_rsi(csip, rsi); err = bt_csip_set_member_generate_rsi(svc_inst, rsi);
if (err != 0) { if (err != 0) {
FAIL("Failed to generate RSI (err %d)\n", err); FAIL("Failed to generate RSI (err %d)\n", err);
return; return;
@ -133,7 +135,7 @@ static void test_force_release(void)
WAIT_FOR_COND(g_locked); WAIT_FOR_COND(g_locked);
printk("Force releasing set\n"); printk("Force releasing set\n");
bt_csip_set_member_lock(csip, false, true); bt_csip_set_member_lock(svc_inst, false, true);
} }
static void test_csip_enc(void) static void test_csip_enc(void)