From e68a3adaba3c56f3d2f3f3ec61c950bc0aab3807 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Mon, 15 Apr 2024 14:56:19 +0200 Subject: [PATCH 1/3] [WIP][DNM] Initial commit adding BASS in bttester Adding BASS support in bttester --- .gdb_out | 156 +++++++++++++++++++++++++++++++ apps/bttester/pkg.yml | 1 + apps/bttester/src/btp/btp.h | 1 + apps/bttester/src/btp/btp_bass.h | 37 ++++++++ apps/bttester/src/btp/btp_gap.h | 10 ++ apps/bttester/src/btp/bttester.h | 7 +- apps/bttester/src/btp_bass.c | 77 +++++++++++++++ apps/bttester/src/btp_core.c | 2 +- apps/bttester/src/btp_gap.c | 46 +++++++++ apps/bttester/syscfg.yml | 4 +- 10 files changed, 337 insertions(+), 4 deletions(-) create mode 100644 .gdb_out create mode 100644 apps/bttester/src/btp/btp_bass.h create mode 100644 apps/bttester/src/btp_bass.c diff --git a/.gdb_out b/.gdb_out new file mode 100644 index 0000000000..079f1e514f --- /dev/null +++ b/.gdb_out @@ -0,0 +1,156 @@ +GNU gdb (Arm GNU Toolchain 12.2.Rel1 (Build arm-12.24)) 12.1.90.20221210-git +Copyright (C) 2022 Free Software Foundation, Inc. +License GPLv3+: GNU GPL version 3 or later +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. +Type "show copying" and "show warranty" for details. +This GDB was configured as "--host=i686-w64-mingw32 --target=arm-none-eabi". +Type "show configuration" for configuration details. +For bug reporting instructions, please see: +. +Find the GDB manual and other documentation resources online at: + . + +For help, type "help". +Type "apropos word" to search for commands related to "word". +SEGGER J-Link GDB Server V7.96 Command Line Version + +JLinkARM.dll V7.96 (DLL compiled Mar 7 2024 16:49:04) + +Command line: -device nrf52840_xxaa -speed 1000 -if SWD -port 3333 -singlerun +-----GDB Server start settings----- +GDBInit file: none +GDB Server Listening port: 3333 +SWO raw output listening port: 2332 +Terminal I/O port: 2333 +Accept remote connection: localhost only +Generate logfile: off +Verify download: off +Init regs on start: off +Silent mode: off +Single run mode: on +Target connection timeout: 0 ms +------J-Link related settings------ +J-Link Host interface: USB +J-Link script: none +J-Link settings file: none +------Target related settings------ +Target device: nrf52840_xxaa +Target device parameters: none +Target interface: SWD +Target interface speed: 1000kHz +Target endian: little + +Connecting to J-Link... +J-Link is connected. +Firmware: J-Link OB-SAM3U128-V2-NordicSemi compiled Oct 30 2023 12:12:17 +Hardware: V1.00 +S/N: 683403725 +Feature(s): RDI, FlashBP, FlashDL, JFlash, GDB +Checking target voltage... +Target voltage: 3.30 V +Listening on TCP/IP port 3333 +Connecting to target... +Halting core... +Connected to target +Waiting for GDB connection...Connected to 0000:0000:0000:0000:0000:0000:0000:0001 +GDB client (conn. 888) requested target.xml from GDB Server +warning: No executable has been specified and target does not support +determining executable automatically. Try using the "file" command. +Reading common registers: Read register 'r0' (4 bytes) from hardware: 0xFF7F0000 +Read register 'r1' (4 bytes) from hardware: 0x01010600 +Read register 'r2' (4 bytes) from hardware: 0x00010600 +Read register 'r3' (4 bytes) from hardware: 0x00100140 +Read register 'r4' (4 bytes) from hardware: 0x80000000 +Read register 'r5' (4 bytes) from hardware: 0x80000000 +Read register 'r6' (4 bytes) from hardware: 0x00000000 +Read register 'r7' (4 bytes) from hardware: 0x01060000 +Read register 'r8' (4 bytes) from hardware: 0x00000000 +Read register 'r9' (4 bytes) from hardware: 0x40000000 +Read register 'r10' (4 bytes) from hardware: 0x00000000 +Read register 'r11' (4 bytes) from hardware: 0x00000000 +Read register 'r12' (4 bytes) from hardware: 0x00000000 +Read register 'sp' (4 bytes) from hardware: 0x00DA0020 +Read register 'lr' (4 bytes) from hardware: 0x19FE0400 +Read register 'pc' (4 bytes) from hardware: 0xA0FE0400 +Read register 'xpsr' (4 bytes) from hardware: 0x00000021 +Read 4 bytes @ address 0x0004FEA0 (Data = 0xBD38B954) +Read 2 bytes @ address 0x0004FEA0 (Data = 0xB954) +0x0004fea0 in ?? () +Received monitor command: reset +Resetting target +Resetting target +Downloading 16000 bytes @ address 0x0000C000 +Downloading 15968 bytes @ address 0x0000FE80 +Downloading 16000 bytes @ address 0x00013CE0 +Downloading 16096 bytes @ address 0x00017B60 +Downloading 16048 bytes @ address 0x0001BA40 +Downloading 15824 bytes @ address 0x0001F8F0 +Downloading 16160 bytes @ address 0x000236C0 +Downloading 16064 bytes @ address 0x000275E0 +Downloading 16096 bytes @ address 0x0002B4A0 +Downloading 16048 bytes @ address 0x0002F380 +Downloading 16096 bytes @ address 0x00033230 +Downloading 16048 bytes @ address 0x00037110 +Downloading 16016 bytes @ address 0x0003AFC0 +Downloading 16016 bytes @ address 0x0003EE50 +Downloading 16064 bytes @ address 0x00042CE0 +Downloading 15936 bytes @ address 0x00046BA0 +Downloading 15952 bytes @ address 0x0004A9E0 +Downloading 16128 bytes @ address 0x0004E830 +Downloading 11416 bytes @ address 0x00052730 +Restoring binary file ..\..\bin\targets\bttester\app\@apache-mynewt-nimble\apps\bttester\bttester.img into memory (0xc000 to 0x553c8) +Reading register 'msp' = 0x20040000 +Reading register 'psp' = 0x00000000 +Reading register 'primask' = 0x00000000 +Reading register 'basepri' = 0x00000000 +Reading register 'faultmask' = 0x00000000 +Reading register 'control' = 0x00000000 +Reading register 'apsr' = 0x00000000 +Reading register 'epsr' = 0x01000000 +Reading register 'ipsr' = 0x00000000 +Reading register 'iapsr' = 0x00000000 +Reading register 'eapsr' = 0x01000000 +Reading register 'iepsr' = 0x01000000 +Reading register 'fpscr' = 0x00000000 +r0 0x7fff 32767 +r1 0x60101 393473 +r2 0x60100 393472 +r3 0x40011000 1073811456 +r4 0x80 128 +r5 0x80 128 +r6 0x0 0 +r7 0x601 1537 +r8 0x0 0 +r9 0x40 64 +r10 0x0 0 +r11 0x0 0 +r12 0x0 0 +sp 0x2000da00 0x2000da00 +lr 0x4fe19 327193 +pc 0x4fea0 0x4fea0 +xpsr 0x21000000 553648128 +msp 0x20040000 0x20040000 +psp 0x0 0x0 +primask 0x0 0 +basepri 0x0 0 +faultmask 0x0 0 +control 0x0 0 +apsr 0x0 0 +epsr 0x1000000 16777216 +ipsr 0x0 0 +iapsr 0x0 0 +eapsr 0x1000000 16777216 +iepsr 0x1000000 16777216 +fpscr 0x0 0 +Received monitor command: reset +Resetting target +Resetting target +GDB closed TCP/IP connection (Socket 888) +A debugging session is active. + + Inferior 1 [Remote target] will be killed. + +Quit anyway? (y or n) [answered Y; input not from terminal] +Restoring target state and closing J-Link connection... +Shutting down... diff --git a/apps/bttester/pkg.yml b/apps/bttester/pkg.yml index e763185fe5..b45faebfda 100644 --- a/apps/bttester/pkg.yml +++ b/apps/bttester/pkg.yml @@ -36,6 +36,7 @@ pkg.deps: - "@apache-mynewt-nimble/nimble/host/services/gap" - "@apache-mynewt-nimble/nimble/host/services/gatt" - "@apache-mynewt-nimble/nimble/host/services/dis" + - "@apache-mynewt-nimble/nimble/host/audio/services/bass" - "@apache-mynewt-nimble/nimble/host/store/config" - "@apache-mynewt-core/hw/drivers/uart" - "@apache-mynewt-core/hw/drivers/rtt" diff --git a/apps/bttester/src/btp/btp.h b/apps/bttester/src/btp/btp.h index 4403a16038..a4ae5225a2 100644 --- a/apps/bttester/src/btp/btp.h +++ b/apps/bttester/src/btp/btp.h @@ -48,6 +48,7 @@ #define BTP_SERVICE_ID_MESH 4 #define BTP_SERVICE_ID_GATTC 6 #define BTP_SERVICE_ID_BAP 14 +#define BTP_SERVICE_ID_BASS 14 #define BTP_SERVICE_ID_MAX BTP_SERVICE_ID_BAP diff --git a/apps/bttester/src/btp/btp_bass.h b/apps/bttester/src/btp/btp_bass.h new file mode 100644 index 0000000000..8e840037e3 --- /dev/null +++ b/apps/bttester/src/btp/btp_bass.h @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BTP_BASS_ +#define H_BTP_BASS_ + +#include "nimble/ble.h" +#include + +#ifndef __packed +#define __packed __attribute__((__packed__)) +#endif + +/* BAS Service */ +/* commands */ +#define BTP_BASS_READ_SUPPORTED_COMMANDS 0x01 +struct btp_bass_read_supported_commands_rp { + uint8_t data[0]; +} __packed; + +#endif /* H_BTP_BASS_ */ \ No newline at end of file diff --git a/apps/bttester/src/btp/btp_gap.h b/apps/bttester/src/btp/btp_gap.h index 2a87b12930..7af0a42f92 100644 --- a/apps/bttester/src/btp/btp_gap.h +++ b/apps/bttester/src/btp/btp_gap.h @@ -70,6 +70,7 @@ struct btp_gap_read_controller_index_list_rp { #define BTP_GAP_SETTINGS_PRIVACY 13 #define BTP_GAP_SETTINGS_CONTROLLER_CONFIG 14 #define BTP_GAP_SETTINGS_STATIC_ADDRESS 15 +#define BTP_GAP_SETTINGS_EXTENDED_ADVERTISING 17 #define BTP_GAP_SETTINGS_PERIODIC_ADVERTISING 18 #define BTP_GAP_READ_CONTROLLER_INFO 0x03 @@ -258,6 +259,15 @@ struct btp_gap_set_filter_accept_list_cmd { ble_addr_t addrs[]; } __packed; +#define GAP_SET_EXT_ADV 0x21 +struct btp_gap_set_ext_advertising_cmd { + uint8_t flags; +} __packed; + +struct btp_gap_set_ext_advertising_rp { + uint32_t current_settings; +} __packed; + #define GAP_PADV_CONFIGURE 0x22 struct gap_periodic_adv_configure_cmd { uint8_t flags; diff --git a/apps/bttester/src/btp/bttester.h b/apps/bttester/src/btp/bttester.h index 7cb82b5c92..873a0803a0 100644 --- a/apps/bttester/src/btp/bttester.h +++ b/apps/bttester/src/btp/bttester.h @@ -148,6 +148,9 @@ tester_init_bap(void); uint8_t tester_unregister_bap(void); #endif /* MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) */ - -#endif /* __BTTESTER_H__ */ +uint8_t +tester_init_bass(void); +uint8_t +tester_unregister_bass(void); +#endif /* MYNEWT_VAL(BLE_ISO_BROADCASTER) */ diff --git a/apps/bttester/src/btp_bass.c b/apps/bttester/src/btp_bass.c new file mode 100644 index 0000000000..8947232634 --- /dev/null +++ b/apps/bttester/src/btp_bass.c @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* btp_bass.c - Bluetooth Broadcast Audio Stream Service Tester */ + +#include "syscfg/syscfg.h" +#include + +#if MYNEWT_VAL(BLE_AUDIO) + +#include "btp/btp_bass.h" + + +#include "btp/btp.h" +#include "console/console.h" + +#include "nimble/ble.h" +#include "host/ble_hs.h" +#include "host/util/util.h" +#include "math.h" + +#include "audio/ble_audio_broadcast_source.h" +#include "services/bass/ble_audio_svc_bass.h" +#include "audio/ble_audio.h" +#include "host/ble_iso.h" + +#include "bsp/bsp.h" + +static uint8_t +supported_commands(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + return BTP_STATUS_SUCCESS; +} + +static const struct btp_handler handlers[] = { + { + .opcode = BTP_BASS_READ_SUPPORTED_COMMANDS, + .index = BTP_INDEX_NONE, + .expect_len = 0, + .func = supported_commands, + }, +}; + +uint8_t +tester_init_bass(void) +{ + tester_register_command_handlers(BTP_SERVICE_ID_BASS, handlers, + ARRAY_SIZE(handlers)); + + return BTP_STATUS_SUCCESS; +} + +uint8_t +tester_unregister_bass(void) +{ + return BTP_STATUS_SUCCESS; +} + +#endif /* MYNEWT_VAL(BLE_AUDIO) */ + diff --git a/apps/bttester/src/btp_core.c b/apps/bttester/src/btp_core.c index a7b1878322..eeae816a9e 100644 --- a/apps/bttester/src/btp_core.c +++ b/apps/bttester/src/btp_core.c @@ -106,7 +106,7 @@ register_service(const void *cmd, uint16_t cmd_len, case BTP_SERVICE_ID_BAP: status = tester_init_bap(); break; -#endif /* MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) */ +#endif /* MYNEWT_VAL(BLE_ISO_BROADCASTER) */ case BTP_SERVICE_ID_GATTC: status = tester_init_gatt_cl(); break; diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index d0aa7ce06e..71062f8946 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -160,6 +160,7 @@ supported_commands(const void *cmd, uint16_t cmd_len, /* octet 4 */ #if MYNEWT_VAL(BLE_PERIODIC_ADV) + tester_set_bit(rp->data, GAP_SET_EXT_ADV); tester_set_bit(rp->data, GAP_PADV_CONFIGURE); tester_set_bit(rp->data, GAP_PADV_START); tester_set_bit(rp->data, GAP_PADV_SET_DATA); @@ -2000,6 +2001,44 @@ set_filter_accept_list(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +#if MYNEWT_VAL(BLE_EXT_ADV) +static uint8_t set_ext_advertising(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int rc; + //const struct btp_gap_set_ext_advertising_cmd *cp = cmd; + struct ble_gap_ext_adv_params ext_params = {0}; + struct btp_gap_set_ext_advertising_rp *rp = rsp; + + ext_params.connectable = 0; + ext_params.scannable = 0; + ext_params.legacy_pdu = 0; + ext_params.anonymous = 0; + ext_params.own_addr_type = own_addr_type; + ext_params.primary_phy = BLE_HCI_LE_PHY_1M; + ext_params.secondary_phy = BLE_HCI_LE_PHY_1M; + ext_params.sid = 1; + + rc = ble_gap_ext_adv_configure(1, &ext_params, NULL, gap_event_cb, NULL); + if (rc) { + SYS_LOG_ERR("Failed to configure extended advertiser; rc=%d", rc); + return BTP_STATUS_FAILED; + } + + rc = ble_gap_ext_adv_start(1,0,0); + if (rc) { + SYS_LOG_ERR("Failed to start extended advertiser; rc=%d", rc); + return BTP_STATUS_FAILED; + } + + current_settings |= BIT(BTP_GAP_SETTINGS_EXTENDED_ADVERTISING); + + rp->current_settings = htole32(current_settings); + *rsp_len = sizeof(*rp); + return BTP_STATUS_SUCCESS; +} +#endif + #if MYNEWT_VAL(BLE_PERIODIC_ADV) static uint8_t periodic_adv_configure(const void *cmd, uint16_t cmd_len, @@ -2330,6 +2369,13 @@ static const struct btp_handler handlers[] = { .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = set_filter_accept_list, }, +#if MYNEWT_VAL(BLE_EXT_ADV) + { + .opcode = GAP_SET_EXT_ADV, + .expect_len = sizeof(struct btp_gap_set_ext_advertising_cmd), + .func = set_ext_advertising, + }, +#endif /* BLE_EXT_ADV*/ #if MYNEWT_VAL(BLE_PERIODIC_ADV) { .opcode = GAP_PADV_CONFIGURE, diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index 80c377a7c1..6aba1d862f 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -94,6 +94,8 @@ syscfg.vals: BLE_ISO: 1 BLE_AUDIO: 1 BLE_ROLE_BROADCASTER: 1 + BLE_ISO_BROADCAST_SOURCE: 1 + BLE_ISO_BROADCAST_SINK: 1 BLE_ISO_MAX_BISES: 1 BLE_ISO_MAX_BIGS: 1 BLE_EXT_ADV: 1 @@ -101,7 +103,7 @@ syscfg.vals: BLE_EXT_ADV_MAX_SIZE: 40 BLE_PERIODIC_ADV: 1 BLE_ISO_BROADCAST_SOURCE: 1 - BLE_MULTI_ADV_INSTANCES: 1 + BLE_MULTI_ADV_INSTANCES: 3 OS_MAIN_STACK_SIZE: 512 SHELL_TASK: 0 From 2b7bbb23ec45372f2abadcdb0cf13755e8d2a6dc Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Fri, 17 May 2024 17:38:14 +0200 Subject: [PATCH 2/3] nimble/host: BASS fixes Fix infinite loops Fix event naming in remove source. Add variable to hold characteristic handle in remove source. Fix incorrect address type in add source. --- .../host/audio/services/bass/src/ble_audio_svc_bass.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) 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 1c4ff639e1..12a6d8e328 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 @@ -385,7 +385,7 @@ 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; @@ -514,7 +514,6 @@ ble_svc_audio_bass_modify_source(uint8_t *data, uint16_t data_len, uint16_t conn if (!rc) { rc = ble_svc_audio_bass_receive_state_notify(rcv_state); ev.bass_operation_status.status = rc; - goto done; } ble_audio_event_listener_call(&ev); @@ -549,7 +548,7 @@ static int ble_svc_audio_bass_remove_source(uint8_t *data, uint16_t data_len, uint16_t conn_handle) { struct ble_audio_event ev = { - .type = BLE_AUDIO_EVENT_BASS_BROADCAST_CODE_SET, + .type = BLE_AUDIO_EVENT_BASS_OPERATION_STATUS, .bass_operation_status = { .op = BLE_AUDIO_EVENT_BASS_SOURCE_REMOVED, .status = 0 @@ -557,6 +556,7 @@ ble_svc_audio_bass_remove_source(uint8_t *data, uint16_t data_len, uint16_t conn }; struct ble_svc_audio_bass_rcv_state_entry *rcv_state = NULL; struct ble_svc_audio_bass_operation operation; + uint16_t chr_val; int rc = 0; int i; @@ -570,6 +570,8 @@ ble_svc_audio_bass_remove_source(uint8_t *data, uint16_t data_len, uint16_t conn goto done; } + chr_val = rcv_state->chr_val; + operation.remove_source.source_id = ev.bass_operation_status.source_id; operation.conn_handle = conn_handle; if (accept_fn.ctrl_point_ev_fn) { @@ -587,12 +589,12 @@ ble_svc_audio_bass_remove_source(uint8_t *data, uint16_t data_len, uint16_t conn memset(rcv_state, 0, sizeof(*rcv_state)); rcv_state->source_id = BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE; + rcv_state->chr_val = chr_val; done: if (!rc) { rc = ble_svc_audio_bass_receive_state_notify(rcv_state); ev.bass_operation_status.status = rc; - goto done; } ble_audio_event_listener_call(&ev); From 3a2155b4a00a20298d447c47ee1d606f64f8428a Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Fri, 24 May 2024 08:54:07 +0200 Subject: [PATCH 3/3] More BASS fixes --- apps/bttester/syscfg.yml | 7 +- .../services/bass/ble_audio_svc_bass.h | 7 + .../services/bass/src/ble_audio_svc_bass.c | 139 ++++++++++++++---- 3 files changed, 121 insertions(+), 32 deletions(-) diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index 6aba1d862f..af1fbd6acd 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -104,6 +104,7 @@ syscfg.vals: BLE_PERIODIC_ADV: 1 BLE_ISO_BROADCAST_SOURCE: 1 BLE_MULTI_ADV_INSTANCES: 3 + BLE_SVC_AUDIO_BASS_METADATA_MAX_SZ: 256 OS_MAIN_STACK_SIZE: 512 SHELL_TASK: 0 @@ -164,6 +165,6 @@ syscfg.vals: BLE_MESH_RX_SEG_MAX: 13 BLE_MESH_TX_SEG_MSG_COUNT: 2 BLE_MAX_CONNECTIONS: 8 - - - + NRF5340_EMBED_NET_CORE: 1 + BSP_NRF5340_NET_ENABLE: 1 + MYNEWT_DOWNLOADER: nrfjprog 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 431ecb968c..f0949a2e1a 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 @@ -286,6 +286,9 @@ struct ble_svc_audio_bass_operation { /** Number of subgroups */ uint8_t num_subgroups; + /** BIS Synchronisation of subgroups */ + uint32_t bis_sync[BLE_SVC_AUDIO_BASS_SUB_NUM_MAX]; + /** Subgroup entries */ struct ble_svc_audio_bass_subgroup subgroups[BLE_SVC_AUDIO_BASS_SUB_NUM_MAX]; @@ -326,6 +329,10 @@ struct ble_svc_audio_bass_operation { /** BIS Synchronisation of subgroups */ uint32_t bis_sync[BLE_SVC_AUDIO_BASS_SUB_NUM_MAX]; + + /** Subgroup entries */ + struct ble_svc_audio_bass_subgroup + subgroups[BLE_SVC_AUDIO_BASS_SUB_NUM_MAX]; } modify_source; /** 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 12a6d8e328..a4494310fd 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 @@ -23,6 +23,9 @@ #include "../../host/src/ble_att_priv.h" #include "services/bass/ble_audio_svc_bass.h" #include "../../../src/ble_audio_priv.h" +#include "os/os_mbuf.h" +#include "os/util.h" +#include #define BLE_SVC_AUDIO_BASS_CHR_LEN_UNLIMITED (-1) #define BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE 0xFF @@ -251,6 +254,10 @@ ble_svc_audio_bass_receive_state_free(struct ble_svc_audio_bass_rcv_state_entry static int ble_svc_audio_bass_remote_scan_stopped(uint8_t *data, uint16_t data_len, uint16_t conn_handle) { + if (data_len > 1) { + return BLE_ATT_ERR_WRITE_REQ_REJECTED; + } + struct ble_audio_event ev = { .type = BLE_AUDIO_EVENT_BASS_REMOTE_SCAN_STOPPED }; @@ -264,6 +271,10 @@ ble_svc_audio_bass_remote_scan_stopped(uint8_t *data, uint16_t data_len, uint16_ static int ble_svc_audio_bass_remote_scan_started(uint8_t *data, uint16_t data_len, uint16_t conn_handle) { + if (data_len > 1) { + return BLE_ATT_ERR_WRITE_REQ_REJECTED; + } + struct ble_audio_event ev = { .type = BLE_AUDIO_EVENT_BASS_REMOTE_SCAN_STARTED }; @@ -274,6 +285,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) { @@ -298,10 +331,23 @@ ble_svc_audio_bass_add_source(uint8_t *data, uint16_t data_len, uint16_t conn_ha operation.op = BLE_SVC_AUDIO_BASS_OPERATION_ADD_SOURCE; operation.conn_handle = conn_handle; + offset++; operation.add_source.adv_addr.type = data[offset++]; + if (operation.add_source.adv_addr.type < 0 || + operation.add_source.adv_addr.type > 3) { + 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 < 0 || + operation.add_source.adv_sid > 0xF) { + 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++]; @@ -326,6 +372,7 @@ ble_svc_audio_bass_add_source(uint8_t *data, uint16_t data_len, uint16_t conn_ha ev.bass_operation_status.status = BLE_HS_EREJECT; goto done; } + operation.add_source.bis_sync[i] = get_le32(&data[offset]); operation.add_source.subgroups[i].bis_sync_state = get_le32(&data[offset]); offset += 4; operation.add_source.subgroups[i].metadata_length = data[offset++]; @@ -339,6 +386,18 @@ ble_svc_audio_bass_add_source(uint8_t *data, uint16_t data_len, uint16_t conn_ha 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(); operation.add_source.source_id = source_id_new; @@ -388,6 +447,8 @@ ble_svc_audio_bass_add_source(uint8_t *data, uint16_t data_len, uint16_t conn_ha 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 +476,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) { @@ -449,6 +488,7 @@ ble_svc_audio_bass_modify_source(uint8_t *data, uint16_t data_len, uint16_t conn .status = 0 } }; + uint8_t *metadata_ptr; uint8_t offset = 0; int rc = 0; int i; @@ -458,6 +498,7 @@ ble_svc_audio_bass_modify_source(uint8_t *data, uint16_t data_len, uint16_t conn operation.op = BLE_SVC_AUDIO_BASS_OPERATION_MODIFY_SOURCE; operation.conn_handle = conn_handle; + offset++; operation.modify_source.source_id = data[offset++]; ble_svc_audio_bass_receive_state_find_by_source_id(&rcv_state, @@ -477,8 +518,7 @@ ble_svc_audio_bass_modify_source(uint8_t *data, uint16_t data_len, uint16_t conn operation.modify_source.pa_interval = get_le16(&data[offset]); offset += 2; - operation.modify_source.num_subgroups = get_le16(&data[offset]); - offset += 2; + operation.modify_source.num_subgroups = data[offset++]; data_len -= offset; if (data_len < operation.modify_source.num_subgroups * sizeof(uint32_t)) { @@ -489,7 +529,18 @@ ble_svc_audio_bass_modify_source(uint8_t *data, uint16_t data_len, uint16_t conn for (i = 0; i < operation.modify_source.num_subgroups; i++) { operation.modify_source.bis_sync[i] = get_le32(&data[offset]); + rcv_state->state.subgroups[i].bis_sync_state = operation.modify_source.bis_sync[i]; offset += 4; + operation.modify_source.subgroups[i].metadata_length = data[offset++]; + data_len -= 5; + if (data_len < operation.modify_source.subgroups[i].metadata_length) { + rc = BLE_ATT_ERR_WRITE_REQ_REJECTED; + ev.bass_operation_status.status = BLE_HS_EREJECT; + goto done; + } + operation.modify_source.subgroups[i].metadata = &data[offset]; + offset += operation.modify_source.subgroups[i].metadata_length; + data_len -= operation.modify_source.subgroups[i].metadata_length; } if (check_bis_sync(operation.modify_source.num_subgroups, @@ -509,6 +560,23 @@ ble_svc_audio_bass_modify_source(uint8_t *data, uint16_t data_len, uint16_t conn } ev.bass_operation_status.source_id = operation.modify_source.source_id; + rcv_state->source_id = operation.modify_source.source_id; + rcv_state->state.pa_sync_state = operation.modify_source.pa_sync; + + for (i = 0; i < operation.modify_source.num_subgroups; i++) { + metadata_ptr = os_memblock_get(&ble_audio_svc_bass_metadata_pool); + if (!metadata_ptr) { + rc = BLE_HS_ENOMEM; + ev.bass_operation_status.status = BLE_HS_ENOMEM; + goto done; + } + rcv_state->state.subgroups[i].metadata_length = operation.modify_source.subgroups[i].metadata_length; + memcpy(metadata_ptr, operation.modify_source.subgroups[i].metadata, + min(operation.modify_source.subgroups[i].metadata_length, + MYNEWT_VAL(BLE_SVC_AUDIO_BASS_METADATA_MAX_SZ))); + + rcv_state->state.subgroups[i].metadata = metadata_ptr; + } done: if (!rc) { @@ -529,6 +597,10 @@ ble_svc_audio_bass_set_broadcast_code(uint8_t *data, uint16_t data_len, uint16_t .type = BLE_AUDIO_EVENT_BASS_BROADCAST_CODE_SET, }; + if (data_len != 18) { + return BLE_ATT_ERR_WRITE_REQ_REJECTED; + } + ev.bass_set_broadcast_code.source_id = data[0]; ble_svc_audio_bass_receive_state_find_by_source_id(&rcv_state, @@ -560,7 +632,7 @@ ble_svc_audio_bass_remove_source(uint8_t *data, uint16_t data_len, uint16_t conn int rc = 0; int i; - ev.bass_set_broadcast_code.source_id = data[0]; + ev.bass_set_broadcast_code.source_id = data[1]; ble_svc_audio_bass_receive_state_find_by_source_id(&rcv_state, ev.bass_operation_status.source_id); @@ -570,6 +642,10 @@ ble_svc_audio_bass_remove_source(uint8_t *data, uint16_t data_len, uint16_t conn goto done; } + if (rcv_state->state.pa_sync_state == BLE_SVC_AUDIO_BASS_PA_SYNC_STATE_SYNCED) { + return rc; + } + chr_val = rcv_state->chr_val; operation.remove_source.source_id = ev.bass_operation_status.source_id; @@ -606,8 +682,9 @@ static struct ble_svc_audio_bass_ctrl_point_handler * ble_svc_audio_bass_find_handler(uint8_t opcode) { int i; + uint8_t handlers_size = ARRAY_SIZE(ble_svc_audio_bass_ctrl_point_handlers); - for (i = 0; i < sizeof(ble_svc_audio_bass_ctrl_point_handlers); i++) { + for (i = 0; i < handlers_size; i++) { if (ble_svc_audio_bass_ctrl_point_handlers[i].op_code == opcode) { return &ble_svc_audio_bass_ctrl_point_handlers[i]; } @@ -620,12 +697,16 @@ static int ble_svc_audio_bass_ctrl_point_write_access(struct ble_gatt_access_ctxt *ctxt, uint16_t conn_handle) { struct ble_svc_audio_bass_ctrl_point_handler *handler; + uint16_t mbuf_len = OS_MBUF_PKTLEN(ctxt->om); + uint8_t opcode; + uint8_t data[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_METADATA_MAX_SZ)]; - uint8_t opcode = ctxt->om->om_data[0]; + os_mbuf_copydata(ctxt->om, 0, mbuf_len, data); + opcode = data[0]; handler = ble_svc_audio_bass_find_handler(opcode); - if (!handler) { + if (handler == NULL) { return BLE_SVC_AUDIO_BASS_ERR_OPCODE_NOT_SUPPORTED; } @@ -635,7 +716,7 @@ ble_svc_audio_bass_ctrl_point_write_access(struct ble_gatt_access_ctxt *ctxt, ui return BLE_ATT_ERR_WRITE_REQ_REJECTED; } - return handler->handler_cb(&ctxt->om->om_data[1], ctxt->om->om_len - 1, conn_handle); + return handler->handler_cb(data, mbuf_len, conn_handle); } static int