Bluetooth: micp_mic_dev: Retry sending notification on error

Retry sending notification was not sent due to e.g. lack of
buffers currently available.

Signed-off-by: Mariusz Skamra <mariusz.skamra@codecoup.pl>
This commit is contained in:
Mariusz Skamra 2023-08-10 10:48:27 +02:00 committed by Carles Cufí
commit 26110d5a1b
3 changed files with 42 additions and 3 deletions

View file

@ -31,6 +31,15 @@ config BT_AUDIO_TX
This hidden option is enabled when any of the profiles/services
enables support for transmitting of audio data.
config BT_AUDIO_NOTIFY_RETRY_DELAY
int "Delay for notification sending retried attempt in 1.25 ms units"
range 6 3200
default 20
help
This option sets the time in 1.25 ms units before the stack will
retry to send notification that failed due to lack of TX buffers
available.
config BT_CCID
bool
help

View file

@ -9,6 +9,8 @@
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/audio/audio.h>
#define BT_AUDIO_NOTIFY_RETRY_DELAY_US ((CONFIG_BT_AUDIO_NOTIFY_RETRY_DELAY) * 1250U)
/** @brief LE Audio Attribute User Data. */
struct bt_audio_attr_user_data {
/** Attribute read callback */

View file

@ -30,6 +30,7 @@ struct bt_micp_server {
struct bt_micp_mic_dev_cb *cb;
struct bt_gatt_service *service_p;
struct bt_aics *aics_insts[CONFIG_BT_MICP_MIC_DEV_AICS_INSTANCE_COUNT];
struct k_work_delayable notify_work;
};
static struct bt_micp_server micp_inst;
@ -49,6 +50,28 @@ static ssize_t read_mute(struct bt_conn *conn,
&micp_inst.mute, sizeof(micp_inst.mute));
}
static void notify_work_handler(struct k_work *work)
{
struct k_work_delayable *d_work = k_work_delayable_from_work(work);
struct bt_micp_server *server = CONTAINER_OF(d_work, struct bt_micp_server, notify_work);
int err;
err = bt_gatt_notify_uuid(NULL, BT_UUID_MICS_MUTE, server->service_p->attrs, &server->mute,
sizeof(server->mute));
if (err == 0 || err == -ENOTCONN) {
return;
}
if (err == -ENOMEM &&
k_work_reschedule(d_work, K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)) >= 0) {
LOG_WRN("Out of buffers for mute state notification. Will retry in %dms",
BT_AUDIO_NOTIFY_RETRY_DELAY_US);
return;
}
LOG_ERR("Mute state notification err %d", err);
}
static ssize_t write_mute(struct bt_conn *conn, const struct bt_gatt_attr *attr,
const void *buf, uint16_t len, uint16_t offset,
uint8_t flags)
@ -75,11 +98,14 @@ static ssize_t write_mute(struct bt_conn *conn, const struct bt_gatt_attr *attr,
LOG_DBG("%u", *val);
if (*val != micp_inst.mute) {
int err;
micp_inst.mute = *val;
bt_gatt_notify_uuid(NULL, BT_UUID_MICS_MUTE,
micp_inst.service_p->attrs,
&micp_inst.mute, sizeof(micp_inst.mute));
err = k_work_reschedule(&micp_inst.notify_work, K_NO_WAIT);
if (err < 0) {
LOG_ERR("Failed to schedule mute state notification err %d", err);
}
if (micp_inst.cb != NULL && micp_inst.cb->mute != NULL) {
micp_inst.cb->mute(micp_inst.mute);
@ -182,6 +208,8 @@ int bt_micp_mic_dev_register(struct bt_micp_mic_dev_register_param *param)
micp_inst.cb = param->cb;
k_work_init_delayable(&micp_inst.notify_work, notify_work_handler);
registered = true;
return err;