From 9a16147edfd7033b88b0a0f1a716d7e1783cbee8 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Fri, 9 Aug 2024 15:44:16 +0200 Subject: [PATCH] nimble/audio/bass: Modify add source operation in BASS Fix memcpy wrong field format from address. Move check_bis_sync up, so add source can use it. Add checks for address type. Add checks for advertising sid. Add pa_sync_state and num of subgroups to receive state. --- .../services/bass/ble_audio_svc_bass.h | 3 + .../services/bass/src/ble_audio_svc_bass.c | 73 +++++++++++++------ 2 files changed, 53 insertions(+), 23 deletions(-) diff --git a/nimble/host/audio/services/bass/include/services/bass/ble_audio_svc_bass.h b/nimble/host/audio/services/bass/include/services/bass/ble_audio_svc_bass.h index 431ecb968..155df24a5 100644 --- a/nimble/host/audio/services/bass/include/services/bass/ble_audio_svc_bass.h +++ b/nimble/host/audio/services/bass/include/services/bass/ble_audio_svc_bass.h @@ -71,6 +71,9 @@ /** BLE AUDIO BASS Error: Invalid Source ID */ #define BLE_SVC_AUDIO_BASS_ERR_INVALID_SOURCE_ID 0x81 +/** BLE AUDIO BASS ADVERTISING SID MAX VALUE */ +#define BLE_SVC_AUDIO_BASS_ADV_SID_MAX_VAL 0x0F + /** BLE AUDIO BASS Encryption States */ enum ble_svc_audio_bass_big_enc { /** BLE AUDIO BASS BIG Encryption: Not Encrypted */ diff --git a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c index 1c4ff639e..99f384b3e 100644 --- a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c +++ b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c @@ -274,6 +274,28 @@ ble_svc_audio_bass_remote_scan_started(uint8_t *data, uint16_t data_len, uint16_ return 0; } +static int +check_bis_sync(uint16_t num_subgroups, const uint32_t *bis_sync_list) +{ + uint32_t bis_sync_mask = 0; + int i; + int j; + + for (i = 0; i < num_subgroups; i++) { + if (bis_sync_list[i] != 0xFFFFFFFF) { + for (j = 0; j < num_subgroups; j++) { + if (bis_sync_list[i] & bis_sync_mask) { + return BLE_HS_EINVAL; + } + + bis_sync_mask |= bis_sync_list[i]; + } + } + } + + return 0; +} + static int ble_svc_audio_bass_add_source(uint8_t *data, uint16_t data_len, uint16_t conn_handle) { @@ -299,9 +321,21 @@ ble_svc_audio_bass_add_source(uint8_t *data, uint16_t data_len, uint16_t conn_ha operation.conn_handle = conn_handle; operation.add_source.adv_addr.type = data[offset++]; + if (operation.add_source.adv_addr.type != BLE_ADDR_PUBLIC || + operation.add_source.adv_addr.type != BLE_ADDR_RANDOM) { + rc = BLE_HS_EINVAL; + ev.bass_operation_status.status = BLE_HS_EINVAL; + goto done; + } memcpy(operation.add_source.adv_addr.val, &data[offset], 6); offset += 6; operation.add_source.adv_sid = data[offset++]; + if (operation.add_source.adv_sid > BLE_SVC_AUDIO_BASS_ADV_SID_MAX_VAL) { + rc = BLE_HS_EINVAL; + ev.bass_operation_status.status = BLE_HS_EINVAL; + goto done; + } + operation.add_source.broadcast_id = get_le24(&data[offset]); offset += 3; operation.add_source.pa_sync = data[offset++]; @@ -338,6 +372,19 @@ ble_svc_audio_bass_add_source(uint8_t *data, uint16_t data_len, uint16_t conn_ha operation.add_source.subgroups[i].metadata = &data[offset]; offset += operation.add_source.subgroups[i].metadata_length; data_len -= operation.add_source.subgroups[i].metadata_length; + + if (check_bis_sync(operation.add_source.num_subgroups, + operation.add_source.bis_sync)) { + rc = BLE_HS_EINVAL; + ev.bass_operation_status.status = BLE_HS_EREJECT; + goto done; + } + + if (data_len != 0) { + rc = BLE_ATT_ERR_WRITE_REQ_REJECTED; + ev.bass_operation_status.status = BLE_HS_EREJECT; + goto done; + } } source_id_new = ble_svc_audio_bass_get_new_source_id(); @@ -385,9 +432,11 @@ ble_svc_audio_bass_add_source(uint8_t *data, uint16_t data_len, uint16_t conn_ha ev.bass_operation_status.source_id = rcv_state->source_id; rcv_state->state.source_addr.type = operation.add_source.adv_addr.type; - memcpy(&rcv_state->state.source_addr.type, operation.add_source.adv_addr.val, 6); + memcpy(&rcv_state->state.source_addr.val, operation.add_source.adv_addr.val, 6); rcv_state->state.source_adv_sid = operation.add_source.adv_sid; rcv_state->state.broadcast_id = operation.add_source.broadcast_id; + rcv_state->state.pa_sync_state = operation.add_source.pa_sync; + rcv_state->state.num_subgroups = operation.add_source.num_subgroups; for (i = 0; i < operation.add_source.num_subgroups; i++) { metadata_ptr = os_memblock_get(&ble_audio_svc_bass_metadata_pool); @@ -415,28 +464,6 @@ ble_svc_audio_bass_add_source(uint8_t *data, uint16_t data_len, uint16_t conn_ha return rc; } -static int -check_bis_sync(uint16_t num_subgroups, const uint32_t *bis_sync_list) -{ - uint32_t bis_sync_mask = 0; - int i; - int j; - - for (i = 0; i < num_subgroups; i++) { - if (bis_sync_list[i] != 0xFFFFFFFF) { - for (j = 0; j < num_subgroups; j++) { - if (bis_sync_list[i] & bis_sync_mask) { - return BLE_HS_EINVAL; - } - - bis_sync_mask |= bis_sync_list[i]; - } - } - } - - return 0; -} - static int ble_svc_audio_bass_modify_source(uint8_t *data, uint16_t data_len, uint16_t conn_handle) {