Bluetooth: AICS: Fix sonarcloud issues

Add missing else and refactored write_aics_control to
be less complex.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
Emil Gydesen 2025-05-16 16:30:59 +02:00 committed by Daniel DeGrasse
commit bf8570256f

View file

@ -214,6 +214,8 @@ static void notify(struct bt_aics *inst, enum bt_aics_notify notify, const struc
notify_work_reschedule(inst, notify, K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)); notify_work_reschedule(inst, notify, K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US));
} else if (err < 0 && err != -ENOTCONN) { } else if (err < 0 && err != -ENOTCONN) {
LOG_ERR("Notify %s err %d", aics_notify_str(notify), err); LOG_ERR("Notify %s err %d", aics_notify_str(notify), err);
} else {
/* Notification sent successfully */
} }
} }
@ -246,99 +248,160 @@ static void value_changed(struct bt_aics *inst, enum bt_aics_notify notify)
#define value_changed(...) #define value_changed(...)
#endif /* CONFIG_BT_AICS */ #endif /* CONFIG_BT_AICS */
static ssize_t write_aics_control(struct bt_conn *conn, static uint8_t valid_control_point_write(uint16_t len, uint16_t offset,
const struct bt_gatt_attr *attr, const struct bt_aics_gain_control *cp,
const void *buf, uint16_t len, uint8_t change_counter)
uint16_t offset, uint8_t flags)
{ {
struct bt_aics *inst = BT_AUDIO_CHRC_USER_DATA(attr); if (offset != 0) {
const struct bt_aics_gain_control *cp = buf; LOG_DBG("Invalid offset: %u", offset);
bool notify = false; return BT_ATT_ERR_INVALID_OFFSET;
if (offset) {
return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
} }
if (!len || !buf) { if (len == 0 || cp == NULL) {
return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); LOG_DBG("Invalid length (%u) or NULL data (%p)", len, cp);
return BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
} }
/* Check opcode before length */ /* Check opcode before length */
if (!VALID_AICS_OPCODE(cp->cp.opcode)) { if (!VALID_AICS_OPCODE(cp->cp.opcode)) {
LOG_DBG("Invalid opcode %u", cp->cp.opcode); LOG_DBG("Invalid opcode %u", cp->cp.opcode);
return BT_GATT_ERR(BT_AICS_ERR_OP_NOT_SUPPORTED); return BT_AICS_ERR_OP_NOT_SUPPORTED;
} }
if ((len < AICS_CP_LEN) || if ((len < AICS_CP_LEN) ||
(len == AICS_CP_SET_GAIN_LEN && cp->cp.opcode != BT_AICS_OPCODE_SET_GAIN) || (len == AICS_CP_SET_GAIN_LEN && cp->cp.opcode != BT_AICS_OPCODE_SET_GAIN) ||
(len > AICS_CP_SET_GAIN_LEN)) { (len > AICS_CP_SET_GAIN_LEN)) {
return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); LOG_DBG("Invalid length: %u", len);
return BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
} }
LOG_DBG("Opcode %u, counter %u", cp->cp.opcode, cp->cp.counter); LOG_DBG("Opcode %u, counter %u", cp->cp.opcode, cp->cp.counter);
if (cp->cp.counter != inst->srv.state.change_counter) { if (cp->cp.counter != change_counter) {
return BT_GATT_ERR(BT_AICS_ERR_INVALID_COUNTER); LOG_DBG("Invalid counter: %u != %u", cp->cp.counter, change_counter);
return BT_AICS_ERR_INVALID_COUNTER;
}
return BT_ATT_ERR_SUCCESS;
}
static uint8_t handle_set_gain_op(struct bt_aics *inst, const struct bt_aics_gain_control *cp,
bool *state_change)
{
LOG_DBG("Set gain %d", cp->gain_setting);
if (cp->gain_setting < inst->srv.gain_settings.minimum ||
cp->gain_setting > inst->srv.gain_settings.maximum) {
return BT_AICS_ERR_OUT_OF_RANGE;
}
if (BT_AICS_INPUT_MODE_SETTABLE(inst->srv.state.gain_mode) &&
inst->srv.state.gain != cp->gain_setting) {
inst->srv.state.gain = cp->gain_setting;
*state_change = true;
}
return BT_ATT_ERR_SUCCESS;
}
static uint8_t handle_unmute_op(struct bt_aics *inst, bool *state_change)
{
LOG_DBG("Unmute");
if (inst->srv.state.mute == BT_AICS_STATE_MUTE_DISABLED) {
return BT_AICS_ERR_MUTE_DISABLED;
}
if (inst->srv.state.mute != BT_AICS_STATE_UNMUTED) {
inst->srv.state.mute = BT_AICS_STATE_UNMUTED;
*state_change = true;
}
return BT_ATT_ERR_SUCCESS;
}
static uint8_t handle_mute_op(struct bt_aics *inst, bool *state_change)
{
LOG_DBG("Mute");
if (inst->srv.state.mute == BT_AICS_STATE_MUTE_DISABLED) {
return BT_AICS_ERR_MUTE_DISABLED;
}
if (inst->srv.state.mute != BT_AICS_STATE_MUTED) {
inst->srv.state.mute = BT_AICS_STATE_MUTED;
*state_change = true;
}
return BT_ATT_ERR_SUCCESS;
}
static uint8_t handle_set_manual_mode_op(struct bt_aics *inst, bool *state_change)
{
LOG_DBG("Set manual mode");
if (BT_AICS_INPUT_MODE_IMMUTABLE(inst->srv.state.gain_mode)) {
return BT_AICS_ERR_GAIN_MODE_NOT_ALLOWED;
}
if (inst->srv.state.gain_mode != BT_AICS_MODE_MANUAL) {
inst->srv.state.gain_mode = BT_AICS_MODE_MANUAL;
*state_change = true;
}
return BT_ATT_ERR_SUCCESS;
}
static uint8_t handle_set_automatic_mode_op(struct bt_aics *inst, bool *state_change)
{
LOG_DBG("Set automatic mode");
if (BT_AICS_INPUT_MODE_IMMUTABLE(inst->srv.state.gain_mode)) {
return BT_AICS_ERR_GAIN_MODE_NOT_ALLOWED;
}
if (inst->srv.state.gain_mode != BT_AICS_MODE_AUTO) {
inst->srv.state.gain_mode = BT_AICS_MODE_AUTO;
*state_change = true;
}
return BT_ATT_ERR_SUCCESS;
}
static ssize_t write_aics_control(struct bt_conn *conn, const struct bt_gatt_attr *attr,
const void *buf, uint16_t len, uint16_t offset, uint8_t flags)
{
struct bt_aics *inst = BT_AUDIO_CHRC_USER_DATA(attr);
const struct bt_aics_gain_control *cp = buf;
bool state_change = false;
int ret;
ret = valid_control_point_write(len, offset, cp, inst->srv.state.change_counter);
if (ret != BT_ATT_ERR_SUCCESS) {
return BT_GATT_ERR(ret);
} }
switch (cp->cp.opcode) { switch (cp->cp.opcode) {
case BT_AICS_OPCODE_SET_GAIN: case BT_AICS_OPCODE_SET_GAIN:
LOG_DBG("Set gain %d", cp->gain_setting); ret = handle_set_gain_op(inst, cp, &state_change);
if (cp->gain_setting < inst->srv.gain_settings.minimum ||
cp->gain_setting > inst->srv.gain_settings.maximum) {
return BT_GATT_ERR(BT_AICS_ERR_OUT_OF_RANGE);
}
if (BT_AICS_INPUT_MODE_SETTABLE(inst->srv.state.gain_mode) &&
inst->srv.state.gain != cp->gain_setting) {
inst->srv.state.gain = cp->gain_setting;
notify = true;
}
break; break;
case BT_AICS_OPCODE_UNMUTE: case BT_AICS_OPCODE_UNMUTE:
LOG_DBG("Unmute"); ret = handle_unmute_op(inst, &state_change);
if (inst->srv.state.mute == BT_AICS_STATE_MUTE_DISABLED) {
return BT_GATT_ERR(BT_AICS_ERR_MUTE_DISABLED);
}
if (inst->srv.state.mute != BT_AICS_STATE_UNMUTED) {
inst->srv.state.mute = BT_AICS_STATE_UNMUTED;
notify = true;
}
break; break;
case BT_AICS_OPCODE_MUTE: case BT_AICS_OPCODE_MUTE:
LOG_DBG("Mute"); ret = handle_mute_op(inst, &state_change);
if (inst->srv.state.mute == BT_AICS_STATE_MUTE_DISABLED) {
return BT_GATT_ERR(BT_AICS_ERR_MUTE_DISABLED);
}
if (inst->srv.state.mute != BT_AICS_STATE_MUTED) {
inst->srv.state.mute = BT_AICS_STATE_MUTED;
notify = true;
}
break; break;
case BT_AICS_OPCODE_SET_MANUAL: case BT_AICS_OPCODE_SET_MANUAL:
LOG_DBG("Set manual mode"); ret = handle_set_manual_mode_op(inst, &state_change);
if (BT_AICS_INPUT_MODE_IMMUTABLE(inst->srv.state.gain_mode)) {
return BT_GATT_ERR(BT_AICS_ERR_GAIN_MODE_NOT_ALLOWED);
}
if (inst->srv.state.gain_mode != BT_AICS_MODE_MANUAL) {
inst->srv.state.gain_mode = BT_AICS_MODE_MANUAL;
notify = true;
}
break; break;
case BT_AICS_OPCODE_SET_AUTO: case BT_AICS_OPCODE_SET_AUTO:
LOG_DBG("Set automatic mode"); ret = handle_set_automatic_mode_op(inst, &state_change);
if (BT_AICS_INPUT_MODE_IMMUTABLE(inst->srv.state.gain_mode)) {
return BT_GATT_ERR(BT_AICS_ERR_GAIN_MODE_NOT_ALLOWED);
}
if (inst->srv.state.gain_mode != BT_AICS_MODE_AUTO) {
inst->srv.state.gain_mode = BT_AICS_MODE_AUTO;
notify = true;
}
break; break;
default: default:
return BT_GATT_ERR(BT_AICS_ERR_OP_NOT_SUPPORTED); ret = BT_AICS_ERR_OP_NOT_SUPPORTED;
} }
if (notify) { if (ret != BT_ATT_ERR_SUCCESS) {
inst->srv.state.change_counter++; return BT_GATT_ERR(ret);
}
if (state_change) {
inst->srv.state.change_counter++; /* May overflow which is OK */
LOG_DBG("New state: gain %d, mute %u, gain_mode %u, counter %u", LOG_DBG("New state: gain %d, mute %u, gain_mode %u, counter %u",
inst->srv.state.gain, inst->srv.state.mute, inst->srv.state.gain_mode, inst->srv.state.gain, inst->srv.state.mute, inst->srv.state.gain_mode,