Bluetooth: Audio: Ensure that read callbacks can handle conn == NULL
The read callbacks may be called with conn == NULL if the device does a local read of the attributes. This commit ensures that all the read callbacks can handle the case where conn == NULL. Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
parent
6a0b1da158
commit
476e7b3fa3
4 changed files with 173 additions and 127 deletions
|
@ -126,6 +126,7 @@ int bt_pacs_conn_set_available_contexts_for_conn(struct bt_conn *conn, enum bt_a
|
|||
* @param dir Direction of the endpoints to get contexts for.
|
||||
*
|
||||
* @return Bitmask of available contexts.
|
||||
* @retval BT_AUDIO_CONTEXT_TYPE_PROHIBITED if @p conn or @p dir are invalid
|
||||
*/
|
||||
enum bt_audio_context bt_pacs_get_available_contexts_for_conn(struct bt_conn *conn,
|
||||
enum bt_audio_dir dir);
|
||||
|
|
|
@ -235,6 +235,10 @@ static int sirk_encrypt(struct bt_conn *conn,
|
|||
LOG_DBG("Encrypting test SIRK");
|
||||
k = test_k;
|
||||
} else {
|
||||
if (conn == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
k = conn->le.keys->ltk.val;
|
||||
}
|
||||
|
||||
|
|
|
@ -89,15 +89,18 @@ static ssize_t read_player_name(struct bt_conn *conn,
|
|||
const struct bt_gatt_attr *attr, void *buf,
|
||||
uint16_t len, uint16_t offset)
|
||||
{
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
const char *name = media_proxy_sctrl_get_player_name();
|
||||
|
||||
LOG_DBG("Player name read: %s (offset %u)", name, offset);
|
||||
|
||||
if (offset == 0) {
|
||||
atomic_clear_bit(client->flags, FLAG_PLAYER_NAME_CHANGED);
|
||||
} else if (atomic_test_bit(client->flags, FLAG_PLAYER_NAME_CHANGED)) {
|
||||
return BT_GATT_ERR(BT_MCS_ERR_LONG_VAL_CHANGED);
|
||||
if (conn != NULL) {
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
|
||||
if (offset == 0) {
|
||||
atomic_clear_bit(client->flags, FLAG_PLAYER_NAME_CHANGED);
|
||||
} else if (atomic_test_bit(client->flags, FLAG_PLAYER_NAME_CHANGED)) {
|
||||
return BT_GATT_ERR(BT_MCS_ERR_LONG_VAL_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, name,
|
||||
|
@ -131,15 +134,18 @@ static ssize_t read_icon_url(struct bt_conn *conn,
|
|||
const struct bt_gatt_attr *attr, void *buf,
|
||||
uint16_t len, uint16_t offset)
|
||||
{
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
const char *url = media_proxy_sctrl_get_icon_url();
|
||||
|
||||
LOG_DBG("Icon URL read, offset: %d, len:%d, URL: %s", offset, len, url);
|
||||
|
||||
if (offset == 0) {
|
||||
atomic_clear_bit(client->flags, FLAG_ICON_URL_CHANGED);
|
||||
} else if (atomic_test_bit(client->flags, FLAG_ICON_URL_CHANGED)) {
|
||||
return BT_GATT_ERR(BT_MCS_ERR_LONG_VAL_CHANGED);
|
||||
if (conn != NULL) {
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
|
||||
if (offset == 0) {
|
||||
atomic_clear_bit(client->flags, FLAG_ICON_URL_CHANGED);
|
||||
} else if (atomic_test_bit(client->flags, FLAG_ICON_URL_CHANGED)) {
|
||||
return BT_GATT_ERR(BT_MCS_ERR_LONG_VAL_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, url,
|
||||
|
@ -155,15 +161,18 @@ static ssize_t read_track_title(struct bt_conn *conn,
|
|||
const struct bt_gatt_attr *attr,
|
||||
void *buf, uint16_t len, uint16_t offset)
|
||||
{
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
const char *title = media_proxy_sctrl_get_track_title();
|
||||
|
||||
LOG_DBG("Track title read, offset: %d, len:%d, title: %s", offset, len, title);
|
||||
|
||||
if (offset == 0) {
|
||||
atomic_clear_bit(client->flags, FLAG_TRACK_TITLE_CHANGED);
|
||||
} else if (atomic_test_bit(client->flags, FLAG_TRACK_TITLE_CHANGED)) {
|
||||
return BT_GATT_ERR(BT_MCS_ERR_LONG_VAL_CHANGED);
|
||||
if (conn != NULL) {
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
|
||||
if (offset == 0) {
|
||||
atomic_clear_bit(client->flags, FLAG_TRACK_TITLE_CHANGED);
|
||||
} else if (atomic_test_bit(client->flags, FLAG_TRACK_TITLE_CHANGED)) {
|
||||
return BT_GATT_ERR(BT_MCS_ERR_LONG_VAL_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, title,
|
||||
|
@ -180,35 +189,38 @@ static ssize_t read_track_duration(struct bt_conn *conn,
|
|||
const struct bt_gatt_attr *attr, void *buf,
|
||||
uint16_t len, uint16_t offset)
|
||||
{
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
int32_t duration = media_proxy_sctrl_get_track_duration();
|
||||
int32_t duration_le = sys_cpu_to_le32(duration);
|
||||
|
||||
LOG_DBG("Track duration read: %d (0x%08x)", duration, duration);
|
||||
|
||||
atomic_clear_bit(client->flags, FLAG_TRACK_DURATION_CHANGED);
|
||||
if (conn != NULL) {
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
|
||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, &duration_le,
|
||||
sizeof(duration_le));
|
||||
atomic_clear_bit(client->flags, FLAG_TRACK_DURATION_CHANGED);
|
||||
}
|
||||
|
||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, &duration_le, sizeof(duration_le));
|
||||
}
|
||||
|
||||
static void track_duration_cfg_changed(const struct bt_gatt_attr *attr,
|
||||
uint16_t value)
|
||||
static void track_duration_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
|
||||
{
|
||||
LOG_DBG("value 0x%04x", value);
|
||||
}
|
||||
|
||||
static ssize_t read_track_position(struct bt_conn *conn,
|
||||
const struct bt_gatt_attr *attr, void *buf,
|
||||
static ssize_t read_track_position(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf,
|
||||
uint16_t len, uint16_t offset)
|
||||
{
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
int32_t position = media_proxy_sctrl_get_track_position();
|
||||
int32_t position_le = sys_cpu_to_le32(position);
|
||||
|
||||
LOG_DBG("Track position read: %d (0x%08x)", position, position);
|
||||
|
||||
atomic_clear_bit(client->flags, FLAG_TRACK_POSITION_CHANGED);
|
||||
if (conn != NULL) {
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
|
||||
atomic_clear_bit(client->flags, FLAG_TRACK_POSITION_CHANGED);
|
||||
}
|
||||
|
||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, &position_le,
|
||||
sizeof(position_le));
|
||||
|
@ -248,21 +260,21 @@ static ssize_t read_playback_speed(struct bt_conn *conn,
|
|||
const struct bt_gatt_attr *attr, void *buf,
|
||||
uint16_t len, uint16_t offset)
|
||||
{
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
int8_t speed = media_proxy_sctrl_get_playback_speed();
|
||||
|
||||
LOG_DBG("Playback speed read: %d", speed);
|
||||
|
||||
atomic_clear_bit(client->flags, FLAG_PLAYBACK_SPEED_CHANGED);
|
||||
if (conn != NULL) {
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
|
||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, &speed,
|
||||
sizeof(speed));
|
||||
atomic_clear_bit(client->flags, FLAG_PLAYBACK_SPEED_CHANGED);
|
||||
}
|
||||
|
||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, &speed, sizeof(speed));
|
||||
}
|
||||
|
||||
static ssize_t write_playback_speed(struct bt_conn *conn,
|
||||
const struct bt_gatt_attr *attr,
|
||||
const void *buf, uint16_t len, uint16_t offset,
|
||||
uint8_t flags)
|
||||
static ssize_t write_playback_speed(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||
const void *buf, uint16_t len, uint16_t offset, uint8_t flags)
|
||||
{
|
||||
int8_t speed;
|
||||
|
||||
|
@ -282,22 +294,23 @@ static ssize_t write_playback_speed(struct bt_conn *conn,
|
|||
return len;
|
||||
}
|
||||
|
||||
static void playback_speed_cfg_changed(const struct bt_gatt_attr *attr,
|
||||
uint16_t value)
|
||||
static void playback_speed_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
|
||||
{
|
||||
LOG_DBG("value 0x%04x", value);
|
||||
}
|
||||
|
||||
static ssize_t read_seeking_speed(struct bt_conn *conn,
|
||||
const struct bt_gatt_attr *attr, void *buf,
|
||||
static ssize_t read_seeking_speed(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf,
|
||||
uint16_t len, uint16_t offset)
|
||||
{
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
int8_t speed = media_proxy_sctrl_get_seeking_speed();
|
||||
|
||||
LOG_DBG("Seeking speed read: %d", speed);
|
||||
|
||||
atomic_clear_bit(client->flags, FLAG_SEEKING_SPEED_CHANGED);
|
||||
if (conn != NULL) {
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
|
||||
atomic_clear_bit(client->flags, FLAG_SEEKING_SPEED_CHANGED);
|
||||
}
|
||||
|
||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, &speed,
|
||||
sizeof(speed));
|
||||
|
@ -329,7 +342,6 @@ static ssize_t read_current_track_id(struct bt_conn *conn,
|
|||
const struct bt_gatt_attr *attr, void *buf,
|
||||
uint16_t len, uint16_t offset)
|
||||
{
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
uint64_t track_id = media_proxy_sctrl_get_current_track_id();
|
||||
uint8_t track_id_le[BT_OTS_OBJ_ID_SIZE];
|
||||
|
||||
|
@ -337,7 +349,11 @@ static ssize_t read_current_track_id(struct bt_conn *conn,
|
|||
|
||||
LOG_DBG_OBJ_ID("Current track ID read: ", track_id);
|
||||
|
||||
atomic_clear_bit(client->flags, FLAG_CURRENT_TRACK_OBJ_ID_CHANGED);
|
||||
if (conn != NULL) {
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
|
||||
atomic_clear_bit(client->flags, FLAG_CURRENT_TRACK_OBJ_ID_CHANGED);
|
||||
}
|
||||
|
||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, track_id_le,
|
||||
sizeof(track_id_le));
|
||||
|
@ -383,13 +399,16 @@ static ssize_t read_next_track_id(struct bt_conn *conn,
|
|||
const struct bt_gatt_attr *attr, void *buf,
|
||||
uint16_t len, uint16_t offset)
|
||||
{
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
uint64_t track_id = media_proxy_sctrl_get_next_track_id();
|
||||
uint8_t track_id_le[BT_OTS_OBJ_ID_SIZE];
|
||||
|
||||
sys_put_le48(track_id, track_id_le);
|
||||
|
||||
atomic_clear_bit(client->flags, FLAG_NEXT_TRACK_OBJ_ID_CHANGED);
|
||||
if (conn != NULL) {
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
|
||||
atomic_clear_bit(client->flags, FLAG_NEXT_TRACK_OBJ_ID_CHANGED);
|
||||
}
|
||||
|
||||
if (track_id == MPL_NO_TRACK_ID) {
|
||||
LOG_DBG("Next track read, but it is empty");
|
||||
|
@ -443,7 +462,6 @@ static ssize_t read_parent_group_id(struct bt_conn *conn,
|
|||
const struct bt_gatt_attr *attr, void *buf,
|
||||
uint16_t len, uint16_t offset)
|
||||
{
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
uint64_t group_id = media_proxy_sctrl_get_parent_group_id();
|
||||
uint8_t group_id_le[BT_OTS_OBJ_ID_SIZE];
|
||||
|
||||
|
@ -451,7 +469,11 @@ static ssize_t read_parent_group_id(struct bt_conn *conn,
|
|||
|
||||
LOG_DBG_OBJ_ID("Parent group read: ", group_id);
|
||||
|
||||
atomic_clear_bit(client->flags, FLAG_PARENT_GROUP_OBJ_ID_CHANGED);
|
||||
if (conn != NULL) {
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
|
||||
atomic_clear_bit(client->flags, FLAG_PARENT_GROUP_OBJ_ID_CHANGED);
|
||||
}
|
||||
|
||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, group_id_le,
|
||||
sizeof(group_id_le));
|
||||
|
@ -467,7 +489,6 @@ static ssize_t read_current_group_id(struct bt_conn *conn,
|
|||
const struct bt_gatt_attr *attr, void *buf,
|
||||
uint16_t len, uint16_t offset)
|
||||
{
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
uint64_t group_id = media_proxy_sctrl_get_current_group_id();
|
||||
uint8_t group_id_le[BT_OTS_OBJ_ID_SIZE];
|
||||
|
||||
|
@ -475,7 +496,11 @@ static ssize_t read_current_group_id(struct bt_conn *conn,
|
|||
|
||||
LOG_DBG_OBJ_ID("Current group read: ", group_id);
|
||||
|
||||
atomic_clear_bit(client->flags, FLAG_CURRENT_GROUP_OBJ_ID_CHANGED);
|
||||
if (conn != NULL) {
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
|
||||
atomic_clear_bit(client->flags, FLAG_CURRENT_GROUP_OBJ_ID_CHANGED);
|
||||
}
|
||||
|
||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, group_id_le,
|
||||
sizeof(group_id_le));
|
||||
|
@ -522,21 +547,21 @@ static ssize_t read_playing_order(struct bt_conn *conn,
|
|||
const struct bt_gatt_attr *attr, void *buf,
|
||||
uint16_t len, uint16_t offset)
|
||||
{
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
uint8_t order = media_proxy_sctrl_get_playing_order();
|
||||
|
||||
LOG_DBG("Playing order read: %d (0x%02x)", order, order);
|
||||
|
||||
atomic_clear_bit(client->flags, FLAG_PLAYING_ORDER_CHANGED);
|
||||
if (conn != NULL) {
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
|
||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, &order,
|
||||
sizeof(order));
|
||||
atomic_clear_bit(client->flags, FLAG_PLAYING_ORDER_CHANGED);
|
||||
}
|
||||
|
||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, &order, sizeof(order));
|
||||
}
|
||||
|
||||
static ssize_t write_playing_order(struct bt_conn *conn,
|
||||
const struct bt_gatt_attr *attr,
|
||||
const void *buf, uint16_t len, uint16_t offset,
|
||||
uint8_t flags)
|
||||
static ssize_t write_playing_order(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||
const void *buf, uint16_t len, uint16_t offset, uint8_t flags)
|
||||
{
|
||||
LOG_DBG("Playing order write");
|
||||
|
||||
|
@ -558,14 +583,12 @@ static ssize_t write_playing_order(struct bt_conn *conn,
|
|||
return len;
|
||||
}
|
||||
|
||||
static void playing_order_cfg_changed(const struct bt_gatt_attr *attr,
|
||||
uint16_t value)
|
||||
static void playing_order_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
|
||||
{
|
||||
LOG_DBG("value 0x%04x", value);
|
||||
}
|
||||
|
||||
static ssize_t read_playing_orders_supported(struct bt_conn *conn,
|
||||
const struct bt_gatt_attr *attr,
|
||||
static ssize_t read_playing_orders_supported(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||
void *buf, uint16_t len, uint16_t offset)
|
||||
{
|
||||
uint16_t orders = media_proxy_sctrl_get_playing_orders_supported();
|
||||
|
@ -573,20 +596,21 @@ static ssize_t read_playing_orders_supported(struct bt_conn *conn,
|
|||
|
||||
LOG_DBG("Playing orders read: %d (0x%04x)", orders, orders);
|
||||
|
||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, &orders_le,
|
||||
sizeof(orders_le));
|
||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, &orders_le, sizeof(orders_le));
|
||||
}
|
||||
|
||||
static ssize_t read_media_state(struct bt_conn *conn,
|
||||
const struct bt_gatt_attr *attr, void *buf,
|
||||
static ssize_t read_media_state(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf,
|
||||
uint16_t len, uint16_t offset)
|
||||
{
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
uint8_t state = media_proxy_sctrl_get_media_state();
|
||||
|
||||
LOG_DBG("Media state read: %d", state);
|
||||
|
||||
atomic_clear_bit(client->flags, FLAG_MEDIA_STATE_CHANGED);
|
||||
if (conn != NULL) {
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
|
||||
atomic_clear_bit(client->flags, FLAG_MEDIA_STATE_CHANGED);
|
||||
}
|
||||
|
||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, &state,
|
||||
sizeof(state));
|
||||
|
@ -603,7 +627,6 @@ static ssize_t write_control_point(struct bt_conn *conn,
|
|||
const void *buf, uint16_t len, uint16_t offset,
|
||||
uint8_t flags)
|
||||
{
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
struct mpl_cmd command;
|
||||
|
||||
if (offset != 0) {
|
||||
|
@ -632,17 +655,23 @@ static ssize_t write_control_point(struct bt_conn *conn,
|
|||
notify(BT_UUID_MCS_MEDIA_CONTROL_POINT, &cmd_ntf, sizeof(cmd_ntf));
|
||||
|
||||
return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
|
||||
} else if (atomic_test_and_set_bit(client->flags, FLAG_MEDIA_CONTROL_POINT_BUSY)) {
|
||||
const struct mpl_cmd_ntf cmd_ntf = {
|
||||
.requested_opcode = command.opcode,
|
||||
.result_code = BT_MCS_OPC_NTF_CANNOT_BE_COMPLETED,
|
||||
};
|
||||
}
|
||||
|
||||
LOG_DBG("Busy with other operation");
|
||||
if (conn != NULL) {
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
|
||||
notify(BT_UUID_MCS_MEDIA_CONTROL_POINT, &cmd_ntf, sizeof(cmd_ntf));
|
||||
if (atomic_test_and_set_bit(client->flags, FLAG_MEDIA_CONTROL_POINT_BUSY)) {
|
||||
const struct mpl_cmd_ntf cmd_ntf = {
|
||||
.requested_opcode = command.opcode,
|
||||
.result_code = BT_MCS_OPC_NTF_CANNOT_BE_COMPLETED,
|
||||
};
|
||||
|
||||
return BT_GATT_ERR(BT_ATT_ERR_PROCEDURE_IN_PROGRESS);
|
||||
LOG_DBG("Busy with other operation");
|
||||
|
||||
notify(BT_UUID_MCS_MEDIA_CONTROL_POINT, &cmd_ntf, sizeof(cmd_ntf));
|
||||
|
||||
return BT_GATT_ERR(BT_ATT_ERR_PROCEDURE_IN_PROGRESS);
|
||||
}
|
||||
}
|
||||
|
||||
if (len == sizeof(command.opcode) + sizeof(command.param)) {
|
||||
|
@ -666,31 +695,30 @@ static ssize_t read_opcodes_supported(struct bt_conn *conn,
|
|||
const struct bt_gatt_attr *attr,
|
||||
void *buf, uint16_t len, uint16_t offset)
|
||||
{
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
uint32_t opcodes = media_proxy_sctrl_get_commands_supported();
|
||||
uint32_t opcodes_le = sys_cpu_to_le32(opcodes);
|
||||
|
||||
LOG_DBG("Opcodes_supported read: %d (0x%08x)", opcodes, opcodes);
|
||||
|
||||
atomic_clear_bit(client->flags, FLAG_MEDIA_CONTROL_OPCODES_CHANGED);
|
||||
if (conn != NULL) {
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
|
||||
return bt_gatt_attr_read(conn, attr, buf, len, offset,
|
||||
&opcodes_le, sizeof(opcodes_le));
|
||||
atomic_clear_bit(client->flags, FLAG_MEDIA_CONTROL_OPCODES_CHANGED);
|
||||
}
|
||||
|
||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, &opcodes_le, sizeof(opcodes_le));
|
||||
}
|
||||
|
||||
static void opcodes_supported_cfg_changed(const struct bt_gatt_attr *attr,
|
||||
uint16_t value)
|
||||
static void opcodes_supported_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
|
||||
{
|
||||
LOG_DBG("value 0x%04x", value);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BT_OTS
|
||||
static ssize_t write_search_control_point(struct bt_conn *conn,
|
||||
const struct bt_gatt_attr *attr,
|
||||
const void *buf, uint16_t len,
|
||||
uint16_t offset, uint8_t flags)
|
||||
static ssize_t write_search_control_point(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||
const void *buf, uint16_t len, uint16_t offset,
|
||||
uint8_t flags)
|
||||
{
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
struct mpl_search search = {0};
|
||||
|
||||
if (offset != 0) {
|
||||
|
@ -701,14 +729,18 @@ static ssize_t write_search_control_point(struct bt_conn *conn,
|
|||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
|
||||
}
|
||||
|
||||
if (atomic_test_and_set_bit(client->flags, FLAG_SEARCH_CONTROL_POINT_BUSY)) {
|
||||
const uint8_t result_code = BT_MCS_SCP_NTF_FAILURE;
|
||||
if (conn != NULL) {
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
|
||||
LOG_DBG("Busy with other operation");
|
||||
if (atomic_test_and_set_bit(client->flags, FLAG_SEARCH_CONTROL_POINT_BUSY)) {
|
||||
const uint8_t result_code = BT_MCS_SCP_NTF_FAILURE;
|
||||
|
||||
notify(BT_UUID_MCS_SEARCH_CONTROL_POINT, &result_code, sizeof(result_code));
|
||||
LOG_DBG("Busy with other operation");
|
||||
|
||||
return BT_GATT_ERR(BT_ATT_ERR_PROCEDURE_IN_PROGRESS);
|
||||
notify(BT_UUID_MCS_SEARCH_CONTROL_POINT, &result_code, sizeof(result_code));
|
||||
|
||||
return BT_GATT_ERR(BT_ATT_ERR_PROCEDURE_IN_PROGRESS);
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(&search.search, (char *)buf, len);
|
||||
|
@ -731,12 +763,15 @@ static ssize_t read_search_results_id(struct bt_conn *conn,
|
|||
const struct bt_gatt_attr *attr,
|
||||
void *buf, uint16_t len, uint16_t offset)
|
||||
{
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
uint64_t search_id = media_proxy_sctrl_get_search_results_id();
|
||||
|
||||
LOG_DBG_OBJ_ID("Search results id read: ", search_id);
|
||||
|
||||
atomic_clear_bit(client->flags, FLAG_SEARCH_RESULTS_OBJ_ID_CHANGED);
|
||||
if (conn != NULL) {
|
||||
struct client_state *client = &clients[bt_conn_index(conn)];
|
||||
|
||||
atomic_clear_bit(client->flags, FLAG_SEARCH_RESULTS_OBJ_ID_CHANGED);
|
||||
}
|
||||
|
||||
/* TODO: The permanent solution here should be that the call to */
|
||||
/* mpl should fill the UUID in a pointed-to value, and return a */
|
||||
|
|
|
@ -199,15 +199,46 @@ static void available_context_cfg_changed(const struct bt_gatt_attr *attr, uint1
|
|||
LOG_DBG("attr %p value 0x%04x", attr, value);
|
||||
}
|
||||
|
||||
static enum bt_audio_context pacs_get_available_contexts_for_conn(struct bt_conn *conn,
|
||||
enum bt_audio_dir dir)
|
||||
{
|
||||
const struct pacs_client *client;
|
||||
|
||||
client = client_lookup_conn(conn);
|
||||
if (client == NULL) {
|
||||
LOG_DBG("No client context for conn %p", (void *)conn);
|
||||
return bt_pacs_get_available_contexts(dir);
|
||||
}
|
||||
|
||||
switch (dir) {
|
||||
case BT_AUDIO_DIR_SINK:
|
||||
#if defined(CONFIG_BT_PAC_SNK)
|
||||
if (client->snk_available_contexts != NULL) {
|
||||
return POINTER_TO_UINT(client->snk_available_contexts);
|
||||
}
|
||||
#endif /* CONFIG_BT_PAC_SNK */
|
||||
break;
|
||||
case BT_AUDIO_DIR_SOURCE:
|
||||
#if defined(CONFIG_BT_PAC_SRC)
|
||||
if (client->src_available_contexts != NULL) {
|
||||
return POINTER_TO_UINT(client->src_available_contexts);
|
||||
}
|
||||
#endif /* CONFIG_BT_PAC_SRC */
|
||||
break;
|
||||
}
|
||||
|
||||
return bt_pacs_get_available_contexts(dir);
|
||||
}
|
||||
|
||||
static ssize_t available_contexts_read(struct bt_conn *conn,
|
||||
const struct bt_gatt_attr *attr, void *buf,
|
||||
uint16_t len, uint16_t offset)
|
||||
{
|
||||
struct bt_pacs_context context = {
|
||||
.snk = sys_cpu_to_le16(
|
||||
bt_pacs_get_available_contexts_for_conn(conn, BT_AUDIO_DIR_SINK)),
|
||||
pacs_get_available_contexts_for_conn(conn, BT_AUDIO_DIR_SINK)),
|
||||
.src = sys_cpu_to_le16(
|
||||
bt_pacs_get_available_contexts_for_conn(conn, BT_AUDIO_DIR_SOURCE)),
|
||||
pacs_get_available_contexts_for_conn(conn, BT_AUDIO_DIR_SOURCE)),
|
||||
};
|
||||
|
||||
LOG_DBG("conn %p attr %p buf %p len %u offset %u", conn, attr, buf, len, offset);
|
||||
|
@ -718,9 +749,9 @@ static int available_contexts_notify(struct bt_conn *conn)
|
|||
{
|
||||
struct bt_pacs_context context = {
|
||||
.snk = sys_cpu_to_le16(
|
||||
bt_pacs_get_available_contexts_for_conn(conn, BT_AUDIO_DIR_SINK)),
|
||||
pacs_get_available_contexts_for_conn(conn, BT_AUDIO_DIR_SINK)),
|
||||
.src = sys_cpu_to_le16(
|
||||
bt_pacs_get_available_contexts_for_conn(conn, BT_AUDIO_DIR_SOURCE)),
|
||||
pacs_get_available_contexts_for_conn(conn, BT_AUDIO_DIR_SOURCE)),
|
||||
};
|
||||
int err;
|
||||
|
||||
|
@ -971,7 +1002,7 @@ static void pacs_disconnected(struct bt_conn *conn, uint8_t reason)
|
|||
uint16_t new;
|
||||
|
||||
client->snk_available_contexts = NULL;
|
||||
new = bt_pacs_get_available_contexts_for_conn(conn, BT_AUDIO_DIR_SINK);
|
||||
new = pacs_get_available_contexts_for_conn(conn, BT_AUDIO_DIR_SINK);
|
||||
|
||||
atomic_set_bit_to(client->flags, FLAG_AVAILABLE_AUDIO_CONTEXT_CHANGED, old != new);
|
||||
}
|
||||
|
@ -983,7 +1014,7 @@ static void pacs_disconnected(struct bt_conn *conn, uint8_t reason)
|
|||
uint16_t new;
|
||||
|
||||
client->src_available_contexts = NULL;
|
||||
new = bt_pacs_get_available_contexts_for_conn(conn, BT_AUDIO_DIR_SOURCE);
|
||||
new = pacs_get_available_contexts_for_conn(conn, BT_AUDIO_DIR_SOURCE);
|
||||
|
||||
atomic_set_bit_to(client->flags, FLAG_AVAILABLE_AUDIO_CONTEXT_CHANGED, old != new);
|
||||
}
|
||||
|
@ -1152,7 +1183,7 @@ int bt_pacs_set_available_contexts(enum bt_audio_dir dir, enum bt_audio_context
|
|||
int bt_pacs_conn_set_available_contexts_for_conn(struct bt_conn *conn, enum bt_audio_dir dir,
|
||||
enum bt_audio_context *contexts)
|
||||
{
|
||||
enum bt_audio_context old = bt_pacs_get_available_contexts_for_conn(conn, dir);
|
||||
enum bt_audio_context old = pacs_get_available_contexts_for_conn(conn, dir);
|
||||
struct bt_conn_info info = { 0 };
|
||||
struct pacs_client *client;
|
||||
int err;
|
||||
|
@ -1193,7 +1224,7 @@ int bt_pacs_conn_set_available_contexts_for_conn(struct bt_conn *conn, enum bt_a
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bt_pacs_get_available_contexts_for_conn(conn, dir) == old) {
|
||||
if (pacs_get_available_contexts_for_conn(conn, dir) == old) {
|
||||
/* No change. Skip notification */
|
||||
return 0;
|
||||
}
|
||||
|
@ -1254,35 +1285,10 @@ enum bt_audio_context bt_pacs_get_available_contexts(enum bt_audio_dir dir)
|
|||
enum bt_audio_context bt_pacs_get_available_contexts_for_conn(struct bt_conn *conn,
|
||||
enum bt_audio_dir dir)
|
||||
{
|
||||
const struct pacs_client *client;
|
||||
|
||||
CHECKIF(conn == NULL) {
|
||||
LOG_ERR("NULL conn");
|
||||
return -EINVAL;
|
||||
return BT_AUDIO_CONTEXT_TYPE_PROHIBITED;
|
||||
}
|
||||
|
||||
client = client_lookup_conn(conn);
|
||||
if (client == NULL) {
|
||||
LOG_ERR("No client context for conn %p", (void *)conn);
|
||||
return bt_pacs_get_available_contexts(dir);
|
||||
}
|
||||
|
||||
switch (dir) {
|
||||
case BT_AUDIO_DIR_SINK:
|
||||
#if defined(CONFIG_BT_PAC_SNK)
|
||||
if (client->snk_available_contexts != NULL) {
|
||||
return POINTER_TO_UINT(client->snk_available_contexts);
|
||||
}
|
||||
#endif /* CONFIG_BT_PAC_SNK */
|
||||
break;
|
||||
case BT_AUDIO_DIR_SOURCE:
|
||||
#if defined(CONFIG_BT_PAC_SRC)
|
||||
if (client->src_available_contexts != NULL) {
|
||||
return POINTER_TO_UINT(client->src_available_contexts);
|
||||
}
|
||||
#endif /* CONFIG_BT_PAC_SRC */
|
||||
break;
|
||||
}
|
||||
|
||||
return bt_pacs_get_available_contexts(dir);
|
||||
return pacs_get_available_contexts_for_conn(conn, dir);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue