Bluetooth: Audio: VCS introduce opaque bt_vcs struct

Add a bt_vcs struct that represents a VCS instance,
either a local (server) or remote (client) instance.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
Emil Gydesen 2021-05-27 22:46:30 +02:00 committed by Carles Cufí
commit db025e26a6
6 changed files with 80 additions and 64 deletions

View file

@ -39,6 +39,9 @@ extern "C" {
#define BT_VCS_ERR_INVALID_COUNTER 0x80 #define BT_VCS_ERR_INVALID_COUNTER 0x80
#define BT_VCS_ERR_OP_NOT_SUPPORTED 0x81 #define BT_VCS_ERR_OP_NOT_SUPPORTED 0x81
/** @brief Opaque Volume Control Service instance. */
struct bt_vcs;
/** Register structure for Volume Control Service */ /** Register structure for Volume Control Service */
struct bt_vcs_register_param { struct bt_vcs_register_param {
/** Register parameters for Volume Offset Control Services */ /** Register parameters for Volume Offset Control Services */
@ -77,10 +80,11 @@ struct bt_vcs_included {
* clients. * clients.
* *
* @param param Volume Control Service register parameters. * @param param Volume Control Service register parameters.
* @param[out] vcs Pointer to the registered Volume Control Service.
* *
* @return 0 if success, errno on failure. * @return 0 if success, errno on failure.
*/ */
int bt_vcs_register(struct bt_vcs_register_param *param); int bt_vcs_register(struct bt_vcs_register_param *param, struct bt_vcs **vcs);
/** /**
* @brief Get Volume Control Service included services. * @brief Get Volume Control Service included services.

View file

@ -34,18 +34,7 @@
#define VALID_VCS_OPCODE(opcode) ((opcode) <= BT_VCS_OPCODE_MUTE) #define VALID_VCS_OPCODE(opcode) ((opcode) <= BT_VCS_OPCODE_MUTE)
struct vcs_inst_t { static struct bt_vcs_server vcs_inst = {
struct vcs_state state;
uint8_t flags;
struct bt_vcs_cb *cb;
uint8_t volume_step;
struct bt_gatt_service *service_p;
struct bt_vocs *vocs_insts[CONFIG_BT_VCS_VOCS_INSTANCE_COUNT];
struct bt_aics *aics_insts[CONFIG_BT_VCS_AICS_INSTANCE_COUNT];
};
static struct vcs_inst_t vcs_inst = {
.state.volume = 100, .state.volume = 100,
.volume_step = 1, .volume_step = 1,
}; };
@ -335,7 +324,7 @@ static int prepare_aics_inst(struct bt_vcs_register_param *param)
} }
/****************************** PUBLIC API ******************************/ /****************************** PUBLIC API ******************************/
int bt_vcs_register(struct bt_vcs_register_param *param) int bt_vcs_register(struct bt_vcs_register_param *param, struct bt_vcs **vcs)
{ {
int err; int err;
@ -366,6 +355,8 @@ int bt_vcs_register(struct bt_vcs_register_param *param)
vcs_inst.cb = param->cb; vcs_inst.cb = param->cb;
*vcs = (struct bt_vcs *)&vcs_inst;
return err; return err;
} }

View file

@ -21,46 +21,18 @@
#include <bluetooth/audio/vcs.h> #include <bluetooth/audio/vcs.h>
#include "vcs_internal.h" #include "vcs_internal.h"
#include "aics_internal.h"
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_VCS_CLIENT) #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_VCS_CLIENT)
#define LOG_MODULE_NAME bt_vcs_client #define LOG_MODULE_NAME bt_vcs_client
#include "common/log.h" #include "common/log.h"
struct vcs_instance {
struct vcs_state state;
uint8_t flags;
uint16_t start_handle;
uint16_t end_handle;
uint16_t state_handle;
uint16_t control_handle;
uint16_t flag_handle;
struct bt_gatt_subscribe_params state_sub_params;
struct bt_gatt_subscribe_params flag_sub_params;
bool cp_retried;
bool busy;
struct vcs_control_vol cp_val;
struct bt_gatt_write_params write_params;
struct bt_gatt_read_params read_params;
struct bt_gatt_discover_params discover_params;
struct bt_uuid_16 uuid;
uint8_t vocs_inst_cnt;
struct bt_vocs *vocs[CONFIG_BT_VCS_CLIENT_MAX_VOCS_INST];
uint8_t aics_inst_cnt;
struct bt_aics *aics[CONFIG_BT_VCS_CLIENT_MAX_AICS_INST];
struct bt_conn *conn;
};
/* Callback functions */ /* Callback functions */
static struct bt_vcs_cb *vcs_client_cb; static struct bt_vcs_cb *vcs_client_cb;
static struct vcs_instance vcs_insts[CONFIG_BT_MAX_CONN]; static struct bt_vcs_client vcs_insts[CONFIG_BT_MAX_CONN];
static int vcs_client_common_vcs_cp(struct bt_conn *conn, uint8_t opcode); static int vcs_client_common_vcs_cp(struct bt_conn *conn, uint8_t opcode);
static struct vcs_instance *lookup_vcs_by_vocs(const struct bt_vocs *vocs) static struct bt_vcs_client *lookup_vcs_by_vocs(const struct bt_vocs *vocs)
{ {
__ASSERT(vocs != NULL, "VOCS pointer cannot be NULL"); __ASSERT(vocs != NULL, "VOCS pointer cannot be NULL");
@ -126,7 +98,7 @@ static uint8_t vcs_client_notify_handler(struct bt_conn *conn,
const void *data, uint16_t length) const void *data, uint16_t length)
{ {
uint16_t handle = params->value_handle; uint16_t handle = params->value_handle;
struct vcs_instance *vcs_inst = &vcs_insts[bt_conn_index(conn)]; struct bt_vcs_client *vcs_inst = &vcs_insts[bt_conn_index(conn)];
if (data == NULL) { if (data == NULL) {
return BT_GATT_ITER_CONTINUE; return BT_GATT_ITER_CONTINUE;
@ -159,7 +131,7 @@ static uint8_t vcs_client_read_vol_state_cb(struct bt_conn *conn, uint8_t err,
const void *data, uint16_t length) const void *data, uint16_t length)
{ {
int cb_err = err; int cb_err = err;
struct vcs_instance *vcs_inst = &vcs_insts[bt_conn_index(conn)]; struct bt_vcs_client *vcs_inst = &vcs_insts[bt_conn_index(conn)];
vcs_inst->busy = false; vcs_inst->busy = false;
@ -197,7 +169,7 @@ static uint8_t vcs_client_read_flag_cb(struct bt_conn *conn, uint8_t err,
const void *data, uint16_t length) const void *data, uint16_t length)
{ {
int cb_err = err; int cb_err = err;
struct vcs_instance *vcs_inst = &vcs_insts[bt_conn_index(conn)]; struct bt_vcs_client *vcs_inst = &vcs_insts[bt_conn_index(conn)];
vcs_inst->busy = false; vcs_inst->busy = false;
@ -278,7 +250,7 @@ static uint8_t internal_read_vol_state_cb(struct bt_conn *conn, uint8_t err,
const void *data, uint16_t length) const void *data, uint16_t length)
{ {
int cb_err = 0; int cb_err = 0;
struct vcs_instance *vcs_inst = &vcs_insts[bt_conn_index(conn)]; struct bt_vcs_client *vcs_inst = &vcs_insts[bt_conn_index(conn)];
uint8_t opcode = vcs_inst->cp_val.cp.opcode; uint8_t opcode = vcs_inst->cp_val.cp.opcode;
@ -327,7 +299,7 @@ static uint8_t internal_read_vol_state_cb(struct bt_conn *conn, uint8_t err,
static void vcs_client_write_vcs_cp_cb(struct bt_conn *conn, uint8_t err, static void vcs_client_write_vcs_cp_cb(struct bt_conn *conn, uint8_t err,
struct bt_gatt_write_params *params) struct bt_gatt_write_params *params)
{ {
struct vcs_instance *vcs_inst = &vcs_insts[bt_conn_index(conn)]; struct bt_vcs_client *vcs_inst = &vcs_insts[bt_conn_index(conn)];
uint8_t opcode = vcs_inst->cp_val.cp.opcode; uint8_t opcode = vcs_inst->cp_val.cp.opcode;
int cb_err = err; int cb_err = err;
@ -373,7 +345,7 @@ static uint8_t vcs_discover_include_func(struct bt_conn *conn,
struct bt_gatt_include *include; struct bt_gatt_include *include;
uint8_t inst_idx; uint8_t inst_idx;
int err; int err;
struct vcs_instance *vcs_inst = &vcs_insts[bt_conn_index(conn)]; struct bt_vcs_client *vcs_inst = &vcs_insts[bt_conn_index(conn)];
if (attr == NULL) { if (attr == NULL) {
BT_DBG("Discover include complete for VCS: %u AICS and %u VOCS", BT_DBG("Discover include complete for VCS: %u AICS and %u VOCS",
@ -474,7 +446,7 @@ static uint8_t vcs_discover_func(struct bt_conn *conn,
int err = 0; int err = 0;
struct bt_gatt_chrc *chrc; struct bt_gatt_chrc *chrc;
struct bt_gatt_subscribe_params *sub_params = NULL; struct bt_gatt_subscribe_params *sub_params = NULL;
struct vcs_instance *vcs_inst = &vcs_insts[bt_conn_index(conn)]; struct bt_vcs_client *vcs_inst = &vcs_insts[bt_conn_index(conn)];
if (attr == NULL) { if (attr == NULL) {
BT_DBG("Setup complete for VCS"); BT_DBG("Setup complete for VCS");
@ -555,7 +527,7 @@ static uint8_t primary_discover_func(struct bt_conn *conn,
struct bt_gatt_discover_params *params) struct bt_gatt_discover_params *params)
{ {
struct bt_gatt_service_val *prim_service; struct bt_gatt_service_val *prim_service;
struct vcs_instance *vcs_inst = &vcs_insts[bt_conn_index(conn)]; struct bt_vcs_client *vcs_inst = &vcs_insts[bt_conn_index(conn)];
if (attr == NULL) { if (attr == NULL) {
BT_DBG("Could not find a VCS instance on the server"); BT_DBG("Could not find a VCS instance on the server");
@ -600,7 +572,7 @@ static uint8_t primary_discover_func(struct bt_conn *conn,
static int vcs_client_common_vcs_cp(struct bt_conn *conn, uint8_t opcode) static int vcs_client_common_vcs_cp(struct bt_conn *conn, uint8_t opcode)
{ {
int err; int err;
struct vcs_instance *vcs_inst; struct bt_vcs_client *vcs_inst;
CHECKIF(conn == NULL) { CHECKIF(conn == NULL) {
BT_DBG("NULL conn"); BT_DBG("NULL conn");
@ -635,7 +607,7 @@ static int vcs_client_common_vcs_cp(struct bt_conn *conn, uint8_t opcode)
static void aics_discover_cb(struct bt_conn *conn, struct bt_aics *inst, static void aics_discover_cb(struct bt_conn *conn, struct bt_aics *inst,
int err) int err)
{ {
struct vcs_instance *vcs_inst = &vcs_insts[bt_conn_index(conn)]; struct bt_vcs_client *vcs_inst = &vcs_insts[bt_conn_index(conn)];
if (err == 0) { if (err == 0) {
/* Continue discovery of included services */ /* Continue discovery of included services */
@ -652,7 +624,7 @@ static void aics_discover_cb(struct bt_conn *conn, struct bt_aics *inst,
static void vocs_discover_cb(struct bt_vocs *inst, int err) static void vocs_discover_cb(struct bt_vocs *inst, int err)
{ {
struct vcs_instance *vcs_inst = lookup_vcs_by_vocs(inst); struct bt_vcs_client *vcs_inst = lookup_vcs_by_vocs(inst);
if (vcs_inst == NULL) { if (vcs_inst == NULL) {
BT_ERR("Could not lookup vcs_inst from vocs"); BT_ERR("Could not lookup vcs_inst from vocs");
@ -681,7 +653,7 @@ static void vocs_discover_cb(struct bt_vocs *inst, int err)
static void vcs_client_reset(struct bt_conn *conn) static void vcs_client_reset(struct bt_conn *conn)
{ {
struct vcs_instance *vcs_inst = &vcs_insts[bt_conn_index(conn)]; struct bt_vcs_client *vcs_inst = &vcs_insts[bt_conn_index(conn)];
memset(&vcs_inst->state, 0, sizeof(vcs_inst->state)); memset(&vcs_inst->state, 0, sizeof(vcs_inst->state));
vcs_inst->flags = 0; vcs_inst->flags = 0;
@ -738,7 +710,7 @@ static void bt_vcs_client_init(void)
int bt_vcs_discover(struct bt_conn *conn) int bt_vcs_discover(struct bt_conn *conn)
{ {
static bool initialized; static bool initialized;
struct vcs_instance *vcs_inst; struct bt_vcs_client *vcs_inst;
/* /*
* This will initiate a discover procedure. The procedure will do the * This will initiate a discover procedure. The procedure will do the
@ -839,7 +811,7 @@ int bt_vcs_client_included_get(struct bt_conn *conn,
struct bt_vcs_included *included) struct bt_vcs_included *included)
{ {
uint8_t conn_index; uint8_t conn_index;
struct vcs_instance *vcs_inst; struct bt_vcs_client *vcs_inst;
CHECKIF(!included || !conn) { CHECKIF(!included || !conn) {
return -EINVAL; return -EINVAL;
@ -861,7 +833,7 @@ int bt_vcs_client_included_get(struct bt_conn *conn,
int bt_vcs_client_read_vol_state(struct bt_conn *conn) int bt_vcs_client_read_vol_state(struct bt_conn *conn)
{ {
int err; int err;
struct vcs_instance *vcs_inst; struct bt_vcs_client *vcs_inst;
CHECKIF(conn == NULL) { CHECKIF(conn == NULL) {
BT_DBG("NULL conn"); BT_DBG("NULL conn");
@ -893,7 +865,7 @@ int bt_vcs_client_read_vol_state(struct bt_conn *conn)
int bt_vcs_client_read_flags(struct bt_conn *conn) int bt_vcs_client_read_flags(struct bt_conn *conn)
{ {
int err; int err;
struct vcs_instance *vcs_inst; struct bt_vcs_client *vcs_inst;
CHECKIF(conn == NULL) { CHECKIF(conn == NULL) {
BT_DBG("NULL conn"); BT_DBG("NULL conn");
@ -946,7 +918,7 @@ int bt_vcs_client_unmute_vol_up(struct bt_conn *conn)
int bt_vcs_client_set_volume(struct bt_conn *conn, uint8_t volume) int bt_vcs_client_set_volume(struct bt_conn *conn, uint8_t volume)
{ {
int err; int err;
struct vcs_instance *vcs_inst; struct bt_vcs_client *vcs_inst;
CHECKIF(conn == NULL) { CHECKIF(conn == NULL) {
BT_DBG("NULL conn"); BT_DBG("NULL conn");

View file

@ -36,6 +36,53 @@ struct vcs_control_vol {
uint8_t volume; uint8_t volume;
} __packed; } __packed;
struct bt_vcs_client {
struct vcs_state state;
uint8_t flags;
uint16_t start_handle;
uint16_t end_handle;
uint16_t state_handle;
uint16_t control_handle;
uint16_t flag_handle;
struct bt_gatt_subscribe_params state_sub_params;
struct bt_gatt_subscribe_params flag_sub_params;
bool cp_retried;
bool busy;
struct vcs_control_vol cp_val;
struct bt_gatt_write_params write_params;
struct bt_gatt_read_params read_params;
struct bt_gatt_discover_params discover_params;
struct bt_uuid_16 uuid;
uint8_t vocs_inst_cnt;
struct bt_vocs *vocs[CONFIG_BT_VCS_CLIENT_MAX_VOCS_INST];
uint8_t aics_inst_cnt;
struct bt_aics *aics[CONFIG_BT_VCS_CLIENT_MAX_AICS_INST];
struct bt_conn *conn;
};
struct bt_vcs_server {
struct vcs_state state;
uint8_t flags;
struct bt_vcs_cb *cb;
uint8_t volume_step;
struct bt_gatt_service *service_p;
struct bt_vocs *vocs_insts[CONFIG_BT_VCS_VOCS_INSTANCE_COUNT];
struct bt_aics *aics_insts[CONFIG_BT_VCS_AICS_INSTANCE_COUNT];
};
/* Struct used as a common type for the api */
struct bt_vcs {
union {
struct bt_vcs_server srv;
struct bt_vcs_client cli;
};
};
int bt_vcs_client_included_get(struct bt_conn *conn, int bt_vcs_client_included_get(struct bt_conn *conn,
struct bt_vcs_included *included); struct bt_vcs_included *included);
int bt_vcs_client_read_vol_state(struct bt_conn *conn); int bt_vcs_client_read_vol_state(struct bt_conn *conn);

View file

@ -16,6 +16,7 @@
#include "bt.h" #include "bt.h"
static struct bt_vcs *vcs;
static struct bt_vcs_included vcs_included; static struct bt_vcs_included vcs_included;
static void vcs_state_cb(struct bt_conn *conn, int err, uint8_t volume, static void vcs_state_cb(struct bt_conn *conn, int err, uint8_t volume,
@ -196,7 +197,7 @@ static int cmd_vcs_init(const struct shell *sh, size_t argc, char **argv)
vcs_param.cb = &vcs_cbs; vcs_param.cb = &vcs_cbs;
result = bt_vcs_register(&vcs_param); result = bt_vcs_register(&vcs_param, &vcs);
if (result) { if (result) {
shell_print(sh, "Fail: %d", result); shell_print(sh, "Fail: %d", result);
return result; return result;

View file

@ -22,6 +22,7 @@ extern enum bst_result_t bst_result;
#define AICS_DESC_SIZE 0 #define AICS_DESC_SIZE 0
#endif /* CONFIG_BT_AICS */ #endif /* CONFIG_BT_AICS */
static struct bt_vcs *vcs;
static struct bt_vcs_included vcs_included; static struct bt_vcs_included vcs_included;
static volatile uint8_t g_volume; static volatile uint8_t g_volume;
@ -497,7 +498,7 @@ static void test_standalone(void)
vcs_param.cb = &vcs_cb; vcs_param.cb = &vcs_cb;
err = bt_vcs_register(&vcs_param); err = bt_vcs_register(&vcs_param, &vcs);
if (err) { if (err) {
FAIL("VCS register failed (err %d)\n", err); FAIL("VCS register failed (err %d)\n", err);
return; return;
@ -690,7 +691,7 @@ static void test_main(void)
vcs_param.cb = &vcs_cb; vcs_param.cb = &vcs_cb;
err = bt_vcs_register(&vcs_param); err = bt_vcs_register(&vcs_param, &vcs);
if (err) { if (err) {
FAIL("VCS register failed (err %d)\n", err); FAIL("VCS register failed (err %d)\n", err);
return; return;