Skip to content

Commit 2248394

Browse files
Thalleycarlescufi
authored andcommitted
Bluetooth: Audio: Fix issues when setting new cfg values
Fix issues when setting new values in cfg that modify the length of the codec configuration LTV value. Signed-off-by: Emil Gydesen <[email protected]>
1 parent baec80f commit 2248394

File tree

2 files changed

+32
-14
lines changed

2 files changed

+32
-14
lines changed

subsys/bluetooth/audio/audio.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,17 @@ int bt_audio_data_parse(const uint8_t ltv[], size_t size,
3434
}
3535

3636
for (size_t i = 0; i < size;) {
37-
const uint8_t len = ltv[i++];
37+
const uint8_t len = ltv[i];
3838
struct bt_data data;
3939

4040
if (i + len > size || len < sizeof(data.type)) {
41-
LOG_DBG("Invalid len %u at i = %zu", len, i - 1);
41+
LOG_DBG("Invalid len %u at i = %zu", len, i);
4242

4343
return -EINVAL;
4444
}
4545

46+
i++; /* Increment as we have parsed the len field */
47+
4648
data.type = ltv[i++];
4749
data.data_len = len - sizeof(data.type);
4850

subsys/bluetooth/audio/codec.c

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -177,31 +177,41 @@ int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg, uint8_t typ
177177
}
178178

179179
for (uint16_t i = 0U; i < codec_cfg->data_len;) {
180-
const uint8_t len = codec_cfg->data[i++];
180+
uint8_t *len = &codec_cfg->data[i++];
181181
const uint8_t data_type = codec_cfg->data[i++];
182-
const uint8_t value_len = len - sizeof(data_type);
182+
const uint8_t value_len = *len - sizeof(data_type);
183183

184184
if (data_type == type) {
185185
uint8_t *value = &codec_cfg->data[i];
186186

187187
if (data_len == value_len) {
188188
memcpy(value, data, data_len);
189189
} else {
190-
const uint8_t *old_next_data_start = value + value_len + 1;
191-
const uint8_t data_len_to_move =
192-
codec_cfg->data_len -
193-
(old_next_data_start - codec_cfg->data);
194-
uint8_t *new_next_data_start = value + data_len + 1;
195190
const int16_t diff = data_len - value_len;
191+
uint8_t *old_next_data_start;
192+
uint8_t *new_next_data_start;
193+
uint8_t data_len_to_move;
194+
195+
/* Check if this is the last value in the buffer */
196+
if (value + value_len == codec_cfg->data + codec_cfg->data_len) {
197+
data_len_to_move = 0U;
198+
} else {
199+
old_next_data_start = value + value_len + 1;
200+
new_next_data_start = value + data_len + 1;
201+
data_len_to_move = codec_cfg->data_len -
202+
(old_next_data_start - codec_cfg->data);
203+
}
196204

197205
if (diff < 0) {
198206
/* In this case we need to move memory around after the copy
199207
* to fit the new shorter data
200208
*/
201209

202210
memcpy(value, data, data_len);
203-
memmove(new_next_data_start, old_next_data_start,
204-
data_len_to_move);
211+
if (data_len_to_move > 0U) {
212+
memmove(new_next_data_start, old_next_data_start,
213+
data_len_to_move);
214+
}
205215
} else {
206216
/* In this case we need to move memory around before
207217
* the copy to fit the new longer data
@@ -215,12 +225,16 @@ int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg, uint8_t typ
215225
return -ENOMEM;
216226
}
217227

218-
memmove(new_next_data_start, old_next_data_start,
219-
data_len_to_move);
228+
if (data_len_to_move > 0) {
229+
memmove(new_next_data_start, old_next_data_start,
230+
data_len_to_move);
231+
}
232+
220233
memcpy(value, data, data_len);
221234
}
222235

223236
codec_cfg->data_len += diff;
237+
*len += diff;
224238
}
225239

226240
return codec_cfg->data_len;
@@ -237,7 +251,9 @@ int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg, uint8_t typ
237251

238252
net_buf_simple_add_u8(&buf, data_len + sizeof(type));
239253
net_buf_simple_add_u8(&buf, type);
240-
net_buf_simple_add_mem(&buf, data, data_len);
254+
if (data_len > 0) {
255+
net_buf_simple_add_mem(&buf, data, data_len);
256+
}
241257
codec_cfg->data_len = buf.len;
242258
} else {
243259
LOG_DBG("Cannot fit data_len %zu in codec_cfg with len %u and size %u", data_len,

0 commit comments

Comments
 (0)