Bluetooth: Audio: Rename BASS and BASS client
Rename BASS to BAP Scan Delegator and BASS Client to BAP Broadcast Assistant. This is the first step towards integrating the BASS with the rest of BAP. Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
parent
c417cbc050
commit
ecb7591d6b
25 changed files with 1020 additions and 974 deletions
|
@ -28,7 +28,8 @@ Bluetooth APIs
|
|||
volume.rst
|
||||
uuid.rst
|
||||
shell/audio.rst
|
||||
shell/bass.rst
|
||||
shell/bap_broadcast_assistant.rst
|
||||
shell/bap_scan_delegator.rst
|
||||
shell/ccp.rst
|
||||
shell/csip.rst
|
||||
shell/iso.rst
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
Bluetooth: Broadcast Audio Profile Broadcast Assistant
|
||||
######################################################
|
||||
|
||||
This document describes how to run the BAP Broadcast Assistant functionality.
|
||||
Note that in the examples below, some lines of debug have been
|
||||
removed to make this shorter and provide a better overview.
|
||||
|
||||
The Broadcast Assistant is responsible for offloading scan for a resource
|
||||
restricted device, such that scanning does not drain the battery. The Broadcast
|
||||
Assistant shall support scanning for periodic advertisements and may optionally
|
||||
support the periodic advertisements synchronization transfer (PAST) protocol.
|
||||
|
||||
The Broadcast Assistant will typically be phones or laptops.
|
||||
The Broadcast Assistant scans for periodic advertisements and transfer
|
||||
information to the server.
|
||||
|
||||
It is necessary to have :code:`BT_DEBUG_BAP_BROADCAST_ASSISTANT` enabled for
|
||||
using the Broadcast Assistant interactively.
|
||||
|
||||
When the Bluetooth stack has been initialized (:code:`bt init`),
|
||||
and a device has been connected, the Broadcast Assistant can discover BASS on
|
||||
the connected device calling :code:`bap_broadcast_assistant discover`, which
|
||||
will start a discovery for the BASS UUIDs and store the handles, and
|
||||
subscribe to all notifications.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
bap_broadcast_assistant - Bluetooth BAP Broadcast Assistant shell commands
|
||||
Subcommands:
|
||||
discover :Discover BASS on the server
|
||||
scan_start :Start scanning for broadcasters
|
||||
scan_stop :Stop scanning for BISs
|
||||
add_src :Add a source <address: XX:XX:XX:XX:XX:XX> <type:
|
||||
public/random> <adv_sid> <sync_pa> <broadcast_id>
|
||||
[<pa_interval>] [<sync_bis>] [<metadata>]
|
||||
mod_src :Set sync <src_id> <sync_pa> [<pa_interval>] [<sync_bis>]
|
||||
[<metadata>]
|
||||
broadcast_code :Send a space separated broadcast code of up to 16 bytes
|
||||
<src_id> [broadcast code]
|
||||
rem_src :Remove a source <src_id>
|
||||
read_state :Remove a source <index>
|
||||
|
||||
Example usage
|
||||
*************
|
||||
|
||||
Setup
|
||||
=====
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
uart:~$ bt init
|
||||
uart:~$ bt connect xx:xx:xx:xx:xx:xx public
|
||||
|
||||
When connected
|
||||
==============
|
||||
|
||||
Start scanning for periodic advertisements for a server:
|
||||
|
||||
.. note::
|
||||
The Broadcast Assistant will not actually start scanning for periodic
|
||||
advertisements, as that feature is still, at the time of writing, not
|
||||
implemented.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
uart:~$ bap_broadcast_assistant discover
|
||||
<dbg> bt_bap_broadcast_assistant.char_discover_func: Found 1 BASS receive states
|
||||
<dbg> bt_bap_broadcast_assistant.read_recv_state_cb: src_id 0, PA 0, BIS 0, encrypt 0, addr 00:00:00:00:00:00 (public), sid 0, metadata_len 0
|
||||
uart:~$ bap_broadcast_assistant scan_start
|
||||
<dbg> bt_bap_broadcast_assistant.write_func: err: 0x00, handle 0x001e
|
||||
|
||||
Adding a source to the receive state:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
uart:~$ bap_broadcast_assistant add_src 11:22:33:44:55:66 public 5 1 1
|
||||
BASS recv state: src_id 0, addr 11:22:33:44:55:66 (public), sid 5, sync_state 1, encrypt_state 000000000000000000000000000000000
|
||||
[0]: BIS sync 0, metadata_len 0
|
48
doc/connectivity/bluetooth/api/shell/bap_scan_delegator.rst
Normal file
48
doc/connectivity/bluetooth/api/shell/bap_scan_delegator.rst
Normal file
|
@ -0,0 +1,48 @@
|
|||
Bluetooth: Broadcast Audio Profile Scan Delegator
|
||||
#################################################
|
||||
|
||||
This document describes how to run the Scan Delegator functionality, Note that
|
||||
in the examples below, some lines of debug have been
|
||||
removed to make this shorter and provide a better overview.
|
||||
|
||||
The Scan Delegator may optionally support the periodic advertisements
|
||||
synchronization transfer (PAST) protocol.
|
||||
|
||||
The Scan Delegator server typically resides on devices that have inputs or
|
||||
outputs.
|
||||
|
||||
It is necessary to have :code:`BT_DEBUG_BAP_SCAN_DELEGATOR` enabled for using
|
||||
the Scan Delegator interactively.
|
||||
|
||||
The Scan Delegator can currently only set the sync state of a receive state, but
|
||||
does not actually support syncing with periodic advertisements yet.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
bap_scan_delegator --help
|
||||
bap_scan_delegator - Bluetooth BAP Scan Delegator shell commands
|
||||
Subcommands:
|
||||
init :Initialize the service and register callbacks
|
||||
synced :Set server scan state <src_id> <pa_synced> <bis_syncs> <enc_state>
|
||||
|
||||
|
||||
Example Usage
|
||||
*************
|
||||
|
||||
Setup
|
||||
=====
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
uart:~$ bt init
|
||||
uart:~$ bt advertise on
|
||||
Advertising started
|
||||
|
||||
When connected
|
||||
==============
|
||||
|
||||
Set sync state for a source:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
uart:~$ bap_scan_delegator synced 0 1 3 0
|
|
@ -1,130 +0,0 @@
|
|||
Bluetooth: Broadcast Audio Scan Service
|
||||
#######################################
|
||||
|
||||
This document describes how to run the BASS functionality, both as a client
|
||||
and as a server. Note that in the examples below, some lines of debug have been
|
||||
removed to make this shorter and provide a better overview.
|
||||
|
||||
The client is responsible for offloading scan for a resource restricted device,
|
||||
such that scanning does not drain the battery. The client shall support scanning
|
||||
for periodic advertisements, and the server shall support synchronizing to
|
||||
periodic advertisements. They may both optionally support the
|
||||
periodic advertisements synchronization transfer (PAST) protocol.
|
||||
|
||||
Broadcast Audio Scan Client (Scan Offloader)
|
||||
********************************************
|
||||
|
||||
The BASS client will typically be phones or laptops.
|
||||
The client scans for periodic advertisements and transfer information to the
|
||||
server.
|
||||
|
||||
It is necessary to have :code:`BT_DEBUG_BASS_CLIENT` enabled for using the BASS
|
||||
client interactively.
|
||||
|
||||
Using the BASS client
|
||||
=====================
|
||||
|
||||
When the Bluetooth stack has been initialized (:code:`bt init`),
|
||||
and a device has been connected, the BASS client can discover BASS on
|
||||
the connected device calling :code:`bass_client discover`, which will
|
||||
start a discovery for the BASS UUIDs and store the handles, and optionally
|
||||
subscribe to all notifications (default is to subscribe to all).
|
||||
|
||||
Since a server may have multiple included Volume Offset or Audio Input service
|
||||
instances, some of the client commands commands will take an index
|
||||
(starting from 0) as input.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
bass_client - Bluetooth BASS client shell commands
|
||||
Subcommands:
|
||||
discover :Discover BASS on the server
|
||||
scan_start :Start scanning for broadcasters
|
||||
scan_stop :Stop scanning for BISs
|
||||
add_src :Add a source <address: XX:XX:XX:XX:XX:XX> <type:
|
||||
public/random> <adv_sid> <sync_pa> <broadcast_id>
|
||||
[<pa_interval>] [<sync_bis>] [<metadata>]
|
||||
mod_src :Set sync <src_id> <sync_pa> [<pa_interval>] [<sync_bis>]
|
||||
[<metadata>]
|
||||
broadcast_code :Send a space separated broadcast code of up to 16 bytes
|
||||
<src_id> [broadcast code]
|
||||
rem_src :Remove a source <src_id>
|
||||
read_state :Remove a source <index>
|
||||
|
||||
Example usage
|
||||
=============
|
||||
|
||||
Setup
|
||||
-----
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
uart:~$ bt init
|
||||
uart:~$ bt connect xx:xx:xx:xx:xx:xx public
|
||||
|
||||
When connected
|
||||
--------------
|
||||
|
||||
Start scanning for periodic advertisements for a server:
|
||||
|
||||
.. note::
|
||||
The BASS client will not actually start scanning for periodic advertisements,
|
||||
as that feature is still, at the time of writing, not implemented.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
uart:~$ bass_client discover
|
||||
<dbg> bt_bass_client.char_discover_func: Found 1 BASS receive states
|
||||
<dbg> bt_bass_client.read_recv_state_cb: src_id 0, PA 0, BIS 0, encrypt 0, addr 00:00:00:00:00:00 (public), sid 0, metadata_len 0
|
||||
uart:~$ bass_client scan_start
|
||||
<dbg> bt_bass_client.write_func: err: 0x00, handle 0x001e
|
||||
|
||||
Adding a source to the receive state:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
uart:~$ bass_client add_src 11:22:33:44:55:66 public 5 1 1
|
||||
BASS recv state: src_id 0, addr 11:22:33:44:55:66 (public), sid 5, sync_state 1, encrypt_state 000000000000000000000000000000000
|
||||
[0]: BIS sync 0, metadata_len 0
|
||||
|
||||
BASS Server
|
||||
***********
|
||||
The BASS server typically resides on devices that have inputs or outputs.
|
||||
|
||||
It is necessary to have :code:`BT_DEBUG_BASS` enabled for using the BASS server
|
||||
interactively.
|
||||
|
||||
Using the BASS server
|
||||
================================
|
||||
The BASS server can currently only set the sync state of a receive state, but
|
||||
does not actually support syncing with periodic advertisements yet.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
bass --help
|
||||
bass - Bluetooth BASS shell commands
|
||||
Subcommands:
|
||||
init :Initialize the service and register callbacks
|
||||
synced :Set server scan state <src_id> <pa_synced> <bis_syncs> <enc_state>
|
||||
|
||||
|
||||
Example Usage
|
||||
=============
|
||||
|
||||
Setup
|
||||
-----
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
uart:~$ bt init
|
||||
uart:~$ bt advertise on
|
||||
Advertising started
|
||||
|
||||
When connected
|
||||
--------------
|
||||
|
||||
Set sync state for a source:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
uart:~$ bass synced 0 1 3 0
|
|
@ -1,56 +1,57 @@
|
|||
/** @file
|
||||
* @brief Header for Bluetooth BASS.
|
||||
* @brief Header for Bluetooth BAP.
|
||||
*
|
||||
* Copyright (c) 2020 Bose Corporation
|
||||
* Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
* Copyright (c) 2021-2022 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_BASS_
|
||||
#define ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_BASS_
|
||||
#ifndef ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_BAP_
|
||||
#define ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_BAP_
|
||||
#include <zephyr/types.h>
|
||||
#include <zephyr/bluetooth/conn.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_BT_BASS)
|
||||
#define BT_BASS_MAX_METADATA_LEN CONFIG_BT_BASS_MAX_METADATA_LEN
|
||||
#define BT_BASS_MAX_SUBGROUPS CONFIG_BT_BASS_MAX_SUBGROUPS
|
||||
#if IS_ENABLED(CONFIG_BT_BAP_SCAN_DELEGATOR)
|
||||
#define BT_BAP_SCAN_DELEGATOR_MAX_METADATA_LEN CONFIG_BT_BAP_SCAN_DELEGATOR_MAX_METADATA_LEN
|
||||
#define BT_BAP_SCAN_DELEGATOR_MAX_SUBGROUPS CONFIG_BT_BAP_SCAN_DELEGATOR_MAX_SUBGROUPS
|
||||
#else
|
||||
#define BT_BASS_MAX_METADATA_LEN 0
|
||||
#define BT_BASS_MAX_SUBGROUPS 0
|
||||
#define BT_BAP_SCAN_DELEGATOR_MAX_METADATA_LEN 0
|
||||
#define BT_BAP_SCAN_DELEGATOR_MAX_SUBGROUPS 0
|
||||
#endif
|
||||
|
||||
#define BT_BASS_BROADCAST_CODE_SIZE 16
|
||||
#define BT_BAP_BROADCAST_CODE_SIZE 16
|
||||
|
||||
#define BT_BASS_PA_STATE_NOT_SYNCED 0x00
|
||||
#define BT_BASS_PA_STATE_INFO_REQ 0x01
|
||||
#define BT_BASS_PA_STATE_SYNCED 0x02
|
||||
#define BT_BASS_PA_STATE_FAILED 0x03
|
||||
#define BT_BASS_PA_STATE_NO_PAST 0x04
|
||||
#define BT_BAP_PA_STATE_NOT_SYNCED 0x00
|
||||
#define BT_BAP_PA_STATE_INFO_REQ 0x01
|
||||
#define BT_BAP_PA_STATE_SYNCED 0x02
|
||||
#define BT_BAP_PA_STATE_FAILED 0x03
|
||||
#define BT_BAP_PA_STATE_NO_PAST 0x04
|
||||
|
||||
#define BT_BASS_BIG_ENC_STATE_NO_ENC 0x00
|
||||
#define BT_BASS_BIG_ENC_STATE_BCODE_REQ 0x01
|
||||
#define BT_BASS_BIG_ENC_STATE_DEC 0x02
|
||||
#define BT_BASS_BIG_ENC_STATE_BAD_CODE 0x03
|
||||
#define BT_BAP_BIG_ENC_STATE_NO_ENC 0x00
|
||||
#define BT_BAP_BIG_ENC_STATE_BCODE_REQ 0x01
|
||||
#define BT_BAP_BIG_ENC_STATE_DEC 0x02
|
||||
#define BT_BAP_BIG_ENC_STATE_BAD_CODE 0x03
|
||||
|
||||
#define BT_BASS_ERR_OPCODE_NOT_SUPPORTED 0x80
|
||||
#define BT_BASS_ERR_INVALID_SRC_ID 0x81
|
||||
#define BT_BAP_BASS_ERR_OPCODE_NOT_SUPPORTED 0x80
|
||||
#define BT_BAP_BASS_ERR_INVALID_SRC_ID 0x81
|
||||
|
||||
#define BT_BASS_PA_INTERVAL_UNKNOWN 0xFFFF
|
||||
#define BT_BAP_PA_INTERVAL_UNKNOWN 0xFFFF
|
||||
|
||||
#define BT_BASS_BROADCAST_MAX_ID 0xFFFFFF
|
||||
#define BT_BAP_BROADCAST_MAX_ID 0xFFFFFF
|
||||
|
||||
#define BT_BASS_BIS_SYNC_NO_PREF 0xFFFFFFFF
|
||||
#define BT_BAP_BIS_SYNC_NO_PREF 0xFFFFFFFF
|
||||
|
||||
struct bt_bass_subgroup {
|
||||
/* TODO: Replace with struct bt_audio_base_subgroup */
|
||||
struct bt_bap_scan_delegator_subgroup {
|
||||
uint32_t bis_sync;
|
||||
uint32_t requested_bis_sync;
|
||||
uint8_t metadata_len;
|
||||
uint8_t metadata[BT_BASS_MAX_METADATA_LEN];
|
||||
uint8_t metadata[BT_BAP_SCAN_DELEGATOR_MAX_METADATA_LEN];
|
||||
};
|
||||
|
||||
/* TODO: Only expose this as an opaque type */
|
||||
struct bt_bass_recv_state {
|
||||
struct bt_bap_scan_delegator_recv_state {
|
||||
uint8_t src_id;
|
||||
bt_addr_le_t addr;
|
||||
uint8_t adv_sid;
|
||||
|
@ -58,27 +59,29 @@ struct bt_bass_recv_state {
|
|||
uint8_t pa_sync_state;
|
||||
uint8_t encrypt_state;
|
||||
uint32_t broadcast_id; /* 24 bits */
|
||||
uint8_t bad_code[BT_BASS_BROADCAST_CODE_SIZE];
|
||||
uint8_t bad_code[BT_BAP_BROADCAST_CODE_SIZE];
|
||||
uint8_t num_subgroups;
|
||||
struct bt_bass_subgroup subgroups[BT_BASS_MAX_SUBGROUPS];
|
||||
struct bt_bap_scan_delegator_subgroup subgroups[BT_BAP_SCAN_DELEGATOR_MAX_SUBGROUPS];
|
||||
};
|
||||
|
||||
struct bt_bass_cb {
|
||||
void (*pa_synced)(struct bt_bass_recv_state *recv_state,
|
||||
struct bt_bap_scan_delegator_cb {
|
||||
void (*pa_synced)(struct bt_bap_scan_delegator_recv_state *recv_state,
|
||||
const struct bt_le_per_adv_sync_synced_info *info);
|
||||
void (*pa_term)(struct bt_bass_recv_state *recv_state,
|
||||
void (*pa_term)(struct bt_bap_scan_delegator_recv_state *recv_state,
|
||||
const struct bt_le_per_adv_sync_term_info *info);
|
||||
void (*pa_recv)(struct bt_bass_recv_state *recv_state,
|
||||
void (*pa_recv)(struct bt_bap_scan_delegator_recv_state *recv_state,
|
||||
const struct bt_le_per_adv_sync_recv_info *info,
|
||||
struct net_buf_simple *buf);
|
||||
void (*biginfo)(struct bt_bass_recv_state *recv_state,
|
||||
void (*biginfo)(struct bt_bap_scan_delegator_recv_state *recv_state,
|
||||
const struct bt_iso_biginfo *biginfo);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Registers the callbacks used by BASS.
|
||||
* @brief Register the callbacks for the Basic Audio Profile Scan Delegator
|
||||
*
|
||||
* @param cb Pointer to the callback struct
|
||||
*/
|
||||
void bt_bass_register_cb(struct bt_bass_cb *cb);
|
||||
void bt_bap_scan_delegator_register_cb(struct bt_bap_scan_delegator_cb *cb);
|
||||
|
||||
/**
|
||||
* @brief Set the sync state of a receive state in the server
|
||||
|
@ -90,14 +93,14 @@ void bt_bass_register_cb(struct bt_bass_cb *cb);
|
|||
* @param encrypted The BIG encryption state.
|
||||
* @return int Error value. 0 on success, ERRNO on fail.
|
||||
*/
|
||||
int bt_bass_set_sync_state(uint8_t src_id, uint8_t pa_sync_state,
|
||||
uint32_t bis_synced[BT_BASS_MAX_SUBGROUPS],
|
||||
int bt_bap_scan_delegator_set_sync_state(uint8_t src_id, uint8_t pa_sync_state,
|
||||
uint32_t bis_synced[BT_BAP_SCAN_DELEGATOR_MAX_SUBGROUPS],
|
||||
uint8_t encrypted);
|
||||
|
||||
/******************************** CLIENT API ********************************/
|
||||
|
||||
/**
|
||||
* @brief Callback function for bt_bass_client_discover.
|
||||
* @brief Callback function for bt_bap_broadcast_assistant_discover.
|
||||
*
|
||||
* @param conn The connection that was used to discover
|
||||
* Broadcast Audio Scan Service.
|
||||
|
@ -105,7 +108,8 @@ int bt_bass_set_sync_state(uint8_t src_id, uint8_t pa_sync_state,
|
|||
* GATT error or ERRNO on fail.
|
||||
* @param recv_state_count Number of receive states on the server.
|
||||
*/
|
||||
typedef void (*bt_bass_client_discover_cb)(struct bt_conn *conn, int err,
|
||||
typedef void (*bt_bap_broadcast_assistant_discover_cb)(struct bt_conn *conn,
|
||||
int err,
|
||||
uint8_t recv_state_count);
|
||||
|
||||
/**
|
||||
|
@ -117,7 +121,7 @@ typedef void (*bt_bass_client_discover_cb)(struct bt_conn *conn, int err,
|
|||
* @param info Advertiser information.
|
||||
* @param broadcast_id 24-bit broadcast ID.
|
||||
*/
|
||||
typedef void (*bt_bass_client_scan_cb)(const struct bt_le_scan_recv_info *info,
|
||||
typedef void (*bt_bap_broadcast_assistant_scan_cb)(const struct bt_le_scan_recv_info *info,
|
||||
uint32_t broadcast_id);
|
||||
|
||||
/**
|
||||
|
@ -129,8 +133,9 @@ typedef void (*bt_bass_client_scan_cb)(const struct bt_le_scan_recv_info *info,
|
|||
* @param err Error value. 0 on success, GATT error on fail.
|
||||
* @param state The receive state.
|
||||
*/
|
||||
typedef void (*bt_bass_client_recv_state_cb)(struct bt_conn *conn, int err,
|
||||
const struct bt_bass_recv_state *state);
|
||||
typedef void (*bt_bap_broadcast_assistant_recv_state_cb)(
|
||||
struct bt_conn *conn, int err,
|
||||
const struct bt_bap_scan_delegator_recv_state *state);
|
||||
|
||||
/**
|
||||
* @brief Callback function for when a receive state is removed.
|
||||
|
@ -139,7 +144,8 @@ typedef void (*bt_bass_client_recv_state_cb)(struct bt_conn *conn, int err,
|
|||
* @param err Error value. 0 on success, GATT error on fail.
|
||||
* @param src_id The receive state.
|
||||
*/
|
||||
typedef void (*bt_bass_client_recv_state_rem_cb)(struct bt_conn *conn, int err,
|
||||
typedef void (*bt_bap_broadcast_assistant_recv_state_rem_cb)(struct bt_conn *conn,
|
||||
int err,
|
||||
uint8_t src_id);
|
||||
|
||||
/**
|
||||
|
@ -148,20 +154,21 @@ typedef void (*bt_bass_client_recv_state_rem_cb)(struct bt_conn *conn, int err,
|
|||
* @param conn The connection to the peer device.
|
||||
* @param err Error value. 0 on success, GATT error on fail.
|
||||
*/
|
||||
typedef void (*bt_bass_client_write_cb)(struct bt_conn *conn, int err);
|
||||
typedef void (*bt_bap_broadcast_assistant_write_cb)(struct bt_conn *conn,
|
||||
int err);
|
||||
|
||||
struct bt_bass_client_cb {
|
||||
bt_bass_client_discover_cb discover;
|
||||
bt_bass_client_scan_cb scan;
|
||||
bt_bass_client_recv_state_cb recv_state;
|
||||
bt_bass_client_recv_state_rem_cb recv_state_removed;
|
||||
struct bt_bap_broadcast_assistant_cb {
|
||||
bt_bap_broadcast_assistant_discover_cb discover;
|
||||
bt_bap_broadcast_assistant_scan_cb scan;
|
||||
bt_bap_broadcast_assistant_recv_state_cb recv_state;
|
||||
bt_bap_broadcast_assistant_recv_state_rem_cb recv_state_removed;
|
||||
|
||||
bt_bass_client_write_cb scan_start;
|
||||
bt_bass_client_write_cb scan_stop;
|
||||
bt_bass_client_write_cb add_src;
|
||||
bt_bass_client_write_cb mod_src;
|
||||
bt_bass_client_write_cb broadcast_code;
|
||||
bt_bass_client_write_cb rem_src;
|
||||
bt_bap_broadcast_assistant_write_cb scan_start;
|
||||
bt_bap_broadcast_assistant_write_cb scan_stop;
|
||||
bt_bap_broadcast_assistant_write_cb add_src;
|
||||
bt_bap_broadcast_assistant_write_cb mod_src;
|
||||
bt_bap_broadcast_assistant_write_cb broadcast_code;
|
||||
bt_bap_broadcast_assistant_write_cb rem_src;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -173,7 +180,7 @@ struct bt_bass_client_cb {
|
|||
* @param conn The connection
|
||||
* @return int Error value. 0 on success, GATT error or ERRNO on fail.
|
||||
*/
|
||||
int bt_bass_client_discover(struct bt_conn *conn);
|
||||
int bt_bap_broadcast_assistant_discover(struct bt_conn *conn);
|
||||
|
||||
/**
|
||||
* @brief Scan start for BISes for a remote server.
|
||||
|
@ -184,7 +191,7 @@ int bt_bass_client_discover(struct bt_conn *conn);
|
|||
* to start scanning itself.
|
||||
*
|
||||
* Scan results, if @p start_scan is true, is sent to the
|
||||
* bt_bass_client_scan_cb callback.
|
||||
* bt_bap_broadcast_assistant_scan_cb callback.
|
||||
*
|
||||
* @param conn Connection to the Broadcast Audio Scan Service server.
|
||||
* Used to let the server know that we are scanning.
|
||||
|
@ -192,7 +199,8 @@ int bt_bass_client_discover(struct bt_conn *conn);
|
|||
* enable scan itself.
|
||||
* @return int Error value. 0 on success, GATT error or ERRNO on fail.
|
||||
*/
|
||||
int bt_bass_client_scan_start(struct bt_conn *conn, bool start_scan);
|
||||
int bt_bap_broadcast_assistant_scan_start(struct bt_conn *conn,
|
||||
bool start_scan);
|
||||
|
||||
/**
|
||||
* @brief Stop remote scanning for BISes for a server.
|
||||
|
@ -200,15 +208,15 @@ int bt_bass_client_scan_start(struct bt_conn *conn, bool start_scan);
|
|||
* @param conn Connection to the server.
|
||||
* @return int Error value. 0 on success, GATT error or ERRNO on fail.
|
||||
*/
|
||||
int bt_bass_client_scan_stop(struct bt_conn *conn);
|
||||
int bt_bap_broadcast_assistant_scan_stop(struct bt_conn *conn);
|
||||
|
||||
/**
|
||||
* @brief Registers the callbacks used by Broadcast Audio Scan Service client.
|
||||
*/
|
||||
void bt_bass_client_register_cb(struct bt_bass_client_cb *cb);
|
||||
void bt_bap_broadcast_assistant_register_cb(struct bt_bap_broadcast_assistant_cb *cb);
|
||||
|
||||
/** Parameters for adding a source to a Broadcast Audio Scan Service server */
|
||||
struct bt_bass_add_src_param {
|
||||
struct bt_bap_broadcast_assistant_add_src_param {
|
||||
/** Address of the advertiser. */
|
||||
bt_addr_le_t addr;
|
||||
/** SID of the advertising set. */
|
||||
|
@ -220,13 +228,13 @@ struct bt_bass_add_src_param {
|
|||
/**
|
||||
* @brief Periodic advertising interval in milliseconds.
|
||||
*
|
||||
* BT_BASS_PA_INTERVAL_UNKNOWN if unknown.
|
||||
* BT_BAP_PA_INTERVAL_UNKNOWN if unknown.
|
||||
*/
|
||||
uint16_t pa_interval;
|
||||
/** Number of subgroups */
|
||||
uint8_t num_subgroups;
|
||||
/** Pointer to array of subgroups */
|
||||
struct bt_bass_subgroup *subgroups;
|
||||
struct bt_bap_scan_delegator_subgroup *subgroups;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -237,11 +245,11 @@ struct bt_bass_add_src_param {
|
|||
*
|
||||
* @return Error value. 0 on success, GATT error or ERRNO on fail.
|
||||
*/
|
||||
int bt_bass_client_add_src(struct bt_conn *conn,
|
||||
struct bt_bass_add_src_param *param);
|
||||
int bt_bap_broadcast_assistant_add_src(struct bt_conn *conn,
|
||||
struct bt_bap_broadcast_assistant_add_src_param *param);
|
||||
|
||||
/** Parameters for modifying a source */
|
||||
struct bt_bass_mod_src_param {
|
||||
struct bt_bap_broadcast_assistant_mod_src_param {
|
||||
/** Source ID of the receive state. */
|
||||
uint8_t src_id;
|
||||
/** Whether to sync to periodic advertisements. */
|
||||
|
@ -249,13 +257,13 @@ struct bt_bass_mod_src_param {
|
|||
/**
|
||||
* @brief Periodic advertising interval.
|
||||
*
|
||||
* BT_BASS_PA_INTERVAL_UNKNOWN if unknown.
|
||||
* BT_BAP_PA_INTERVAL_UNKNOWN if unknown.
|
||||
*/
|
||||
uint16_t pa_interval;
|
||||
/** Number of subgroups */
|
||||
uint8_t num_subgroups;
|
||||
/** Pointer to array of subgroups */
|
||||
struct bt_bass_subgroup *subgroups;
|
||||
struct bt_bap_scan_delegator_subgroup *subgroups;
|
||||
};
|
||||
|
||||
/** @brief Modify a source on the server.
|
||||
|
@ -265,8 +273,8 @@ struct bt_bass_mod_src_param {
|
|||
*
|
||||
* @return Error value. 0 on success, GATT error or ERRNO on fail.
|
||||
*/
|
||||
int bt_bass_client_mod_src(struct bt_conn *conn,
|
||||
struct bt_bass_mod_src_param *param);
|
||||
int bt_bap_broadcast_assistant_mod_src(struct bt_conn *conn,
|
||||
struct bt_bap_broadcast_assistant_mod_src_param *param);
|
||||
|
||||
/** @brief Set a broadcast code to the specified receive state.
|
||||
*
|
||||
|
@ -276,8 +284,9 @@ int bt_bass_client_mod_src(struct bt_conn *conn,
|
|||
*
|
||||
* @return Error value. 0 on success, GATT error or ERRNO on fail.
|
||||
*/
|
||||
int bt_bass_client_set_broadcast_code(struct bt_conn *conn, uint8_t src_id,
|
||||
uint8_t broadcast_code[BT_BASS_BROADCAST_CODE_SIZE]);
|
||||
int bt_bap_broadcast_assistant_set_broadcast_code(
|
||||
struct bt_conn *conn, uint8_t src_id,
|
||||
uint8_t broadcast_code[BT_BAP_BROADCAST_CODE_SIZE]);
|
||||
|
||||
/** @brief Remove a source from the server.
|
||||
*
|
||||
|
@ -286,15 +295,16 @@ int bt_bass_client_set_broadcast_code(struct bt_conn *conn, uint8_t src_id,
|
|||
*
|
||||
* @return Error value. 0 on success, GATT error or ERRNO on fail.
|
||||
*/
|
||||
int bt_bass_client_rem_src(struct bt_conn *conn, uint8_t src_id);
|
||||
int bt_bap_broadcast_assistant_rem_src(struct bt_conn *conn, uint8_t src_id);
|
||||
|
||||
/** @brief Read the specified receive state from the server.
|
||||
*
|
||||
* @param conn Connection to the server.
|
||||
* @param idx The index of the receive start (0 up to the value from
|
||||
* bt_bass_client_discover_cb)
|
||||
* bt_bap_broadcast_assistant_discover_cb)
|
||||
*
|
||||
* @return Error value. 0 on success, GATT error or ERRNO on fail.
|
||||
*/
|
||||
int bt_bass_client_read_recv_state(struct bt_conn *conn, uint8_t idx);
|
||||
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_BASS_ */
|
||||
int bt_bap_broadcast_assistant_read_recv_state(struct bt_conn *conn,
|
||||
uint8_t idx);
|
||||
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_BAP_ */
|
|
@ -55,8 +55,8 @@ zephyr_library_sources_ifdef(CONFIG_BT_AUDIO_UNICAST_SERVER unicast_server.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_BT_AUDIO_UNICAST_CLIENT unicast_client.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_BT_AUDIO_BROADCAST_SOURCE broadcast_source.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_BT_AUDIO_BROADCAST_SINK broadcast_sink.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_BT_BASS bass.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_BT_BASS_CLIENT bass_client.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_BT_BAP_SCAN_DELEGATOR bap_scan_delegator.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_BT_BAP_BROADCAST_ASSISTANT bap_broadcast_assistant.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_BT_HAS has.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_BT_HAS_CLIENT has_client.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_BT_CAP cap_stream.c)
|
||||
|
|
|
@ -189,6 +189,69 @@ config BT_AUDIO_BROADCAST_SNK_STREAM_COUNT
|
|||
|
||||
endif # BT_AUDIO_BROADCAST_SINK
|
||||
|
||||
config BT_BAP_SCAN_DELEGATOR
|
||||
bool "Basic Audio Profile Scan Delegator role support [EXPERIMENTAL]"
|
||||
select EXPERIMENTAL
|
||||
select BT_OBSERVER
|
||||
select BT_EXT_ADV
|
||||
select BT_PER_ADV_SYNC
|
||||
select BT_ISO_SYNC_RECEIVER
|
||||
help
|
||||
This option enables support for the Scan Delegator role and the
|
||||
Broadcast Audio Scan Service (BASS).
|
||||
|
||||
if BT_BAP_SCAN_DELEGATOR
|
||||
|
||||
config BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT
|
||||
int "Scan Delegator Receive State Count"
|
||||
default 1
|
||||
range 1 3
|
||||
help
|
||||
Sets the number of receive state characteristics present on the
|
||||
server. Each characteristic may hold information to sync to a
|
||||
periodic advertise or a broadcast isochronous stream.
|
||||
|
||||
config BT_BAP_SCAN_DELEGATOR_MAX_METADATA_LEN
|
||||
int "Scan Delegator Maximum Metadata Length"
|
||||
default 32
|
||||
range 0 255
|
||||
help
|
||||
The maximum metadata length support by the BASS server.
|
||||
|
||||
config BT_BAP_SCAN_DELEGATOR_MAX_SUBGROUPS
|
||||
int "Scan Delegator Maximum Number of Subgroups support"
|
||||
default 1
|
||||
range 0 31
|
||||
help
|
||||
The maximum number of BIS subgroups supported.
|
||||
|
||||
endif # BT_BAP_SCAN_DELEGATOR
|
||||
|
||||
config BT_BAP_BROADCAST_ASSISTANT
|
||||
bool "Basic Audio Profile Broadcast Assistant role support [EXPERIMENTAL]"
|
||||
select EXPERIMENTAL
|
||||
select BT_OBSERVER
|
||||
select BT_EXT_ADV
|
||||
select BT_PER_ADV_SYNC
|
||||
select BT_ISO_SYNC_RECEIVER
|
||||
select BT_GATT_CLIENT
|
||||
select BT_GATT_AUTO_DISCOVER_CCC
|
||||
select BT_GATT_AUTO_UPDATE_MTU
|
||||
help
|
||||
This option enables support for the Broadcast Assistant role.
|
||||
|
||||
if BT_BAP_BROADCAST_ASSISTANT
|
||||
|
||||
config BT_BAP_BROADCAST_ASSISTANT_RECV_STATE_COUNT
|
||||
int "Broadcast Assistant Max Receive State Count"
|
||||
default 1
|
||||
range 1 255
|
||||
help
|
||||
Sets the number of maximum receive stat characteristics that will be
|
||||
discovered and ready to use. Each characteristic may hold information
|
||||
to sync to a periodic advertise or a broadcast isochronous stream.
|
||||
|
||||
endif # BT_BAP_BROADCAST_ASSISTANT
|
||||
|
||||
config BT_AUDIO_DEBUG_STREAM
|
||||
bool "Bluetooth Audio Stream debug"
|
||||
|
@ -240,6 +303,19 @@ config BT_AUDIO_DEBUG_BROADCAST_SINK
|
|||
Use this option to enable Bluetooth Audio Broadcast Sink debug logs
|
||||
for the Bluetooth Audio functionality.
|
||||
|
||||
config BT_DEBUG_BAP_SCAN_DELEGATOR
|
||||
bool "Broadcast Audio Scan Service debug"
|
||||
depends on BT_BAP_SCAN_DELEGATOR
|
||||
help
|
||||
Use this option to enable Broadcast Audio Scan Service debug logs for
|
||||
the Bluetooth Audio functionality.
|
||||
|
||||
config BT_DEBUG_BAP_BROADCAST_ASSISTANT
|
||||
bool "Broadcast Audio Scan Service client debug"
|
||||
depends on BT_BAP_BROADCAST_ASSISTANT
|
||||
help
|
||||
Use this option to enable Broadcast Audio Scan Service client
|
||||
debug logs for the Bluetooth Audio functionality.
|
||||
|
||||
config BT_AUDIO_STREAM
|
||||
# Virtual/hidden option
|
||||
|
|
|
@ -8,86 +8,5 @@
|
|||
|
||||
if BT_AUDIO
|
||||
|
||||
##################### Broadcast Audio Scan Service #####################
|
||||
|
||||
config BT_BASS
|
||||
bool "Broadcast Audio Scan Service"
|
||||
select BT_OBSERVER
|
||||
select BT_EXT_ADV
|
||||
select BT_PER_ADV_SYNC
|
||||
select BT_ISO_SYNC_RECEIVER
|
||||
help
|
||||
This option enables support for the Broadcast Audio Scan Service.
|
||||
|
||||
if BT_BASS
|
||||
|
||||
config BT_BASS_RECV_STATE_COUNT
|
||||
int "Broadcast Audio Scan Service Receive State Count"
|
||||
default 1
|
||||
range 1 3
|
||||
help
|
||||
Sets the number of receive state characteristics present on the
|
||||
server. Each characteristic may hold information to sync to a
|
||||
periodic advertise or a broadcast isochronous stream.
|
||||
|
||||
config BT_BASS_MAX_METADATA_LEN
|
||||
int "Broadcast Audio Scan Service Maximum Metadata Length"
|
||||
default 32
|
||||
range 0 255
|
||||
help
|
||||
The maximum metadata length support by the BASS server.
|
||||
|
||||
config BT_BASS_MAX_SUBGROUPS
|
||||
int "Broadcast Audio Scan Service Maximum Number of Subgroups support"
|
||||
default 1
|
||||
range 0 31
|
||||
help
|
||||
The maximum number of BIS subgroups supported.
|
||||
|
||||
############### DEBUG ###############
|
||||
|
||||
config BT_DEBUG_BASS
|
||||
bool "Broadcast Audio Scan Service debug"
|
||||
help
|
||||
Use this option to enable Broadcast Audio Scan Service debug logs for
|
||||
the Bluetooth Audio functionality.
|
||||
|
||||
endif # BT_BASS
|
||||
|
||||
##################### Broadcast Audio Scan Client #####################
|
||||
|
||||
config BT_BASS_CLIENT
|
||||
bool "Broadcast Audio Scan Service client"
|
||||
select BT_OBSERVER
|
||||
select BT_EXT_ADV
|
||||
select BT_PER_ADV_SYNC
|
||||
select BT_ISO_SYNC_RECEIVER
|
||||
select BT_GATT_CLIENT
|
||||
select BT_GATT_AUTO_DISCOVER_CCC
|
||||
select BT_GATT_AUTO_UPDATE_MTU
|
||||
help
|
||||
This option enables support for the Broadcast Audio Scan Service
|
||||
client.
|
||||
|
||||
if BT_BASS_CLIENT
|
||||
|
||||
config BT_BASS_CLIENT_RECV_STATE_COUNT
|
||||
int "Broadcast Audio Scan Service Client Max Receive State Count"
|
||||
default 1
|
||||
range 1 255
|
||||
help
|
||||
Sets the number of maximum receive stat characteristics that will be
|
||||
discovered and ready to use. Each characteristic may hold information
|
||||
to sync to a periodic advertise or a broadcast isochronous stream.
|
||||
|
||||
############### DEBUG ###############
|
||||
|
||||
config BT_DEBUG_BASS_CLIENT
|
||||
bool "Broadcast Audio Scan Service client debug"
|
||||
help
|
||||
Use this option to enable Broadcast Audio Scan Service client
|
||||
debug logs for the Bluetooth Audio functionality.
|
||||
|
||||
endif # BT_BASS_CLIENT
|
||||
|
||||
endif # BT_AUDIO
|
||||
|
|
|
@ -10,7 +10,7 @@ config BT_CAP
|
|||
|
||||
config BT_CAP_ACCEPTOR
|
||||
bool "Common Audio Profile Acceptor Role Support [EXPERIMENTAL]"
|
||||
depends on BT_AUDIO_UNICAST_SERVER || (BT_AUDIO_BROADCAST_SINK && BT_BASS)
|
||||
depends on BT_AUDIO_UNICAST_SERVER || (BT_AUDIO_BROADCAST_SINK && BT_BAP_SCAN_DELEGATOR)
|
||||
select EXPERIMENTAL
|
||||
help
|
||||
Enabling this will enable the CAP Acceptor role. This instantiates the
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
/* Bluetooth BASS - Broadcast Audio Scan Service - Client */
|
||||
/* Bluetooth BAP Broadcast Assistant */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 Bose Corporation
|
||||
* Copyright (c) 2022 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -19,18 +20,18 @@
|
|||
#include <zephyr/sys/byteorder.h>
|
||||
#include <zephyr/sys/check.h>
|
||||
|
||||
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_BASS_CLIENT)
|
||||
#define LOG_MODULE_NAME bt_bass_client
|
||||
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_BAP_BROADCAST_ASSISTANT)
|
||||
#define LOG_MODULE_NAME bt_bap_broadcast_assistant
|
||||
#include "common/log.h"
|
||||
#include "common/bt_str.h"
|
||||
|
||||
#include "bass_internal.h"
|
||||
#include "bap_internal.h"
|
||||
#include "../host/conn_internal.h"
|
||||
#include "../host/hci_core.h"
|
||||
|
||||
#define MINIMUM_RECV_STATE_LEN 15
|
||||
|
||||
struct bass_client_instance {
|
||||
struct bap_broadcast_assistant_instance {
|
||||
bool discovering;
|
||||
bool scanning;
|
||||
uint8_t pa_sync;
|
||||
|
@ -38,34 +39,34 @@ struct bass_client_instance {
|
|||
/* Source ID cache so that we can notify application about
|
||||
* which source ID was removed
|
||||
*/
|
||||
uint8_t src_ids[CONFIG_BT_BASS_CLIENT_RECV_STATE_COUNT];
|
||||
uint8_t src_ids[CONFIG_BT_BAP_BROADCAST_ASSISTANT_RECV_STATE_COUNT];
|
||||
|
||||
uint16_t start_handle;
|
||||
uint16_t end_handle;
|
||||
uint16_t cp_handle;
|
||||
uint16_t recv_state_handles[CONFIG_BT_BASS_CLIENT_RECV_STATE_COUNT];
|
||||
uint16_t recv_state_handles[CONFIG_BT_BAP_BROADCAST_ASSISTANT_RECV_STATE_COUNT];
|
||||
|
||||
bool busy;
|
||||
struct bt_gatt_subscribe_params recv_state_sub_params
|
||||
[CONFIG_BT_BASS_CLIENT_RECV_STATE_COUNT];
|
||||
[CONFIG_BT_BAP_BROADCAST_ASSISTANT_RECV_STATE_COUNT];
|
||||
struct bt_gatt_discover_params recv_state_disc_params
|
||||
[CONFIG_BT_BASS_CLIENT_RECV_STATE_COUNT];
|
||||
[CONFIG_BT_BAP_BROADCAST_ASSISTANT_RECV_STATE_COUNT];
|
||||
struct bt_gatt_read_params read_params;
|
||||
struct bt_gatt_write_params write_params;
|
||||
struct bt_gatt_discover_params disc_params;
|
||||
};
|
||||
|
||||
static struct bt_bass_client_cb *bass_cbs;
|
||||
static struct bt_bap_broadcast_assistant_cb *broadcast_assistant_cbs;
|
||||
|
||||
static struct bass_client_instance bass_client;
|
||||
static struct bap_broadcast_assistant_instance broadcast_assistant;
|
||||
static struct bt_uuid_16 uuid = BT_UUID_INIT_16(0);
|
||||
|
||||
NET_BUF_SIMPLE_DEFINE_STATIC(cp_buf, CONFIG_BT_L2CAP_TX_MTU);
|
||||
|
||||
static int16_t lookup_index_by_handle(uint16_t handle)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_SIZE(bass_client.recv_state_handles); i++) {
|
||||
if (bass_client.recv_state_handles[i] == handle) {
|
||||
for (int i = 0; i < ARRAY_SIZE(broadcast_assistant.recv_state_handles); i++) {
|
||||
if (broadcast_assistant.recv_state_handles[i] == handle) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +77,7 @@ static int16_t lookup_index_by_handle(uint16_t handle)
|
|||
}
|
||||
|
||||
static int parse_recv_state(const void *data, uint16_t length,
|
||||
struct bt_bass_recv_state *recv_state)
|
||||
struct bt_bap_scan_delegator_recv_state *recv_state)
|
||||
{
|
||||
struct net_buf_simple buf;
|
||||
bt_addr_t *addr;
|
||||
|
@ -106,7 +107,7 @@ static int parse_recv_state(const void *data, uint16_t length,
|
|||
recv_state->broadcast_id = net_buf_simple_pull_le24(&buf);
|
||||
recv_state->pa_sync_state = net_buf_simple_pull_u8(&buf);
|
||||
recv_state->encrypt_state = net_buf_simple_pull_u8(&buf);
|
||||
if (recv_state->encrypt_state == BT_BASS_BIG_ENC_STATE_BAD_CODE) {
|
||||
if (recv_state->encrypt_state == BT_BAP_BIG_ENC_STATE_BAD_CODE) {
|
||||
uint8_t *broadcast_code;
|
||||
const size_t minimum_size = sizeof(recv_state->bad_code) +
|
||||
sizeof(recv_state->num_subgroups);
|
||||
|
@ -118,14 +119,14 @@ static int parse_recv_state(const void *data, uint16_t length,
|
|||
}
|
||||
|
||||
broadcast_code = net_buf_simple_pull_mem(&buf,
|
||||
BT_BASS_BROADCAST_CODE_SIZE);
|
||||
BT_BAP_BROADCAST_CODE_SIZE);
|
||||
(void)memcpy(recv_state->bad_code, broadcast_code,
|
||||
sizeof(recv_state->bad_code));
|
||||
}
|
||||
|
||||
recv_state->num_subgroups = net_buf_simple_pull_u8(&buf);
|
||||
for (int i = 0; i < recv_state->num_subgroups; i++) {
|
||||
struct bt_bass_subgroup *subgroup = &recv_state->subgroups[i];
|
||||
struct bt_bap_scan_delegator_subgroup *subgroup = &recv_state->subgroups[i];
|
||||
uint8_t *metadata;
|
||||
|
||||
if (buf.len < sizeof(subgroup->bis_sync)) {
|
||||
|
@ -176,7 +177,7 @@ static uint8_t notify_handler(struct bt_conn *conn,
|
|||
const void *data, uint16_t length)
|
||||
{
|
||||
uint16_t handle = params->value_handle;
|
||||
struct bt_bass_recv_state recv_state;
|
||||
struct bt_bap_scan_delegator_recv_state recv_state;
|
||||
int err;
|
||||
int16_t index;
|
||||
|
||||
|
@ -207,14 +208,17 @@ static uint8_t notify_handler(struct bt_conn *conn,
|
|||
return BT_GATT_ITER_STOP;
|
||||
}
|
||||
|
||||
bass_client.src_ids[index] = recv_state.src_id;
|
||||
broadcast_assistant.src_ids[index] = recv_state.src_id;
|
||||
|
||||
if (bass_cbs != NULL && bass_cbs->recv_state != NULL) {
|
||||
bass_cbs->recv_state(conn, 0, &recv_state);
|
||||
if (broadcast_assistant_cbs != NULL &&
|
||||
broadcast_assistant_cbs->recv_state != NULL) {
|
||||
broadcast_assistant_cbs->recv_state(conn, 0, &
|
||||
recv_state);
|
||||
}
|
||||
} else if (bass_cbs != NULL && bass_cbs->recv_state_removed != NULL) {
|
||||
bass_cbs->recv_state_removed(conn, 0,
|
||||
bass_client.src_ids[index]);
|
||||
} else if (broadcast_assistant_cbs != NULL &&
|
||||
broadcast_assistant_cbs->recv_state_removed != NULL) {
|
||||
broadcast_assistant_cbs->recv_state_removed(conn, 0,
|
||||
broadcast_assistant.src_ids[index]);
|
||||
}
|
||||
|
||||
return BT_GATT_ITER_CONTINUE;
|
||||
|
@ -225,63 +229,71 @@ static uint8_t read_recv_state_cb(struct bt_conn *conn, uint8_t err,
|
|||
const void *data, uint16_t length)
|
||||
{
|
||||
uint16_t handle = params->single.handle;
|
||||
uint8_t last_handle_index = bass_client.recv_state_cnt - 1;
|
||||
uint16_t last_handle = bass_client.recv_state_handles[last_handle_index];
|
||||
struct bt_bass_recv_state recv_state;
|
||||
int bass_err = err;
|
||||
uint8_t last_handle_index = broadcast_assistant.recv_state_cnt - 1;
|
||||
uint16_t last_handle = broadcast_assistant.recv_state_handles[last_handle_index];
|
||||
struct bt_bap_scan_delegator_recv_state recv_state;
|
||||
int cb_err = err;
|
||||
bool active_recv_state = data != NULL && length != 0;
|
||||
|
||||
/* TODO: Split discovery and receive state characteristic read */
|
||||
|
||||
(void)memset(params, 0, sizeof(*params));
|
||||
|
||||
if (bass_err == 0 && active_recv_state) {
|
||||
if (cb_err == 0 && active_recv_state) {
|
||||
int16_t index;
|
||||
|
||||
index = lookup_index_by_handle(handle);
|
||||
if (index < 0) {
|
||||
bass_err = BT_GATT_ERR(BT_ATT_ERR_INVALID_HANDLE);
|
||||
cb_err = BT_GATT_ERR(BT_ATT_ERR_INVALID_HANDLE);
|
||||
} else {
|
||||
bass_err = parse_recv_state(data, length, &recv_state);
|
||||
cb_err = parse_recv_state(data, length, &recv_state);
|
||||
|
||||
if (bass_err != 0) {
|
||||
if (cb_err != 0) {
|
||||
BT_DBG("Invalid receive state");
|
||||
} else {
|
||||
bass_client.src_ids[index] = recv_state.src_id;
|
||||
broadcast_assistant.src_ids[index] = recv_state.src_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bass_err != 0) {
|
||||
BT_DBG("err: %d", bass_err);
|
||||
if (bass_client.discovering) {
|
||||
bass_client.discovering = false;
|
||||
if (bass_cbs != NULL && bass_cbs->discover != NULL) {
|
||||
bass_cbs->discover(conn, bass_err, 0);
|
||||
if (cb_err != 0) {
|
||||
BT_DBG("err: %d", cb_err);
|
||||
if (broadcast_assistant.discovering) {
|
||||
broadcast_assistant.discovering = false;
|
||||
if (broadcast_assistant_cbs != NULL &&
|
||||
broadcast_assistant_cbs->discover != NULL) {
|
||||
broadcast_assistant_cbs->discover(conn,
|
||||
cb_err, 0);
|
||||
}
|
||||
} else {
|
||||
if (bass_cbs != NULL && bass_cbs->recv_state != NULL) {
|
||||
bass_cbs->recv_state(conn, bass_err, NULL);
|
||||
if (broadcast_assistant_cbs != NULL &&
|
||||
broadcast_assistant_cbs->recv_state != NULL) {
|
||||
broadcast_assistant_cbs->recv_state(conn,
|
||||
cb_err,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
} else if (handle == last_handle) {
|
||||
if (bass_client.discovering) {
|
||||
bass_client.discovering = false;
|
||||
if (bass_cbs != NULL && bass_cbs->discover != NULL) {
|
||||
bass_cbs->discover(conn, bass_err,
|
||||
bass_client.recv_state_cnt);
|
||||
if (broadcast_assistant.discovering) {
|
||||
broadcast_assistant.discovering = false;
|
||||
if (broadcast_assistant_cbs != NULL &&
|
||||
broadcast_assistant_cbs->discover != NULL) {
|
||||
broadcast_assistant_cbs->discover(
|
||||
conn, cb_err,
|
||||
broadcast_assistant.recv_state_cnt);
|
||||
}
|
||||
} else {
|
||||
if (bass_cbs != NULL && bass_cbs->recv_state != NULL) {
|
||||
bass_cbs->recv_state(conn, bass_err,
|
||||
if (broadcast_assistant_cbs != NULL &&
|
||||
broadcast_assistant_cbs->recv_state != NULL) {
|
||||
broadcast_assistant_cbs->recv_state(conn,
|
||||
cb_err,
|
||||
&recv_state);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < bass_client.recv_state_cnt; i++) {
|
||||
if (handle == bass_client.recv_state_handles[i]) {
|
||||
(void)bt_bass_client_read_recv_state(conn,
|
||||
i + 1);
|
||||
for (int i = 0; i < broadcast_assistant.recv_state_cnt; i++) {
|
||||
if (handle == broadcast_assistant.recv_state_handles[i]) {
|
||||
(void)bt_bap_broadcast_assistant_read_recv_state(conn, i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -304,14 +316,15 @@ static uint8_t char_discover_func(struct bt_conn *conn,
|
|||
|
||||
if (attr == NULL) {
|
||||
BT_DBG("Found %u BASS receive states",
|
||||
bass_client.recv_state_cnt);
|
||||
broadcast_assistant.recv_state_cnt);
|
||||
(void)memset(params, 0, sizeof(*params));
|
||||
|
||||
err = bt_bass_client_read_recv_state(conn, 0);
|
||||
err = bt_bap_broadcast_assistant_read_recv_state(conn, 0);
|
||||
if (err != 0) {
|
||||
bass_client.discovering = false;
|
||||
if (bass_cbs != NULL && bass_cbs->discover != NULL) {
|
||||
bass_cbs->discover(conn, err, 0);
|
||||
broadcast_assistant.discovering = false;
|
||||
if (broadcast_assistant_cbs != NULL &&
|
||||
broadcast_assistant_cbs->discover != NULL) {
|
||||
broadcast_assistant_cbs->discover(conn, err, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -326,23 +339,25 @@ static uint8_t char_discover_func(struct bt_conn *conn,
|
|||
|
||||
if (bt_uuid_cmp(chrc->uuid, BT_UUID_BASS_CONTROL_POINT) == 0) {
|
||||
BT_DBG("Control Point");
|
||||
bass_client.cp_handle = attr->handle + 1;
|
||||
broadcast_assistant.cp_handle = attr->handle + 1;
|
||||
} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_BASS_RECV_STATE) == 0) {
|
||||
if (bass_client.recv_state_cnt < CONFIG_BT_BASS_CLIENT_RECV_STATE_COUNT) {
|
||||
uint8_t idx = bass_client.recv_state_cnt++;
|
||||
if (broadcast_assistant.recv_state_cnt <
|
||||
CONFIG_BT_BAP_BROADCAST_ASSISTANT_RECV_STATE_COUNT) {
|
||||
uint8_t idx = broadcast_assistant.recv_state_cnt++;
|
||||
|
||||
BT_DBG("Receive State %u",
|
||||
bass_client.recv_state_cnt);
|
||||
bass_client.recv_state_handles[idx] =
|
||||
broadcast_assistant.recv_state_cnt);
|
||||
broadcast_assistant.recv_state_handles[idx] =
|
||||
attr->handle + 1;
|
||||
sub_params = &bass_client.recv_state_sub_params[idx];
|
||||
sub_params->disc_params = &bass_client.recv_state_disc_params[idx];
|
||||
sub_params = &broadcast_assistant.recv_state_sub_params[idx];
|
||||
sub_params->disc_params =
|
||||
&broadcast_assistant.recv_state_disc_params[idx];
|
||||
}
|
||||
}
|
||||
|
||||
if (sub_params != NULL) {
|
||||
/* With ccc_handle == 0 it will use auto discovery */
|
||||
sub_params->end_handle = bass_client.end_handle;
|
||||
sub_params->end_handle = broadcast_assistant.end_handle;
|
||||
sub_params->ccc_handle = 0;
|
||||
sub_params->value = BT_GATT_CCC_NOTIFY;
|
||||
sub_params->value_handle = attr->handle + 1;
|
||||
|
@ -353,10 +368,12 @@ static uint8_t char_discover_func(struct bt_conn *conn,
|
|||
BT_DBG("Could not subscribe to handle 0x%04x",
|
||||
sub_params->value_handle);
|
||||
|
||||
bass_client.discovering = false;
|
||||
if (bass_cbs != NULL &&
|
||||
bass_cbs->discover != NULL) {
|
||||
bass_cbs->discover(conn, err, 0);
|
||||
broadcast_assistant.discovering = false;
|
||||
if (broadcast_assistant_cbs != NULL &&
|
||||
broadcast_assistant_cbs->discover != NULL) {
|
||||
broadcast_assistant_cbs->discover(conn,
|
||||
err,
|
||||
0);
|
||||
}
|
||||
|
||||
return BT_GATT_ITER_STOP;
|
||||
|
@ -378,11 +395,12 @@ static uint8_t service_discover_func(struct bt_conn *conn,
|
|||
BT_DBG("Could not discover BASS");
|
||||
(void)memset(params, 0, sizeof(*params));
|
||||
|
||||
bass_client.discovering = false;
|
||||
broadcast_assistant.discovering = false;
|
||||
|
||||
if (bass_cbs != NULL && bass_cbs->discover != NULL) {
|
||||
if (broadcast_assistant_cbs != NULL &&
|
||||
broadcast_assistant_cbs->discover != NULL) {
|
||||
err = BT_GATT_ERR(BT_ATT_ERR_NOT_SUPPORTED);
|
||||
bass_cbs->discover(conn, err, 0);
|
||||
broadcast_assistant_cbs->discover(conn, err, 0);
|
||||
}
|
||||
|
||||
return BT_GATT_ITER_STOP;
|
||||
|
@ -392,22 +410,23 @@ static uint8_t service_discover_func(struct bt_conn *conn,
|
|||
|
||||
if (params->type == BT_GATT_DISCOVER_PRIMARY) {
|
||||
prim_service = (struct bt_gatt_service_val *)attr->user_data;
|
||||
bass_client.start_handle = attr->handle + 1;
|
||||
bass_client.end_handle = prim_service->end_handle;
|
||||
broadcast_assistant.start_handle = attr->handle + 1;
|
||||
broadcast_assistant.end_handle = prim_service->end_handle;
|
||||
|
||||
bass_client.disc_params.uuid = NULL;
|
||||
bass_client.disc_params.start_handle = bass_client.start_handle;
|
||||
bass_client.disc_params.end_handle = bass_client.end_handle;
|
||||
bass_client.disc_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
|
||||
bass_client.disc_params.func = char_discover_func;
|
||||
broadcast_assistant.disc_params.uuid = NULL;
|
||||
broadcast_assistant.disc_params.start_handle = broadcast_assistant.start_handle;
|
||||
broadcast_assistant.disc_params.end_handle = broadcast_assistant.end_handle;
|
||||
broadcast_assistant.disc_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
|
||||
broadcast_assistant.disc_params.func = char_discover_func;
|
||||
|
||||
err = bt_gatt_discover(conn, &bass_client.disc_params);
|
||||
err = bt_gatt_discover(conn, &broadcast_assistant.disc_params);
|
||||
if (err != 0) {
|
||||
BT_DBG("Discover failed (err %d)", err);
|
||||
bass_client.discovering = false;
|
||||
broadcast_assistant.discovering = false;
|
||||
|
||||
if (bass_cbs != NULL && bass_cbs->discover != NULL) {
|
||||
bass_cbs->discover(conn, err, 0);
|
||||
if (broadcast_assistant_cbs != NULL &&
|
||||
broadcast_assistant_cbs->discover != NULL) {
|
||||
broadcast_assistant_cbs->discover(conn, err, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -415,46 +434,46 @@ static uint8_t service_discover_func(struct bt_conn *conn,
|
|||
return BT_GATT_ITER_STOP;
|
||||
}
|
||||
|
||||
static void bass_client_write_cp_cb(struct bt_conn *conn, uint8_t err,
|
||||
static void bap_broadcast_assistant_write_cp_cb(struct bt_conn *conn, uint8_t err,
|
||||
struct bt_gatt_write_params *params)
|
||||
{
|
||||
uint8_t opcode = net_buf_simple_pull_u8(&cp_buf);
|
||||
|
||||
bass_client.busy = false;
|
||||
broadcast_assistant.busy = false;
|
||||
|
||||
if (bass_cbs == NULL) {
|
||||
if (broadcast_assistant_cbs == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (opcode) {
|
||||
case BT_BASS_OP_SCAN_STOP:
|
||||
if (bass_cbs->scan_stop != NULL) {
|
||||
bass_cbs->scan_stop(conn, err);
|
||||
case BT_BAP_BASS_OP_SCAN_STOP:
|
||||
if (broadcast_assistant_cbs->scan_stop != NULL) {
|
||||
broadcast_assistant_cbs->scan_stop(conn, err);
|
||||
}
|
||||
break;
|
||||
case BT_BASS_OP_SCAN_START:
|
||||
if (bass_cbs->scan_start != NULL) {
|
||||
bass_cbs->scan_start(conn, err);
|
||||
case BT_BAP_BASS_OP_SCAN_START:
|
||||
if (broadcast_assistant_cbs->scan_start != NULL) {
|
||||
broadcast_assistant_cbs->scan_start(conn, err);
|
||||
}
|
||||
break;
|
||||
case BT_BASS_OP_ADD_SRC:
|
||||
if (bass_cbs->add_src != NULL) {
|
||||
bass_cbs->add_src(conn, err);
|
||||
case BT_BAP_BASS_OP_ADD_SRC:
|
||||
if (broadcast_assistant_cbs->add_src != NULL) {
|
||||
broadcast_assistant_cbs->add_src(conn, err);
|
||||
}
|
||||
break;
|
||||
case BT_BASS_OP_MOD_SRC:
|
||||
if (bass_cbs->mod_src != NULL) {
|
||||
bass_cbs->mod_src(conn, err);
|
||||
case BT_BAP_BASS_OP_MOD_SRC:
|
||||
if (broadcast_assistant_cbs->mod_src != NULL) {
|
||||
broadcast_assistant_cbs->mod_src(conn, err);
|
||||
}
|
||||
break;
|
||||
case BT_BASS_OP_BROADCAST_CODE:
|
||||
if (bass_cbs->broadcast_code != NULL) {
|
||||
bass_cbs->broadcast_code(conn, err);
|
||||
case BT_BAP_BASS_OP_BROADCAST_CODE:
|
||||
if (broadcast_assistant_cbs->broadcast_code != NULL) {
|
||||
broadcast_assistant_cbs->broadcast_code(conn, err);
|
||||
}
|
||||
break;
|
||||
case BT_BASS_OP_REM_SRC:
|
||||
if (bass_cbs->rem_src != NULL) {
|
||||
bass_cbs->rem_src(conn, err);
|
||||
case BT_BAP_BASS_OP_REM_SRC:
|
||||
if (broadcast_assistant_cbs->rem_src != NULL) {
|
||||
broadcast_assistant_cbs->rem_src(conn, err);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -463,27 +482,27 @@ static void bass_client_write_cp_cb(struct bt_conn *conn, uint8_t err,
|
|||
}
|
||||
}
|
||||
|
||||
static int bt_bass_client_common_cp(struct bt_conn *conn,
|
||||
static int bt_bap_broadcast_assistant_common_cp(struct bt_conn *conn,
|
||||
const struct net_buf_simple *buf)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (conn == NULL) {
|
||||
return -EINVAL;
|
||||
} else if (bass_client.cp_handle == 0) {
|
||||
} else if (broadcast_assistant.cp_handle == 0) {
|
||||
BT_DBG("Handle not set");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bass_client.write_params.offset = 0;
|
||||
bass_client.write_params.data = buf->data;
|
||||
bass_client.write_params.length = buf->len;
|
||||
bass_client.write_params.handle = bass_client.cp_handle;
|
||||
bass_client.write_params.func = bass_client_write_cp_cb;
|
||||
broadcast_assistant.write_params.offset = 0;
|
||||
broadcast_assistant.write_params.data = buf->data;
|
||||
broadcast_assistant.write_params.length = buf->len;
|
||||
broadcast_assistant.write_params.handle = broadcast_assistant.cp_handle;
|
||||
broadcast_assistant.write_params.func = bap_broadcast_assistant_write_cp_cb;
|
||||
|
||||
err = bt_gatt_write(conn, &bass_client.write_params);
|
||||
err = bt_gatt_write(conn, &broadcast_assistant.write_params);
|
||||
if (err == 0) {
|
||||
bass_client.busy = true;
|
||||
broadcast_assistant.busy = true;
|
||||
}
|
||||
|
||||
return err;
|
||||
|
@ -500,7 +519,7 @@ static bool broadcast_source_found(struct bt_data *data, void *user_data)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (data->data_len < BT_UUID_SIZE_16 + BT_BASS_BROADCAST_ID_SIZE) {
|
||||
if (data->data_len < BT_UUID_SIZE_16 + BT_AUDIO_BROADCAST_ID_SIZE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -517,8 +536,9 @@ static bool broadcast_source_found(struct bt_data *data, void *user_data)
|
|||
BT_DBG("Found BIS advertiser with address %s",
|
||||
bt_addr_le_str(info->addr));
|
||||
|
||||
if (bass_cbs != NULL && bass_cbs->scan != NULL) {
|
||||
bass_cbs->scan(info, broadcast_id);
|
||||
if (broadcast_assistant_cbs != NULL &&
|
||||
broadcast_assistant_cbs->scan != NULL) {
|
||||
broadcast_assistant_cbs->scan(info, broadcast_id);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -542,7 +562,7 @@ static struct bt_le_scan_cb scan_cb = {
|
|||
|
||||
/****************************** PUBLIC API ******************************/
|
||||
|
||||
int bt_bass_client_discover(struct bt_conn *conn)
|
||||
int bt_bap_broadcast_assistant_discover(struct bt_conn *conn)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
@ -551,39 +571,39 @@ int bt_bass_client_discover(struct bt_conn *conn)
|
|||
}
|
||||
|
||||
/* Discover BASS on peer, setup handles and notify */
|
||||
(void)memset(&bass_client, 0, sizeof(bass_client));
|
||||
(void)memset(&broadcast_assistant, 0, sizeof(broadcast_assistant));
|
||||
(void)memcpy(&uuid, BT_UUID_BASS, sizeof(uuid));
|
||||
bass_client.disc_params.func = service_discover_func;
|
||||
bass_client.disc_params.uuid = &uuid.uuid;
|
||||
bass_client.disc_params.type = BT_GATT_DISCOVER_PRIMARY;
|
||||
bass_client.disc_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
|
||||
bass_client.disc_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
|
||||
broadcast_assistant.disc_params.func = service_discover_func;
|
||||
broadcast_assistant.disc_params.uuid = &uuid.uuid;
|
||||
broadcast_assistant.disc_params.type = BT_GATT_DISCOVER_PRIMARY;
|
||||
broadcast_assistant.disc_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
|
||||
broadcast_assistant.disc_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
|
||||
|
||||
err = bt_gatt_discover(conn, &bass_client.disc_params);
|
||||
err = bt_gatt_discover(conn, &broadcast_assistant.disc_params);
|
||||
if (err != 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
bass_client.discovering = true;
|
||||
broadcast_assistant.discovering = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bt_bass_client_register_cb(struct bt_bass_client_cb *cb)
|
||||
void bt_bap_broadcast_assistant_register_cb(struct bt_bap_broadcast_assistant_cb *cb)
|
||||
{
|
||||
bass_cbs = cb;
|
||||
broadcast_assistant_cbs = cb;
|
||||
}
|
||||
|
||||
int bt_bass_client_scan_start(struct bt_conn *conn, bool start_scan)
|
||||
int bt_bap_broadcast_assistant_scan_start(struct bt_conn *conn, bool start_scan)
|
||||
{
|
||||
struct bt_bass_cp_scan_start *cp;
|
||||
struct bt_bap_bass_cp_scan_start *cp;
|
||||
int err;
|
||||
|
||||
if (conn == NULL) {
|
||||
return -EINVAL;
|
||||
} else if (bass_client.cp_handle == 0) {
|
||||
} else if (broadcast_assistant.cp_handle == 0) {
|
||||
return -EINVAL;
|
||||
} else if (bass_client.busy) {
|
||||
} else if (broadcast_assistant.busy) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
@ -602,32 +622,32 @@ int bt_bass_client_scan_start(struct bt_conn *conn, bool start_scan)
|
|||
return err;
|
||||
}
|
||||
|
||||
bass_client.scanning = true;
|
||||
broadcast_assistant.scanning = true;
|
||||
}
|
||||
|
||||
/* Reset buffer before using */
|
||||
net_buf_simple_reset(&cp_buf);
|
||||
cp = net_buf_simple_add(&cp_buf, sizeof(*cp));
|
||||
|
||||
cp->opcode = BT_BASS_OP_SCAN_START;
|
||||
cp->opcode = BT_BAP_BASS_OP_SCAN_START;
|
||||
|
||||
return bt_bass_client_common_cp(conn, &cp_buf);
|
||||
return bt_bap_broadcast_assistant_common_cp(conn, &cp_buf);
|
||||
}
|
||||
|
||||
int bt_bass_client_scan_stop(struct bt_conn *conn)
|
||||
int bt_bap_broadcast_assistant_scan_stop(struct bt_conn *conn)
|
||||
{
|
||||
struct bt_bass_cp_scan_stop *cp;
|
||||
struct bt_bap_bass_cp_scan_stop *cp;
|
||||
int err;
|
||||
|
||||
if (conn == NULL) {
|
||||
return 0;
|
||||
} else if (bass_client.cp_handle == 0) {
|
||||
} else if (broadcast_assistant.cp_handle == 0) {
|
||||
return -EINVAL;
|
||||
} else if (bass_client.busy) {
|
||||
} else if (broadcast_assistant.busy) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (bass_client.scanning) {
|
||||
if (broadcast_assistant.scanning) {
|
||||
err = bt_le_scan_stop();
|
||||
if (err != 0) {
|
||||
BT_DBG("Could not stop scan (%d)", err);
|
||||
|
@ -635,27 +655,28 @@ int bt_bass_client_scan_stop(struct bt_conn *conn)
|
|||
return err;
|
||||
}
|
||||
|
||||
bass_client.scanning = false;
|
||||
broadcast_assistant.scanning = false;
|
||||
}
|
||||
|
||||
/* Reset buffer before using */
|
||||
net_buf_simple_reset(&cp_buf);
|
||||
cp = net_buf_simple_add(&cp_buf, sizeof(*cp));
|
||||
|
||||
cp->opcode = BT_BASS_OP_SCAN_STOP;
|
||||
cp->opcode = BT_BAP_BASS_OP_SCAN_STOP;
|
||||
|
||||
return bt_bass_client_common_cp(conn, &cp_buf);
|
||||
return bt_bap_broadcast_assistant_common_cp(conn, &cp_buf);
|
||||
}
|
||||
|
||||
int bt_bass_client_add_src(struct bt_conn *conn, struct bt_bass_add_src_param *param)
|
||||
int bt_bap_broadcast_assistant_add_src(struct bt_conn *conn,
|
||||
struct bt_bap_broadcast_assistant_add_src_param *param)
|
||||
{
|
||||
struct bt_bass_cp_add_src *cp;
|
||||
struct bt_bap_bass_cp_add_src *cp;
|
||||
|
||||
if (conn == NULL) {
|
||||
return 0;
|
||||
} else if (bass_client.cp_handle == 0) {
|
||||
} else if (broadcast_assistant.cp_handle == 0) {
|
||||
return -EINVAL;
|
||||
} else if (bass_client.busy) {
|
||||
} else if (broadcast_assistant.busy) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
@ -663,7 +684,7 @@ int bt_bass_client_add_src(struct bt_conn *conn, struct bt_bass_add_src_param *p
|
|||
net_buf_simple_reset(&cp_buf);
|
||||
cp = net_buf_simple_add(&cp_buf, sizeof(*cp));
|
||||
|
||||
cp->opcode = BT_BASS_OP_ADD_SRC;
|
||||
cp->opcode = BT_BAP_BASS_OP_ADD_SRC;
|
||||
cp->adv_sid = param->adv_sid;
|
||||
bt_addr_le_copy(&cp->addr, ¶m->addr);
|
||||
|
||||
|
@ -675,19 +696,19 @@ int bt_bass_client_add_src(struct bt_conn *conn, struct bt_bass_add_src_param *p
|
|||
/* TODO: Validate that we are synced to the peer address
|
||||
* before saying to use PAST - Requires additional per_adv_sync API
|
||||
*/
|
||||
cp->pa_sync = BT_BASS_PA_REQ_SYNC_PAST;
|
||||
cp->pa_sync = BT_BAP_BASS_PA_REQ_SYNC_PAST;
|
||||
} else {
|
||||
cp->pa_sync = BT_BASS_PA_REQ_SYNC;
|
||||
cp->pa_sync = BT_BAP_BASS_PA_REQ_SYNC;
|
||||
}
|
||||
} else {
|
||||
cp->pa_sync = BT_BASS_PA_REQ_NO_SYNC;
|
||||
cp->pa_sync = BT_BAP_BASS_PA_REQ_NO_SYNC;
|
||||
}
|
||||
|
||||
cp->pa_interval = sys_cpu_to_le16(param->pa_interval);
|
||||
|
||||
cp->num_subgroups = param->num_subgroups;
|
||||
for (int i = 0; i < param->num_subgroups; i++) {
|
||||
struct bt_bass_cp_subgroup *subgroup;
|
||||
struct bt_bap_bass_cp_subgroup *subgroup;
|
||||
const size_t subgroup_size = sizeof(subgroup->bis_sync) +
|
||||
sizeof(subgroup->metadata_len) +
|
||||
param->subgroups[i].metadata_len;
|
||||
|
@ -719,19 +740,19 @@ int bt_bass_client_add_src(struct bt_conn *conn, struct bt_bass_add_src_param *p
|
|||
|
||||
}
|
||||
|
||||
return bt_bass_client_common_cp(conn, &cp_buf);
|
||||
return bt_bap_broadcast_assistant_common_cp(conn, &cp_buf);
|
||||
}
|
||||
|
||||
int bt_bass_client_mod_src(struct bt_conn *conn,
|
||||
struct bt_bass_mod_src_param *param)
|
||||
int bt_bap_broadcast_assistant_mod_src(struct bt_conn *conn,
|
||||
struct bt_bap_broadcast_assistant_mod_src_param *param)
|
||||
{
|
||||
struct bt_bass_cp_mod_src *cp;
|
||||
struct bt_bap_bass_cp_mod_src *cp;
|
||||
|
||||
if (conn == NULL) {
|
||||
return 0;
|
||||
} else if (bass_client.cp_handle == 0) {
|
||||
} else if (broadcast_assistant.cp_handle == 0) {
|
||||
return -EINVAL;
|
||||
} else if (bass_client.busy) {
|
||||
} else if (broadcast_assistant.busy) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
@ -739,24 +760,24 @@ int bt_bass_client_mod_src(struct bt_conn *conn,
|
|||
net_buf_simple_reset(&cp_buf);
|
||||
cp = net_buf_simple_add(&cp_buf, sizeof(*cp));
|
||||
|
||||
cp->opcode = BT_BASS_OP_MOD_SRC;
|
||||
cp->opcode = BT_BAP_BASS_OP_MOD_SRC;
|
||||
cp->src_id = param->src_id;
|
||||
|
||||
if (param->pa_sync != 0) {
|
||||
if (BT_FEAT_LE_PAST_SEND(conn->le.features) &&
|
||||
BT_FEAT_LE_PAST_RECV(bt_dev.le.features)) {
|
||||
cp->pa_sync = BT_BASS_PA_REQ_SYNC_PAST;
|
||||
cp->pa_sync = BT_BAP_BASS_PA_REQ_SYNC_PAST;
|
||||
} else {
|
||||
cp->pa_sync = BT_BASS_PA_REQ_SYNC;
|
||||
cp->pa_sync = BT_BAP_BASS_PA_REQ_SYNC;
|
||||
}
|
||||
} else {
|
||||
cp->pa_sync = BT_BASS_PA_REQ_NO_SYNC;
|
||||
cp->pa_sync = BT_BAP_BASS_PA_REQ_NO_SYNC;
|
||||
}
|
||||
cp->pa_interval = sys_cpu_to_le16(param->pa_interval);
|
||||
|
||||
cp->num_subgroups = param->num_subgroups;
|
||||
for (int i = 0; i < param->num_subgroups; i++) {
|
||||
struct bt_bass_cp_subgroup *subgroup;
|
||||
struct bt_bap_bass_cp_subgroup *subgroup;
|
||||
const size_t subgroup_size = sizeof(subgroup->bis_sync) +
|
||||
sizeof(subgroup->metadata_len) +
|
||||
param->subgroups[i].metadata_len;
|
||||
|
@ -785,19 +806,20 @@ int bt_bass_client_mod_src(struct bt_conn *conn,
|
|||
}
|
||||
}
|
||||
|
||||
return bt_bass_client_common_cp(conn, &cp_buf);
|
||||
return bt_bap_broadcast_assistant_common_cp(conn, &cp_buf);
|
||||
}
|
||||
|
||||
int bt_bass_client_set_broadcast_code(struct bt_conn *conn, uint8_t src_id,
|
||||
uint8_t broadcast_code[BT_BASS_BROADCAST_CODE_SIZE])
|
||||
int bt_bap_broadcast_assistant_set_broadcast_code(
|
||||
struct bt_conn *conn, uint8_t src_id,
|
||||
uint8_t broadcast_code[BT_BAP_BROADCAST_CODE_SIZE])
|
||||
{
|
||||
struct bt_bass_cp_broadcase_code *cp;
|
||||
struct bt_bap_bass_cp_broadcase_code *cp;
|
||||
|
||||
if (conn == NULL) {
|
||||
return 0;
|
||||
} else if (bass_client.cp_handle == 0) {
|
||||
} else if (broadcast_assistant.cp_handle == 0) {
|
||||
return -EINVAL;
|
||||
} else if (bass_client.busy) {
|
||||
} else if (broadcast_assistant.busy) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
@ -805,24 +827,24 @@ int bt_bass_client_set_broadcast_code(struct bt_conn *conn, uint8_t src_id,
|
|||
net_buf_simple_reset(&cp_buf);
|
||||
cp = net_buf_simple_add(&cp_buf, sizeof(*cp));
|
||||
|
||||
cp->opcode = BT_BASS_OP_BROADCAST_CODE;
|
||||
cp->opcode = BT_BAP_BASS_OP_BROADCAST_CODE;
|
||||
cp->src_id = src_id;
|
||||
|
||||
(void)memcpy(cp->broadcast_code, broadcast_code,
|
||||
BT_BASS_BROADCAST_CODE_SIZE);
|
||||
BT_BAP_BROADCAST_CODE_SIZE);
|
||||
|
||||
return bt_bass_client_common_cp(conn, &cp_buf);
|
||||
return bt_bap_broadcast_assistant_common_cp(conn, &cp_buf);
|
||||
}
|
||||
|
||||
int bt_bass_client_rem_src(struct bt_conn *conn, uint8_t src_id)
|
||||
int bt_bap_broadcast_assistant_rem_src(struct bt_conn *conn, uint8_t src_id)
|
||||
{
|
||||
struct bt_bass_cp_rem_src *cp;
|
||||
struct bt_bap_bass_cp_rem_src *cp;
|
||||
|
||||
if (conn == NULL) {
|
||||
return 0;
|
||||
} else if (bass_client.cp_handle == 0) {
|
||||
} else if (broadcast_assistant.cp_handle == 0) {
|
||||
return -EINVAL;
|
||||
} else if (bass_client.busy) {
|
||||
} else if (broadcast_assistant.busy) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
@ -830,13 +852,14 @@ int bt_bass_client_rem_src(struct bt_conn *conn, uint8_t src_id)
|
|||
net_buf_simple_reset(&cp_buf);
|
||||
cp = net_buf_simple_add(&cp_buf, sizeof(*cp));
|
||||
|
||||
cp->opcode = BT_BASS_OP_REM_SRC;
|
||||
cp->opcode = BT_BAP_BASS_OP_REM_SRC;
|
||||
cp->src_id = src_id;
|
||||
|
||||
return bt_bass_client_common_cp(conn, &cp_buf);
|
||||
return bt_bap_broadcast_assistant_common_cp(conn, &cp_buf);
|
||||
}
|
||||
|
||||
int bt_bass_client_read_recv_state(struct bt_conn *conn, uint8_t idx)
|
||||
int bt_bap_broadcast_assistant_read_recv_state(struct bt_conn *conn,
|
||||
uint8_t idx)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
@ -844,20 +867,20 @@ int bt_bass_client_read_recv_state(struct bt_conn *conn, uint8_t idx)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bass_client.recv_state_handles[idx] == 0) {
|
||||
if (broadcast_assistant.recv_state_handles[idx] == 0) {
|
||||
BT_DBG("Handle not set");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bass_client.read_params.func = read_recv_state_cb;
|
||||
bass_client.read_params.handle_count = 1;
|
||||
bass_client.read_params.single.handle =
|
||||
bass_client.recv_state_handles[idx];
|
||||
broadcast_assistant.read_params.func = read_recv_state_cb;
|
||||
broadcast_assistant.read_params.handle_count = 1;
|
||||
broadcast_assistant.read_params.single.handle =
|
||||
broadcast_assistant.recv_state_handles[idx];
|
||||
|
||||
err = bt_gatt_read(conn, &bass_client.read_params);
|
||||
err = bt_gatt_read(conn, &broadcast_assistant.read_params);
|
||||
if (err != 0) {
|
||||
(void)memset(&bass_client.read_params, 0,
|
||||
sizeof(bass_client.read_params));
|
||||
(void)memset(&broadcast_assistant.read_params, 0,
|
||||
sizeof(broadcast_assistant.read_params));
|
||||
}
|
||||
|
||||
return err;
|
93
subsys/bluetooth/audio/bap_internal.h
Normal file
93
subsys/bluetooth/audio/bap_internal.h
Normal file
|
@ -0,0 +1,93 @@
|
|||
/** @file
|
||||
* @brief Internal header for Bluetooth BAP.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 Bose Corporation
|
||||
* Copyright (c) 2021-2022 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/types.h>
|
||||
#include <zephyr/bluetooth/conn.h>
|
||||
#include <zephyr/bluetooth/audio/audio.h>
|
||||
#include <zephyr/bluetooth/audio/bap.h>
|
||||
|
||||
#define BT_BAP_BASS_SCAN_STATE_NOT_SCANNING 0x00
|
||||
#define BT_BAP_BASS_SCAN_STATE_SCANNING 0x01
|
||||
|
||||
#define BT_BAP_BASS_OP_SCAN_STOP 0x00
|
||||
#define BT_BAP_BASS_OP_SCAN_START 0x01
|
||||
#define BT_BAP_BASS_OP_ADD_SRC 0x02
|
||||
#define BT_BAP_BASS_OP_MOD_SRC 0x03
|
||||
#define BT_BAP_BASS_OP_BROADCAST_CODE 0x04
|
||||
#define BT_BAP_BASS_OP_REM_SRC 0x05
|
||||
|
||||
#define BT_BAP_BASS_SCAN_STATE_IDLE 0x00
|
||||
#define BT_BAP_BASS_SCAN_STATE_SCANNING 0x01
|
||||
#define BT_BAP_BASS_SCAN_STATE_FAILED 0x02
|
||||
#define BT_BAP_BASS_SCAN_STATE_SYNCED 0x03
|
||||
|
||||
#define BT_BAP_BASS_PA_REQ_NO_SYNC 0x00
|
||||
#define BT_BAP_BASS_PA_REQ_SYNC_PAST 0x01
|
||||
#define BT_BAP_BASS_PA_REQ_SYNC 0x02
|
||||
|
||||
#define BT_BAP_BASS_VALID_OPCODE(opcode) \
|
||||
((opcode) >= BT_BAP_BASS_OP_SCAN_STOP && \
|
||||
(opcode) <= BT_BAP_BASS_OP_REM_SRC)
|
||||
|
||||
struct bt_bap_bass_cp_scan_stop {
|
||||
uint8_t opcode;
|
||||
} __packed;
|
||||
|
||||
struct bt_bap_bass_cp_scan_start {
|
||||
uint8_t opcode;
|
||||
} __packed;
|
||||
|
||||
struct bt_bap_bass_cp_subgroup {
|
||||
uint32_t bis_sync;
|
||||
uint8_t metadata_len;
|
||||
uint8_t metadata[0];
|
||||
} __packed;
|
||||
|
||||
struct bt_bap_bass_cp_add_src {
|
||||
uint8_t opcode;
|
||||
bt_addr_le_t addr;
|
||||
uint8_t adv_sid;
|
||||
uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE];
|
||||
uint8_t pa_sync;
|
||||
uint16_t pa_interval;
|
||||
uint8_t num_subgroups;
|
||||
struct bt_bap_bass_cp_subgroup subgroups[0];
|
||||
} __packed;
|
||||
|
||||
struct bt_bap_bass_cp_mod_src {
|
||||
uint8_t opcode;
|
||||
uint8_t src_id;
|
||||
uint8_t pa_sync;
|
||||
uint16_t pa_interval;
|
||||
uint8_t num_subgroups;
|
||||
struct bt_bap_bass_cp_subgroup subgroups[0];
|
||||
} __packed;
|
||||
|
||||
struct bt_bap_bass_cp_broadcase_code {
|
||||
uint8_t opcode;
|
||||
uint8_t src_id;
|
||||
uint8_t broadcast_code[16];
|
||||
} __packed;
|
||||
|
||||
struct bt_bap_bass_cp_rem_src {
|
||||
uint8_t opcode;
|
||||
uint8_t src_id;
|
||||
} __packed;
|
||||
|
||||
union bt_bap_bass_cp {
|
||||
uint8_t opcode;
|
||||
struct bt_bap_bass_cp_scan_stop scan_stop;
|
||||
struct bt_bap_bass_cp_scan_start scan_start;
|
||||
struct bt_bap_bass_cp_add_src add_src;
|
||||
struct bt_bap_bass_cp_mod_src mod_src;
|
||||
struct bt_bap_bass_cp_broadcase_code broadcast_code;
|
||||
struct bt_bap_bass_cp_rem_src rem_src;
|
||||
};
|
|
@ -1,8 +1,8 @@
|
|||
/* Bluetooth BASS */
|
||||
/* Bluetooth Scan Delegator */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 Bose Corporation
|
||||
* Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
* Copyright (c) 2021-2022 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -20,13 +20,13 @@
|
|||
#include <zephyr/bluetooth/gatt.h>
|
||||
#include <zephyr/bluetooth/buf.h>
|
||||
|
||||
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_BASS)
|
||||
#define LOG_MODULE_NAME bt_bass
|
||||
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_BAP_SCAN_DELEGATOR)
|
||||
#define LOG_MODULE_NAME bt_bap_scan_delegator
|
||||
#include "common/log.h"
|
||||
#include "common/bt_str.h"
|
||||
|
||||
#include "audio_internal.h"
|
||||
#include "bass_internal.h"
|
||||
#include "bap_internal.h"
|
||||
#include "../host/conn_internal.h"
|
||||
#include "../host/hci_core.h"
|
||||
|
||||
|
@ -36,19 +36,19 @@
|
|||
|
||||
NET_BUF_SIMPLE_DEFINE_STATIC(read_buf, BT_ATT_MAX_ATTRIBUTE_LEN);
|
||||
|
||||
struct bt_bass_client {
|
||||
struct broadcast_assistant {
|
||||
struct bt_conn *conn;
|
||||
uint8_t scanning;
|
||||
};
|
||||
|
||||
/* TODO: Merge bass_recv_state_internal_t and bt_bass_recv_state */
|
||||
/* TODO: Merge bass_recv_state_internal_t and bt_bap_scan_delegator_recv_state */
|
||||
struct bass_recv_state_internal {
|
||||
const struct bt_gatt_attr *attr;
|
||||
|
||||
bool active;
|
||||
uint8_t index;
|
||||
struct bt_bass_recv_state state;
|
||||
uint8_t broadcast_code[BT_BASS_BROADCAST_CODE_SIZE];
|
||||
struct bt_bap_scan_delegator_recv_state state;
|
||||
uint8_t broadcast_code[BT_BAP_BROADCAST_CODE_SIZE];
|
||||
uint16_t pa_interval;
|
||||
bool broadcast_code_received;
|
||||
struct bt_le_per_adv_sync *pa_sync;
|
||||
|
@ -61,16 +61,16 @@ struct bass_recv_state_internal {
|
|||
struct bt_iso_big *big;
|
||||
};
|
||||
|
||||
struct bt_bass_inst {
|
||||
struct bt_bap_scan_delegator_inst {
|
||||
uint8_t next_src_id;
|
||||
struct bt_bass_client client_configs[CONFIG_BT_MAX_CONN];
|
||||
struct broadcast_assistant assistant_configs[CONFIG_BT_MAX_CONN];
|
||||
struct bass_recv_state_internal recv_states
|
||||
[CONFIG_BT_BASS_RECV_STATE_COUNT];
|
||||
[CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT];
|
||||
};
|
||||
|
||||
static bool conn_cb_registered;
|
||||
static struct bt_bass_inst bass_inst;
|
||||
static struct bt_bass_cb *bass_cbs;
|
||||
static struct bt_bap_scan_delegator_inst scan_delegator;
|
||||
static struct bt_bap_scan_delegator_cb *scan_delegator_cbs;
|
||||
|
||||
static int bis_sync(struct bass_recv_state_internal *state);
|
||||
|
||||
|
@ -89,7 +89,8 @@ static void iso_connected(struct bt_iso_chan *chan)
|
|||
|
||||
static void iso_disconnected(struct bt_iso_chan *chan, uint8_t reason)
|
||||
{
|
||||
printk("ISO Channel %p disconnected with reason 0x%02x\n", chan, reason);
|
||||
printk("ISO Channel %p disconnected with reason 0x%02x\n",
|
||||
chan, reason);
|
||||
}
|
||||
|
||||
static struct bt_iso_chan_ops iso_ops = {
|
||||
|
@ -119,7 +120,7 @@ static bool bits_subset_of(uint32_t a, uint32_t b)
|
|||
|
||||
static bool valid_bis_syncs(uint32_t bis_sync)
|
||||
{
|
||||
if (bis_sync == BT_BASS_BIS_SYNC_NO_PREF) {
|
||||
if (bis_sync == BT_BAP_BIS_SYNC_NO_PREF) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -134,8 +135,8 @@ static bool bis_syncs_unique_or_no_pref(uint32_t requested_bis_syncs,
|
|||
uint32_t aggregated_bis_syncs)
|
||||
{
|
||||
return (requested_bis_syncs & aggregated_bis_syncs) != 0 &&
|
||||
requested_bis_syncs != BT_BASS_BIS_SYNC_NO_PREF &&
|
||||
aggregated_bis_syncs != BT_BASS_BIS_SYNC_NO_PREF;
|
||||
requested_bis_syncs != BT_BAP_BIS_SYNC_NO_PREF &&
|
||||
aggregated_bis_syncs != BT_BAP_BIS_SYNC_NO_PREF;
|
||||
}
|
||||
|
||||
static uint32_t aggregated_bis_syncs_get(const struct bass_recv_state_internal *recv_state)
|
||||
|
@ -151,7 +152,9 @@ static uint32_t aggregated_bis_syncs_get(const struct bass_recv_state_internal *
|
|||
|
||||
static void bt_debug_dump_recv_state(const struct bass_recv_state_internal *recv_state)
|
||||
{
|
||||
const struct bt_bass_recv_state *state = &recv_state->state;
|
||||
const struct bt_bap_scan_delegator_recv_state *state = &recv_state->state;
|
||||
const bool is_bad_code = state->encrypt_state ==
|
||||
BT_BAP_BIG_ENC_STATE_BAD_CODE;
|
||||
|
||||
BT_DBG("Receive State[%d]: src ID %u, addr %s, adv_sid %u, "
|
||||
"broadcast_id %u, pa_sync_state %u, "
|
||||
|
@ -159,13 +162,12 @@ static void bt_debug_dump_recv_state(const struct bass_recv_state_internal *recv
|
|||
recv_state->index, state->src_id, bt_addr_le_str(&state->addr),
|
||||
state->adv_sid, state->broadcast_id, state->pa_sync_state,
|
||||
state->encrypt_state,
|
||||
state->encrypt_state == BT_BASS_BIG_ENC_STATE_BAD_CODE ? ", bad code" : "",
|
||||
state->encrypt_state == BT_BASS_BIG_ENC_STATE_BAD_CODE ?
|
||||
bt_hex(state->bad_code, sizeof(state->bad_code)) : "",
|
||||
is_bad_code ? ", bad code" : "",
|
||||
is_bad_code ? bt_hex(state->bad_code, sizeof(state->bad_code)) : "",
|
||||
state->num_subgroups);
|
||||
|
||||
for (int i = 0; i < state->num_subgroups; i++) {
|
||||
const struct bt_bass_subgroup *subgroup = &state->subgroups[i];
|
||||
const struct bt_bap_scan_delegator_subgroup *subgroup = &state->subgroups[i];
|
||||
|
||||
BT_DBG("\tSubgroup[%d]: BIS sync %u (requested %u), metadata_len %u, metadata: %s",
|
||||
i, subgroup->bis_sync, subgroup->requested_bis_sync,
|
||||
|
@ -186,7 +188,7 @@ static void bass_notify_receive_state(const struct bass_recv_state_internal *sta
|
|||
|
||||
static void net_buf_put_recv_state(const struct bass_recv_state_internal *recv_state)
|
||||
{
|
||||
const struct bt_bass_recv_state *state = &recv_state->state;
|
||||
const struct bt_bap_scan_delegator_recv_state *state = &recv_state->state;
|
||||
|
||||
net_buf_simple_reset(&read_buf);
|
||||
|
||||
|
@ -200,13 +202,13 @@ static void net_buf_put_recv_state(const struct bass_recv_state_internal *recv_s
|
|||
(void)net_buf_simple_add_le24(&read_buf, state->broadcast_id);
|
||||
(void)net_buf_simple_add_u8(&read_buf, state->pa_sync_state);
|
||||
(void)net_buf_simple_add_u8(&read_buf, state->encrypt_state);
|
||||
if (state->encrypt_state == BT_BASS_BIG_ENC_STATE_BAD_CODE) {
|
||||
if (state->encrypt_state == BT_BAP_BIG_ENC_STATE_BAD_CODE) {
|
||||
(void)net_buf_simple_add_mem(&read_buf, &state->bad_code,
|
||||
sizeof(state->bad_code));
|
||||
}
|
||||
(void)net_buf_simple_add_u8(&read_buf, state->num_subgroups);
|
||||
for (int i = 0; i < state->num_subgroups; i++) {
|
||||
const struct bt_bass_subgroup *subgroup = &state->subgroups[i];
|
||||
const struct bt_bap_scan_delegator_subgroup *subgroup = &state->subgroups[i];
|
||||
|
||||
(void)net_buf_simple_add_le32(&read_buf, subgroup->bis_sync);
|
||||
(void)net_buf_simple_add_u8(&read_buf, subgroup->metadata_len);
|
||||
|
@ -215,26 +217,27 @@ static void net_buf_put_recv_state(const struct bass_recv_state_internal *recv_s
|
|||
}
|
||||
}
|
||||
|
||||
static void bass_disconnected(struct bt_conn *conn, uint8_t reason)
|
||||
static void scan_delegator_disconnected(struct bt_conn *conn, uint8_t reason)
|
||||
{
|
||||
int i;
|
||||
struct bt_bass_client *client = NULL;
|
||||
struct broadcast_assistant *assistant = NULL;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(bass_inst.client_configs); i++) {
|
||||
if (bass_inst.client_configs[i].conn == conn) {
|
||||
client = &bass_inst.client_configs[i];
|
||||
for (i = 0; i < ARRAY_SIZE(scan_delegator.assistant_configs); i++) {
|
||||
if (scan_delegator.assistant_configs[i].conn == conn) {
|
||||
assistant = &scan_delegator.assistant_configs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (client != NULL) {
|
||||
if (assistant != NULL) {
|
||||
BT_DBG("Instance %u with addr %s disconnected",
|
||||
i, bt_addr_le_str(bt_conn_get_dst(conn)));
|
||||
(void)memset(client, 0, sizeof(*client));
|
||||
(void)memset(assistant, 0, sizeof(*assistant));
|
||||
}
|
||||
}
|
||||
|
||||
static void bass_security_changed(struct bt_conn *conn, bt_security_t level,
|
||||
static void scan_delegator_security_changed(struct bt_conn *conn,
|
||||
bt_security_t level,
|
||||
enum bt_security_err err)
|
||||
{
|
||||
if (err != 0 || conn->encrypt == 0) {
|
||||
|
@ -246,8 +249,8 @@ static void bass_security_changed(struct bt_conn *conn, bt_security_t level,
|
|||
}
|
||||
|
||||
/* Notify all receive states after a bonded device reconnects */
|
||||
for (int i = 0; i < ARRAY_SIZE(bass_inst.recv_states); i++) {
|
||||
struct bass_recv_state_internal *state = &bass_inst.recv_states[i];
|
||||
for (int i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
|
||||
struct bass_recv_state_internal *state = &scan_delegator.recv_states[i];
|
||||
int err;
|
||||
|
||||
if (!state->active) {
|
||||
|
@ -260,27 +263,27 @@ static void bass_security_changed(struct bt_conn *conn, bt_security_t level,
|
|||
state->attr, read_buf.data,
|
||||
read_buf.len);
|
||||
if (err != 0) {
|
||||
BT_WARN("Could not notify receive state[%d] to reconnecting client: %d",
|
||||
BT_WARN("Could not notify receive state[%d] to reconnecting assistant: %d",
|
||||
i, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static struct bt_conn_cb conn_cb = {
|
||||
.disconnected = bass_disconnected,
|
||||
.security_changed = bass_security_changed,
|
||||
.disconnected = scan_delegator_disconnected,
|
||||
.security_changed = scan_delegator_security_changed,
|
||||
};
|
||||
|
||||
static struct bt_bass_client *get_bass_client(struct bt_conn *conn)
|
||||
static struct broadcast_assistant *get_bap_broadcast_assistant(struct bt_conn *conn)
|
||||
{
|
||||
struct bt_bass_client *new = NULL;
|
||||
struct broadcast_assistant *new = NULL;
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(bass_inst.client_configs); i++) {
|
||||
if (bass_inst.client_configs[i].conn == conn) {
|
||||
return &bass_inst.client_configs[i];
|
||||
for (int i = 0; i < ARRAY_SIZE(scan_delegator.assistant_configs); i++) {
|
||||
if (scan_delegator.assistant_configs[i].conn == conn) {
|
||||
return &scan_delegator.assistant_configs[i];
|
||||
} else if (new == NULL &&
|
||||
bass_inst.client_configs[i].conn == NULL) {
|
||||
new = &bass_inst.client_configs[i];
|
||||
scan_delegator.assistant_configs[i].conn == NULL) {
|
||||
new = &scan_delegator.assistant_configs[i];
|
||||
new->conn = conn;
|
||||
}
|
||||
}
|
||||
|
@ -299,11 +302,11 @@ static uint8_t next_src_id(void)
|
|||
bool unique = false;
|
||||
|
||||
while (!unique) {
|
||||
next_src_id = bass_inst.next_src_id++;
|
||||
next_src_id = scan_delegator.next_src_id++;
|
||||
unique = true;
|
||||
for (int i = 0; i < ARRAY_SIZE(bass_inst.recv_states); i++) {
|
||||
if (bass_inst.recv_states[i].active &&
|
||||
bass_inst.recv_states[i].state.src_id == next_src_id) {
|
||||
for (int i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
|
||||
if (scan_delegator.recv_states[i].active &&
|
||||
scan_delegator.recv_states[i].state.src_id == next_src_id) {
|
||||
unique = false;
|
||||
break;
|
||||
}
|
||||
|
@ -315,10 +318,10 @@ static uint8_t next_src_id(void)
|
|||
|
||||
static struct bass_recv_state_internal *bass_lookup_src_id(uint8_t src_id)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_SIZE(bass_inst.recv_states); i++) {
|
||||
if (bass_inst.recv_states[i].active &&
|
||||
bass_inst.recv_states[i].state.src_id == src_id) {
|
||||
return &bass_inst.recv_states[i];
|
||||
for (int i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
|
||||
if (scan_delegator.recv_states[i].active &&
|
||||
scan_delegator.recv_states[i].state.src_id == src_id) {
|
||||
return &scan_delegator.recv_states[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -327,9 +330,9 @@ static struct bass_recv_state_internal *bass_lookup_src_id(uint8_t src_id)
|
|||
|
||||
static struct bass_recv_state_internal *bass_lookup_pa_sync(struct bt_le_per_adv_sync *sync)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_SIZE(bass_inst.recv_states); i++) {
|
||||
if (bass_inst.recv_states[i].pa_sync == sync) {
|
||||
return &bass_inst.recv_states[i];
|
||||
for (int i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
|
||||
if (scan_delegator.recv_states[i].pa_sync == sync) {
|
||||
return &scan_delegator.recv_states[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -338,9 +341,10 @@ static struct bass_recv_state_internal *bass_lookup_pa_sync(struct bt_le_per_adv
|
|||
|
||||
static struct bass_recv_state_internal *bass_lookup_addr(const bt_addr_le_t *addr)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_SIZE(bass_inst.recv_states); i++) {
|
||||
if (bt_addr_le_eq(&bass_inst.recv_states[i].state.addr, addr)) {
|
||||
return &bass_inst.recv_states[i];
|
||||
for (int i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
|
||||
if (bt_addr_le_eq(&scan_delegator.recv_states[i].state.addr,
|
||||
addr)) {
|
||||
return &scan_delegator.recv_states[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -351,7 +355,7 @@ static uint16_t interval_to_sync_timeout(uint16_t pa_interval)
|
|||
{
|
||||
uint16_t pa_timeout;
|
||||
|
||||
if (pa_interval == BT_BASS_PA_INTERVAL_UNKNOWN) {
|
||||
if (pa_interval == BT_BAP_PA_INTERVAL_UNKNOWN) {
|
||||
/* Use maximum value to maximize chance of success */
|
||||
pa_timeout = BT_GAP_PER_ADV_MAX_TIMEOUT;
|
||||
} else {
|
||||
|
@ -392,15 +396,15 @@ static void pa_synced(struct bt_le_per_adv_sync *sync,
|
|||
state->pa_sync = sync;
|
||||
|
||||
(void)k_work_cancel_delayable(&state->pa_timer);
|
||||
state->state.pa_sync_state = BT_BASS_PA_STATE_SYNCED;
|
||||
state->state.pa_sync_state = BT_BAP_PA_STATE_SYNCED;
|
||||
state->pa_sync_pending = false;
|
||||
|
||||
bt_debug_dump_recv_state(state);
|
||||
net_buf_put_recv_state(state);
|
||||
bass_notify_receive_state(state);
|
||||
|
||||
if (bass_cbs != NULL && bass_cbs->pa_synced != NULL) {
|
||||
bass_cbs->pa_synced(&state->state, info);
|
||||
if (scan_delegator_cbs != NULL && scan_delegator_cbs->pa_synced != NULL) {
|
||||
scan_delegator_cbs->pa_synced(&state->state, info);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -412,15 +416,15 @@ static void pa_terminated(struct bt_le_per_adv_sync *sync,
|
|||
BT_DBG("Terminated");
|
||||
|
||||
if (state != NULL) {
|
||||
state->state.pa_sync_state = BT_BASS_PA_STATE_NOT_SYNCED;
|
||||
state->state.pa_sync_state = BT_BAP_PA_STATE_NOT_SYNCED;
|
||||
state->pa_sync_pending = false;
|
||||
|
||||
bt_debug_dump_recv_state(state);
|
||||
net_buf_put_recv_state(state);
|
||||
bass_notify_receive_state(state);
|
||||
|
||||
if (bass_cbs != NULL && bass_cbs->pa_term != NULL) {
|
||||
bass_cbs->pa_term(&state->state, info);
|
||||
if (scan_delegator_cbs != NULL && scan_delegator_cbs->pa_term != NULL) {
|
||||
scan_delegator_cbs->pa_term(&state->state, info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -432,8 +436,8 @@ static void pa_recv(struct bt_le_per_adv_sync *sync,
|
|||
struct bass_recv_state_internal *state = bass_lookup_pa_sync(sync);
|
||||
|
||||
if (state != NULL) {
|
||||
if (bass_cbs != NULL && bass_cbs->pa_recv != NULL) {
|
||||
bass_cbs->pa_recv(&state->state, info, buf);
|
||||
if (scan_delegator_cbs != NULL && scan_delegator_cbs->pa_recv != NULL) {
|
||||
scan_delegator_cbs->pa_recv(&state->state, info, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -459,10 +463,10 @@ static void biginfo_recv(struct bt_le_per_adv_sync *sync,
|
|||
* broadcast source, that should be in charge of
|
||||
* validating this.
|
||||
*/
|
||||
state->state.encrypt_state = BT_BASS_BIG_ENC_STATE_DEC;
|
||||
state->state.encrypt_state = BT_BAP_BIG_ENC_STATE_DEC;
|
||||
} else {
|
||||
/* Request broadcast code from client */
|
||||
state->state.encrypt_state = BT_BASS_BIG_ENC_STATE_BCODE_REQ;
|
||||
/* Request broadcast code from assistant */
|
||||
state->state.encrypt_state = BT_BAP_BIG_ENC_STATE_BCODE_REQ;
|
||||
}
|
||||
|
||||
bt_debug_dump_recv_state(state);
|
||||
|
@ -476,8 +480,8 @@ static void biginfo_recv(struct bt_le_per_adv_sync *sync,
|
|||
}
|
||||
}
|
||||
|
||||
if (bass_cbs != NULL && bass_cbs->biginfo != NULL) {
|
||||
bass_cbs->biginfo(&state->state, biginfo);
|
||||
if (scan_delegator_cbs != NULL && scan_delegator_cbs->biginfo != NULL) {
|
||||
scan_delegator_cbs->biginfo(&state->state, biginfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -498,8 +502,8 @@ static void pa_timer_handler(struct k_work *work)
|
|||
|
||||
__ASSERT(recv_state, "NULL receive state");
|
||||
|
||||
if (recv_state->state.pa_sync_state == BT_BASS_PA_STATE_INFO_REQ) {
|
||||
recv_state->state.pa_sync_state = BT_BASS_PA_STATE_NO_PAST;
|
||||
if (recv_state->state.pa_sync_state == BT_BAP_PA_STATE_INFO_REQ) {
|
||||
recv_state->state.pa_sync_state = BT_BAP_PA_STATE_NO_PAST;
|
||||
} else {
|
||||
int err = bt_le_per_adv_sync_delete(recv_state->pa_sync);
|
||||
|
||||
|
@ -507,7 +511,7 @@ static void pa_timer_handler(struct k_work *work)
|
|||
BT_ERR("Could not delete BASS pa_sync");
|
||||
}
|
||||
|
||||
recv_state->state.pa_sync_state = BT_BASS_PA_STATE_FAILED;
|
||||
recv_state->state.pa_sync_state = BT_BAP_PA_STATE_FAILED;
|
||||
}
|
||||
recv_state->pa_sync_pending = false;
|
||||
|
||||
|
@ -540,7 +544,7 @@ static int bis_sync(struct bass_recv_state_internal *state)
|
|||
if (param.bis_bitfield == 0) {
|
||||
/* Don't attempt to sync anything */
|
||||
return 0;
|
||||
} else if (param.bis_bitfield == BT_BASS_BIS_SYNC_NO_PREF) {
|
||||
} else if (param.bis_bitfield == BT_BAP_BIS_SYNC_NO_PREF) {
|
||||
param.bis_bitfield = 0;
|
||||
/* Attempt to sync to all BISes */
|
||||
for (int i = 0; i < state->biginfo_num_bis; i++) {
|
||||
|
@ -573,7 +577,7 @@ static int bis_sync(struct bass_recv_state_internal *state)
|
|||
}
|
||||
|
||||
/* We could start a timer for BIG sync but there is no way to let the
|
||||
* client know if it has timed out, so it doesn't really matter.
|
||||
* assistant know if it has timed out, so it doesn't really matter.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
@ -596,10 +600,10 @@ static int bis_sync_cancel(struct bass_recv_state_internal *state)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void bass_pa_sync_past(struct bt_conn *conn,
|
||||
static void scan_delegator_pa_sync_past(struct bt_conn *conn,
|
||||
struct bass_recv_state_internal *state)
|
||||
{
|
||||
struct bt_bass_recv_state *recv_state = &state->state;
|
||||
struct bt_bap_scan_delegator_recv_state *recv_state = &state->state;
|
||||
int err;
|
||||
struct bt_le_per_adv_sync_transfer_param param = { 0 };
|
||||
|
||||
|
@ -608,9 +612,9 @@ static void bass_pa_sync_past(struct bt_conn *conn,
|
|||
|
||||
err = bt_le_per_adv_sync_transfer_subscribe(conn, ¶m);
|
||||
if (err != 0) {
|
||||
recv_state->pa_sync_state = BT_BASS_PA_STATE_FAILED;
|
||||
recv_state->pa_sync_state = BT_BAP_PA_STATE_FAILED;
|
||||
} else {
|
||||
recv_state->pa_sync_state = BT_BASS_PA_STATE_INFO_REQ;
|
||||
recv_state->pa_sync_state = BT_BAP_PA_STATE_INFO_REQ;
|
||||
state->pa_sync_pending = true;
|
||||
|
||||
/* Multiply by 10 as param.timeout is in unit of 10ms */
|
||||
|
@ -619,9 +623,9 @@ static void bass_pa_sync_past(struct bt_conn *conn,
|
|||
}
|
||||
}
|
||||
|
||||
static void bass_pa_sync_no_past(struct bass_recv_state_internal *state)
|
||||
static void scan_delegator_pa_sync_no_past(struct bass_recv_state_internal *state)
|
||||
{
|
||||
struct bt_bass_recv_state *recv_state = &state->state;
|
||||
struct bt_bap_scan_delegator_recv_state *recv_state = &state->state;
|
||||
int err;
|
||||
struct bt_le_per_adv_sync_param param = { 0 };
|
||||
|
||||
|
@ -641,7 +645,7 @@ static void bass_pa_sync_no_past(struct bass_recv_state_internal *state)
|
|||
err = bt_le_per_adv_sync_create(¶m, &state->pa_sync);
|
||||
if (err != 0) {
|
||||
BT_WARN("Could not sync per adv: %d", err);
|
||||
recv_state->pa_sync_state = BT_BASS_PA_STATE_FAILED;
|
||||
recv_state->pa_sync_state = BT_BAP_PA_STATE_FAILED;
|
||||
} else {
|
||||
BT_DBG("PA sync pending for addr %s",
|
||||
bt_addr_le_str(&recv_state->addr));
|
||||
|
@ -651,9 +655,9 @@ static void bass_pa_sync_no_past(struct bass_recv_state_internal *state)
|
|||
}
|
||||
}
|
||||
|
||||
static void bass_pa_sync_cancel(struct bass_recv_state_internal *state)
|
||||
static void scan_delegator_pa_sync_cancel(struct bass_recv_state_internal *state)
|
||||
{
|
||||
struct bt_bass_recv_state *recv_state = &state->state;
|
||||
struct bt_bap_scan_delegator_recv_state *recv_state = &state->state;
|
||||
int err;
|
||||
|
||||
(void)k_work_cancel_delayable(&state->pa_timer);
|
||||
|
@ -668,48 +672,50 @@ static void bass_pa_sync_cancel(struct bass_recv_state_internal *state)
|
|||
} else {
|
||||
state->pa_sync_pending = false;
|
||||
state->pa_sync = NULL;
|
||||
recv_state->pa_sync_state = BT_BASS_PA_STATE_NOT_SYNCED;
|
||||
recv_state->pa_sync_state = BT_BAP_PA_STATE_NOT_SYNCED;
|
||||
}
|
||||
}
|
||||
|
||||
static void bass_pa_sync(struct bt_conn *conn, struct bass_recv_state_internal *state,
|
||||
static void scan_delegator_pa_sync(struct bt_conn *conn,
|
||||
struct bass_recv_state_internal *state,
|
||||
bool pa_past)
|
||||
{
|
||||
struct bt_bass_recv_state *recv_state = &state->state;
|
||||
struct bt_bap_scan_delegator_recv_state *recv_state = &state->state;
|
||||
|
||||
BT_DBG("pa_past %u, pa_interval 0x%04x", pa_past, state->pa_interval);
|
||||
|
||||
if (recv_state->pa_sync_state == BT_BASS_PA_STATE_SYNCED ||
|
||||
recv_state->pa_sync_state == BT_BASS_PA_STATE_INFO_REQ) {
|
||||
if (recv_state->pa_sync_state == BT_BAP_PA_STATE_SYNCED ||
|
||||
recv_state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (conn != NULL && pa_past &&
|
||||
BT_FEAT_LE_PAST_SEND(conn->le.features) &&
|
||||
BT_FEAT_LE_PAST_RECV(bt_dev.le.features)) {
|
||||
bass_pa_sync_past(conn, state);
|
||||
scan_delegator_pa_sync_past(conn, state);
|
||||
} else {
|
||||
bass_pa_sync_no_past(state);
|
||||
scan_delegator_pa_sync_no_past(state);
|
||||
}
|
||||
}
|
||||
|
||||
static int bass_add_source(struct bt_conn *conn, struct net_buf_simple *buf)
|
||||
static int scan_delegator_add_source(struct bt_conn *conn,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
struct bass_recv_state_internal *internal_state = NULL;
|
||||
struct bt_bass_recv_state *state;
|
||||
struct bt_bap_scan_delegator_recv_state *state;
|
||||
bt_addr_t *addr;
|
||||
uint8_t pa_sync;
|
||||
uint16_t pa_interval;
|
||||
uint32_t aggregated_bis_syncs = 0;
|
||||
|
||||
/* subtract 1 as the opcode has already been pulled */
|
||||
if (buf->len < sizeof(struct bt_bass_cp_add_src) - 1) {
|
||||
if (buf->len < sizeof(struct bt_bap_bass_cp_add_src) - 1) {
|
||||
BT_DBG("Invalid length %u", buf->size);
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
|
||||
}
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(bass_inst.recv_states); i++) {
|
||||
struct bass_recv_state_internal *state = &bass_inst.recv_states[i];
|
||||
for (int i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
|
||||
struct bass_recv_state_internal *state = &scan_delegator.recv_states[i];
|
||||
|
||||
if (!state->active) {
|
||||
internal_state = state;
|
||||
|
@ -743,7 +749,7 @@ static int bass_add_source(struct bt_conn *conn, struct net_buf_simple *buf)
|
|||
state->broadcast_id = net_buf_simple_pull_le24(buf);
|
||||
|
||||
pa_sync = net_buf_simple_pull_u8(buf);
|
||||
if (pa_sync > BT_BASS_PA_REQ_SYNC) {
|
||||
if (pa_sync > BT_BAP_BASS_PA_REQ_SYNC) {
|
||||
BT_DBG("Invalid PA sync value %u", pa_sync);
|
||||
return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
|
||||
}
|
||||
|
@ -751,14 +757,14 @@ static int bass_add_source(struct bt_conn *conn, struct net_buf_simple *buf)
|
|||
pa_interval = net_buf_simple_pull_le16(buf);
|
||||
|
||||
state->num_subgroups = net_buf_simple_pull_u8(buf);
|
||||
if (state->num_subgroups > CONFIG_BT_BASS_MAX_SUBGROUPS) {
|
||||
if (state->num_subgroups > CONFIG_BT_BAP_SCAN_DELEGATOR_MAX_SUBGROUPS) {
|
||||
BT_WARN("Too many subgroups %u/%u",
|
||||
state->num_subgroups, CONFIG_BT_BASS_MAX_SUBGROUPS);
|
||||
state->num_subgroups, CONFIG_BT_BAP_SCAN_DELEGATOR_MAX_SUBGROUPS);
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
|
||||
for (int i = 0; i < state->num_subgroups; i++) {
|
||||
struct bt_bass_subgroup *subgroup = &state->subgroups[i];
|
||||
struct bt_bap_scan_delegator_subgroup *subgroup = &state->subgroups[i];
|
||||
uint8_t *metadata;
|
||||
|
||||
if (buf->len < (sizeof(subgroup->bis_sync) + sizeof(subgroup->metadata_len))) {
|
||||
|
@ -769,7 +775,7 @@ static int bass_add_source(struct bt_conn *conn, struct net_buf_simple *buf)
|
|||
subgroup->requested_bis_sync = net_buf_simple_pull_le32(buf);
|
||||
|
||||
if (subgroup->requested_bis_sync &&
|
||||
pa_sync == BT_BASS_PA_REQ_NO_SYNC) {
|
||||
pa_sync == BT_BAP_BASS_PA_REQ_NO_SYNC) {
|
||||
BT_DBG("Cannot sync to BIS without PA");
|
||||
return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
|
||||
}
|
||||
|
@ -798,16 +804,17 @@ static int bass_add_source(struct bt_conn *conn, struct net_buf_simple *buf)
|
|||
}
|
||||
|
||||
|
||||
if (subgroup->metadata_len > CONFIG_BT_BASS_MAX_METADATA_LEN) {
|
||||
if (subgroup->metadata_len > CONFIG_BT_BAP_SCAN_DELEGATOR_MAX_METADATA_LEN) {
|
||||
BT_WARN("Metadata too long %u/%u",
|
||||
subgroup->metadata_len,
|
||||
CONFIG_BT_BASS_MAX_METADATA_LEN);
|
||||
CONFIG_BT_BAP_SCAN_DELEGATOR_MAX_METADATA_LEN);
|
||||
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
|
||||
metadata = net_buf_simple_pull_mem(buf, subgroup->metadata_len);
|
||||
(void)memcpy(subgroup->metadata, metadata, subgroup->metadata_len);
|
||||
(void)memcpy(subgroup->metadata, metadata,
|
||||
subgroup->metadata_len);
|
||||
}
|
||||
|
||||
if (buf->len != 0) {
|
||||
|
@ -819,9 +826,9 @@ static int bass_add_source(struct bt_conn *conn, struct net_buf_simple *buf)
|
|||
state->req_pa_sync_value = pa_sync;
|
||||
internal_state->pa_interval = pa_interval;
|
||||
|
||||
if (pa_sync != BT_BASS_PA_REQ_NO_SYNC) {
|
||||
bass_pa_sync(conn, internal_state,
|
||||
(pa_sync == BT_BASS_PA_REQ_SYNC_PAST));
|
||||
if (pa_sync != BT_BAP_BASS_PA_REQ_NO_SYNC) {
|
||||
scan_delegator_pa_sync(conn, internal_state,
|
||||
(pa_sync == BT_BAP_BASS_PA_REQ_SYNC_PAST));
|
||||
}
|
||||
|
||||
BT_DBG("Index %u: New source added: ID 0x%02x",
|
||||
|
@ -834,23 +841,25 @@ static int bass_add_source(struct bt_conn *conn, struct net_buf_simple *buf)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int bass_mod_src(struct bt_conn *conn, struct net_buf_simple *buf)
|
||||
static int scan_delegator_mod_src(struct bt_conn *conn,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
struct bass_recv_state_internal *internal_state;
|
||||
struct bt_bass_recv_state *state;
|
||||
struct bt_bap_scan_delegator_recv_state *state;
|
||||
uint8_t src_id;
|
||||
uint8_t old_pa_sync_state;
|
||||
bool state_changed = false;
|
||||
bool need_synced = false;
|
||||
uint16_t pa_interval;
|
||||
uint8_t num_subgroups;
|
||||
struct bt_bass_subgroup subgroups[CONFIG_BT_BASS_MAX_SUBGROUPS] = { 0 };
|
||||
struct bt_bap_scan_delegator_subgroup
|
||||
subgroups[CONFIG_BT_BAP_SCAN_DELEGATOR_MAX_SUBGROUPS] = { 0 };
|
||||
uint8_t pa_sync;
|
||||
uint32_t aggregated_bis_syncs = 0;
|
||||
int err;
|
||||
|
||||
/* subtract 1 as the opcode has already been pulled */
|
||||
if (buf->len < sizeof(struct bt_bass_cp_mod_src) - 1) {
|
||||
if (buf->len < sizeof(struct bt_bap_bass_cp_mod_src) - 1) {
|
||||
BT_DBG("Invalid length %u", buf->size);
|
||||
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
|
||||
|
@ -862,11 +871,11 @@ static int bass_mod_src(struct bt_conn *conn, struct net_buf_simple *buf)
|
|||
if (internal_state == NULL) {
|
||||
BT_DBG("Could not find state by src id %u", src_id);
|
||||
|
||||
return BT_GATT_ERR(BT_BASS_ERR_INVALID_SRC_ID);
|
||||
return BT_GATT_ERR(BT_BAP_BASS_ERR_INVALID_SRC_ID);
|
||||
}
|
||||
|
||||
pa_sync = net_buf_simple_pull_u8(buf);
|
||||
if (pa_sync > BT_BASS_PA_REQ_SYNC) {
|
||||
if (pa_sync > BT_BAP_BASS_PA_REQ_SYNC) {
|
||||
BT_DBG("Invalid PA sync value %u", pa_sync);
|
||||
|
||||
return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
|
||||
|
@ -875,15 +884,16 @@ static int bass_mod_src(struct bt_conn *conn, struct net_buf_simple *buf)
|
|||
pa_interval = net_buf_simple_pull_le16(buf);
|
||||
|
||||
num_subgroups = net_buf_simple_pull_u8(buf);
|
||||
if (num_subgroups > CONFIG_BT_BASS_MAX_SUBGROUPS) {
|
||||
if (num_subgroups > CONFIG_BT_BAP_SCAN_DELEGATOR_MAX_SUBGROUPS) {
|
||||
BT_WARN("Too many subgroups %u/%u",
|
||||
num_subgroups, CONFIG_BT_BASS_MAX_SUBGROUPS);
|
||||
num_subgroups,
|
||||
CONFIG_BT_BAP_SCAN_DELEGATOR_MAX_SUBGROUPS);
|
||||
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_subgroups; i++) {
|
||||
struct bt_bass_subgroup *subgroup = &subgroups[i];
|
||||
struct bt_bap_scan_delegator_subgroup *subgroup = &subgroups[i];
|
||||
uint8_t *metadata;
|
||||
|
||||
if (buf->len < (sizeof(subgroup->bis_sync) + sizeof(subgroup->metadata_len))) {
|
||||
|
@ -892,7 +902,8 @@ static int bass_mod_src(struct bt_conn *conn, struct net_buf_simple *buf)
|
|||
}
|
||||
|
||||
subgroup->requested_bis_sync = net_buf_simple_pull_le32(buf);
|
||||
if (subgroup->requested_bis_sync && pa_sync == BT_BASS_PA_REQ_NO_SYNC) {
|
||||
if (subgroup->requested_bis_sync &&
|
||||
pa_sync == BT_BAP_BASS_PA_REQ_NO_SYNC) {
|
||||
BT_DBG("Cannot sync to BIS without PA");
|
||||
return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
|
||||
}
|
||||
|
@ -918,10 +929,10 @@ static int bass_mod_src(struct bt_conn *conn, struct net_buf_simple *buf)
|
|||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
|
||||
}
|
||||
|
||||
if (subgroup->metadata_len > CONFIG_BT_BASS_MAX_METADATA_LEN) {
|
||||
if (subgroup->metadata_len > CONFIG_BT_BAP_SCAN_DELEGATOR_MAX_METADATA_LEN) {
|
||||
BT_WARN("Metadata too long %u/%u",
|
||||
subgroup->metadata_len,
|
||||
CONFIG_BT_BASS_MAX_METADATA_LEN);
|
||||
CONFIG_BT_BAP_SCAN_DELEGATOR_MAX_METADATA_LEN);
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
|
||||
|
@ -994,11 +1005,11 @@ static int bass_mod_src(struct bt_conn *conn, struct net_buf_simple *buf)
|
|||
}
|
||||
|
||||
/* Terminated PA let's re-sync later */
|
||||
bass_pa_sync_cancel(internal_state);
|
||||
scan_delegator_pa_sync_cancel(internal_state);
|
||||
|
||||
if (pa_sync != BT_BASS_PA_REQ_NO_SYNC) {
|
||||
bass_pa_sync(conn, internal_state,
|
||||
(pa_sync == BT_BASS_PA_REQ_SYNC_PAST));
|
||||
if (pa_sync != BT_BAP_BASS_PA_REQ_NO_SYNC) {
|
||||
scan_delegator_pa_sync(conn, internal_state,
|
||||
(pa_sync == BT_BAP_BASS_PA_REQ_SYNC_PAST));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1017,7 +1028,7 @@ static int bass_mod_src(struct bt_conn *conn, struct net_buf_simple *buf)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int bass_broadcast_code(struct net_buf_simple *buf)
|
||||
static int scan_delegator_broadcast_code(struct net_buf_simple *buf)
|
||||
{
|
||||
struct bass_recv_state_internal *internal_state;
|
||||
uint8_t src_id;
|
||||
|
@ -1025,7 +1036,7 @@ static int bass_broadcast_code(struct net_buf_simple *buf)
|
|||
int err;
|
||||
|
||||
/* subtract 1 as the opcode has already been pulled */
|
||||
if (buf->len != sizeof(struct bt_bass_cp_broadcase_code) - 1) {
|
||||
if (buf->len != sizeof(struct bt_bap_bass_cp_broadcase_code) - 1) {
|
||||
BT_DBG("Invalid length %u", buf->size);
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
|
||||
}
|
||||
|
@ -1035,7 +1046,7 @@ static int bass_broadcast_code(struct net_buf_simple *buf)
|
|||
|
||||
if (internal_state == NULL) {
|
||||
BT_DBG("Could not find state by src id %u", src_id);
|
||||
return BT_GATT_ERR(BT_BASS_ERR_INVALID_SRC_ID);
|
||||
return BT_GATT_ERR(BT_BAP_BASS_ERR_INVALID_SRC_ID);
|
||||
}
|
||||
|
||||
broadcast_code = net_buf_simple_pull_mem(buf, sizeof(internal_state->broadcast_code));
|
||||
|
@ -1064,14 +1075,14 @@ static int bass_broadcast_code(struct net_buf_simple *buf)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int bass_rem_src(struct net_buf_simple *buf)
|
||||
static int scan_delegator_rem_src(struct net_buf_simple *buf)
|
||||
{
|
||||
int err;
|
||||
struct bass_recv_state_internal *internal_state;
|
||||
uint8_t src_id;
|
||||
|
||||
/* subtract 1 as the opcode has already been pulled */
|
||||
if (buf->len != sizeof(struct bt_bass_cp_rem_src) - 1) {
|
||||
if (buf->len != sizeof(struct bt_bap_bass_cp_rem_src) - 1) {
|
||||
BT_DBG("Invalid length %u", buf->size);
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
|
||||
}
|
||||
|
@ -1081,11 +1092,11 @@ static int bass_rem_src(struct net_buf_simple *buf)
|
|||
|
||||
if (internal_state == NULL) {
|
||||
BT_DBG("Could not find state by src id %u", src_id);
|
||||
return BT_GATT_ERR(BT_BASS_ERR_INVALID_SRC_ID);
|
||||
return BT_GATT_ERR(BT_BAP_BASS_ERR_INVALID_SRC_ID);
|
||||
}
|
||||
|
||||
/* Terminate PA sync */
|
||||
bass_pa_sync_cancel(internal_state);
|
||||
scan_delegator_pa_sync_cancel(internal_state);
|
||||
|
||||
/* Check if successful */
|
||||
if (internal_state->pa_sync) {
|
||||
|
@ -1122,7 +1133,7 @@ static ssize_t write_control_point(struct bt_conn *conn,
|
|||
const void *data, uint16_t len,
|
||||
uint16_t offset, uint8_t flags)
|
||||
{
|
||||
struct bt_bass_client *bass_client;
|
||||
struct broadcast_assistant *bap_broadcast_assistant;
|
||||
struct net_buf_simple buf;
|
||||
uint8_t opcode;
|
||||
int err;
|
||||
|
@ -1137,72 +1148,72 @@ static ssize_t write_control_point(struct bt_conn *conn,
|
|||
|
||||
opcode = net_buf_simple_pull_u8(&buf);
|
||||
|
||||
if (!BT_BASS_VALID_OPCODE(opcode)) {
|
||||
return BT_GATT_ERR(BT_BASS_ERR_OPCODE_NOT_SUPPORTED);
|
||||
if (!BT_BAP_BASS_VALID_OPCODE(opcode)) {
|
||||
return BT_GATT_ERR(BT_BAP_BASS_ERR_OPCODE_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
bass_client = get_bass_client(conn);
|
||||
bap_broadcast_assistant = get_bap_broadcast_assistant(conn);
|
||||
|
||||
if (bass_client == NULL) {
|
||||
if (bap_broadcast_assistant == NULL) {
|
||||
return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY);
|
||||
}
|
||||
|
||||
LOG_HEXDUMP_DBG(data, len, "Data");
|
||||
|
||||
switch (opcode) {
|
||||
case BT_BASS_OP_SCAN_STOP:
|
||||
BT_DBG("Client stopping scanning");
|
||||
case BT_BAP_BASS_OP_SCAN_STOP:
|
||||
BT_DBG("Assistant stopping scanning");
|
||||
|
||||
if (buf.len != 0) {
|
||||
BT_DBG("Invalid length %u", buf.size);
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
|
||||
}
|
||||
|
||||
bass_client->scanning = false;
|
||||
bap_broadcast_assistant->scanning = false;
|
||||
break;
|
||||
case BT_BASS_OP_SCAN_START:
|
||||
BT_DBG("Client starting scanning");
|
||||
case BT_BAP_BASS_OP_SCAN_START:
|
||||
BT_DBG("Assistant starting scanning");
|
||||
|
||||
if (buf.len != 0) {
|
||||
BT_DBG("Invalid length %u", buf.size);
|
||||
return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
|
||||
}
|
||||
bass_client->scanning = true;
|
||||
bap_broadcast_assistant->scanning = true;
|
||||
break;
|
||||
case BT_BASS_OP_ADD_SRC:
|
||||
BT_DBG("Client adding source");
|
||||
case BT_BAP_BASS_OP_ADD_SRC:
|
||||
BT_DBG("Assistant adding source");
|
||||
|
||||
err = bass_add_source(conn, &buf);
|
||||
err = scan_delegator_add_source(conn, &buf);
|
||||
if (err != 0) {
|
||||
BT_DBG("Could not add source %d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
break;
|
||||
case BT_BASS_OP_MOD_SRC:
|
||||
BT_DBG("Client modifying source");
|
||||
case BT_BAP_BASS_OP_MOD_SRC:
|
||||
BT_DBG("Assistant modifying source");
|
||||
|
||||
err = bass_mod_src(conn, &buf);
|
||||
err = scan_delegator_mod_src(conn, &buf);
|
||||
if (err != 0) {
|
||||
BT_DBG("Could not modify source %d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
break;
|
||||
case BT_BASS_OP_BROADCAST_CODE:
|
||||
BT_DBG("Client setting broadcast code");
|
||||
case BT_BAP_BASS_OP_BROADCAST_CODE:
|
||||
BT_DBG("Assistant setting broadcast code");
|
||||
|
||||
err = bass_broadcast_code(&buf);
|
||||
err = scan_delegator_broadcast_code(&buf);
|
||||
if (err != 0) {
|
||||
BT_DBG("Could not set broadcast code");
|
||||
return err;
|
||||
}
|
||||
|
||||
break;
|
||||
case BT_BASS_OP_REM_SRC:
|
||||
BT_DBG("Client removing source");
|
||||
case BT_BAP_BASS_OP_REM_SRC:
|
||||
BT_DBG("Assistant removing source");
|
||||
|
||||
err = bass_rem_src(&buf);
|
||||
err = scan_delegator_rem_src(&buf);
|
||||
if (err != 0) {
|
||||
BT_DBG("Could not remove source %d", err);
|
||||
return err;
|
||||
|
@ -1227,8 +1238,8 @@ static ssize_t read_recv_state(struct bt_conn *conn,
|
|||
uint16_t len, uint16_t offset)
|
||||
{
|
||||
uint8_t idx = POINTER_TO_UINT(BT_AUDIO_CHRC_USER_DATA(attr));
|
||||
struct bass_recv_state_internal *recv_state = &bass_inst.recv_states[idx];
|
||||
struct bt_bass_recv_state *state = &recv_state->state;
|
||||
struct bass_recv_state_internal *recv_state = &scan_delegator.recv_states[idx];
|
||||
struct bt_bap_scan_delegator_recv_state *state = &recv_state->state;
|
||||
|
||||
if (recv_state->active) {
|
||||
BT_DBG("Index %u: Source ID 0x%02x", idx, state->src_id);
|
||||
|
@ -1260,48 +1271,50 @@ BT_GATT_SERVICE_DEFINE(bass_svc,
|
|||
BT_GATT_PERM_WRITE_ENCRYPT,
|
||||
NULL, write_control_point, NULL),
|
||||
RECEIVE_STATE_CHARACTERISTIC(0),
|
||||
#if CONFIG_BT_BASS_RECV_STATE_COUNT > 1
|
||||
#if CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 1
|
||||
RECEIVE_STATE_CHARACTERISTIC(1),
|
||||
#if CONFIG_BT_BASS_RECV_STATE_COUNT > 2
|
||||
#if CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 2
|
||||
RECEIVE_STATE_CHARACTERISTIC(2)
|
||||
#endif /* CONFIG_BT_BASS_RECV_STATE_COUNT > 2 */
|
||||
#endif /* CONFIG_BT_BASS_RECV_STATE_COUNT > 1 */
|
||||
#endif /* CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 2 */
|
||||
#endif /* CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 1 */
|
||||
);
|
||||
|
||||
static int bt_bass_init(const struct device *unused)
|
||||
static int bt_bap_scan_delegator_init(const struct device *unused)
|
||||
{
|
||||
/* Store the pointer to the first characteristic in each receive state */
|
||||
bass_inst.recv_states[0].attr = &bass_svc.attrs[3];
|
||||
bass_inst.recv_states[0].index = 0;
|
||||
#if CONFIG_BT_BASS_RECV_STATE_COUNT > 1
|
||||
bass_inst.recv_states[1].attr = &bass_svc.attrs[6];
|
||||
bass_inst.recv_states[1].index = 1;
|
||||
#if CONFIG_BT_BASS_RECV_STATE_COUNT > 2
|
||||
bass_inst.recv_states[2].attr = &bass_svc.attrs[9];
|
||||
bass_inst.recv_states[2].index = 2;
|
||||
#endif /* CONFIG_BT_BASS_RECV_STATE_COUNT > 2 */
|
||||
#endif /* CONFIG_BT_BASS_RECV_STATE_COUNT > 1 */
|
||||
scan_delegator.recv_states[0].attr = &bass_svc.attrs[3];
|
||||
scan_delegator.recv_states[0].index = 0;
|
||||
#if CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 1
|
||||
scan_delegator.recv_states[1].attr = &bass_svc.attrs[6];
|
||||
scan_delegator.recv_states[1].index = 1;
|
||||
#if CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 2
|
||||
scan_delegator.recv_states[2].attr = &bass_svc.attrs[9];
|
||||
scan_delegator.recv_states[2].index = 2;
|
||||
#endif /* CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 2 */
|
||||
#endif /* CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 1 */
|
||||
|
||||
bt_le_per_adv_sync_cb_register(&pa_sync_cb);
|
||||
for (int i = 0; i < ARRAY_SIZE(bass_inst.recv_states); i++) {
|
||||
k_work_init_delayable(&bass_inst.recv_states[i].pa_timer,
|
||||
for (int i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
|
||||
k_work_init_delayable(&scan_delegator.recv_states[i].pa_timer,
|
||||
pa_timer_handler);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEVICE_DEFINE(bt_bass, "bt_bass", &bt_bass_init, NULL, NULL, NULL,
|
||||
DEVICE_DEFINE(bt_bap_scan_delegator, "bt_bap_scan_delegator",
|
||||
&bt_bap_scan_delegator_init, NULL, NULL, NULL,
|
||||
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, NULL);
|
||||
|
||||
/****************************** PUBLIC API ******************************/
|
||||
void bt_bass_register_cb(struct bt_bass_cb *cb)
|
||||
void bt_bap_scan_delegator_register_cb(struct bt_bap_scan_delegator_cb *cb)
|
||||
{
|
||||
bass_cbs = cb;
|
||||
scan_delegator_cbs = cb;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_TESTING)
|
||||
int bt_bass_set_sync_state(uint8_t src_id, uint8_t pa_sync_state,
|
||||
uint32_t bis_synced[CONFIG_BT_BASS_MAX_SUBGROUPS],
|
||||
int bt_bap_scan_delegator_set_sync_state(
|
||||
uint8_t src_id, uint8_t pa_sync_state,
|
||||
uint32_t bis_synced[CONFIG_BT_BAP_SCAN_DELEGATOR_MAX_SUBGROUPS],
|
||||
uint8_t encrypt_state)
|
||||
{
|
||||
struct bass_recv_state_internal *recv_state =
|
||||
|
@ -1310,17 +1323,17 @@ int bt_bass_set_sync_state(uint8_t src_id, uint8_t pa_sync_state,
|
|||
|
||||
if (recv_state == NULL) {
|
||||
return -EINVAL;
|
||||
} else if (encrypt_state > BT_BASS_BIG_ENC_STATE_BAD_CODE) {
|
||||
} else if (encrypt_state > BT_BAP_BIG_ENC_STATE_BAD_CODE) {
|
||||
return -EINVAL;
|
||||
} else if (pa_sync_state > BT_BASS_PA_STATE_NO_PAST) {
|
||||
} else if (pa_sync_state > BT_BAP_PA_STATE_NO_PAST) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (int i = 0; i < recv_state->state.num_subgroups; i++) {
|
||||
struct bt_bass_subgroup *subgroup = &recv_state->state.subgroups[i];
|
||||
struct bt_bap_scan_delegator_subgroup *subgroup = &recv_state->state.subgroups[i];
|
||||
|
||||
if (bis_synced[i] != 0 &&
|
||||
pa_sync_state == BT_BASS_PA_STATE_NOT_SYNCED) {
|
||||
pa_sync_state == BT_BAP_PA_STATE_NOT_SYNCED) {
|
||||
BT_DBG("Cannot set BIS sync when PA sync is not synced");
|
||||
|
||||
return -EINVAL;
|
||||
|
@ -1350,7 +1363,7 @@ int bt_bass_set_sync_state(uint8_t src_id, uint8_t pa_sync_state,
|
|||
recv_state->state.pa_sync_state = pa_sync_state;
|
||||
recv_state->state.encrypt_state = encrypt_state;
|
||||
|
||||
if (recv_state->state.encrypt_state == BT_BASS_BIG_ENC_STATE_BAD_CODE) {
|
||||
if (recv_state->state.encrypt_state == BT_BAP_BIG_ENC_STATE_BAD_CODE) {
|
||||
(void)memcpy(recv_state->state.bad_code,
|
||||
recv_state->broadcast_code,
|
||||
sizeof(recv_state->state.bad_code));
|
||||
|
@ -1367,17 +1380,17 @@ int bt_bass_set_sync_state(uint8_t src_id, uint8_t pa_sync_state,
|
|||
}
|
||||
#endif
|
||||
|
||||
int bt_bass_remove_source(uint8_t src_id)
|
||||
int bt_bap_scan_delegator_remove_source(uint8_t src_id)
|
||||
{
|
||||
struct net_buf_simple buf;
|
||||
struct bt_bass_cp_rem_src cp = {
|
||||
.opcode = BT_BASS_OP_REM_SRC,
|
||||
struct bt_bap_bass_cp_rem_src cp = {
|
||||
.opcode = BT_BAP_BASS_OP_REM_SRC,
|
||||
.src_id = src_id
|
||||
};
|
||||
|
||||
net_buf_simple_init_with_data(&buf, (void *)&cp, sizeof(cp));
|
||||
|
||||
if (bass_rem_src(&buf) == 0) {
|
||||
if (scan_delegator_rem_src(&buf) == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return -EINVAL;
|
|
@ -1,93 +0,0 @@
|
|||
/** @file
|
||||
* @brief Internal header for Bluetooth BASS.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 Bose Corporation
|
||||
* Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/types.h>
|
||||
#include <zephyr/bluetooth/conn.h>
|
||||
#include <zephyr/bluetooth/audio/bass.h>
|
||||
|
||||
#define BT_BASS_SCAN_STATE_NOT_SCANNING 0x00
|
||||
#define BT_BASS_SCAN_STATE_SCANNING 0x01
|
||||
|
||||
#define BT_BASS_OP_SCAN_STOP 0x00
|
||||
#define BT_BASS_OP_SCAN_START 0x01
|
||||
#define BT_BASS_OP_ADD_SRC 0x02
|
||||
#define BT_BASS_OP_MOD_SRC 0x03
|
||||
#define BT_BASS_OP_BROADCAST_CODE 0x04
|
||||
#define BT_BASS_OP_REM_SRC 0x05
|
||||
|
||||
#define BT_BASS_SCAN_STATE_IDLE 0x00
|
||||
#define BT_BASS_SCAN_STATE_SCANNING 0x01
|
||||
#define BT_BASS_SCAN_STATE_FAILED 0x02
|
||||
#define BT_BASS_SCAN_STATE_SYNCED 0x03
|
||||
|
||||
#define BT_BASS_PA_REQ_NO_SYNC 0x00
|
||||
#define BT_BASS_PA_REQ_SYNC_PAST 0x01
|
||||
#define BT_BASS_PA_REQ_SYNC 0x02
|
||||
|
||||
#define BT_BASS_BROADCAST_ID_SIZE 3
|
||||
|
||||
#define BT_BASS_VALID_OPCODE(opcode) \
|
||||
((opcode) >= BT_BASS_OP_SCAN_STOP && (opcode) <= BT_BASS_OP_REM_SRC)
|
||||
|
||||
struct bt_bass_cp_scan_stop {
|
||||
uint8_t opcode;
|
||||
} __packed;
|
||||
|
||||
struct bt_bass_cp_scan_start {
|
||||
uint8_t opcode;
|
||||
} __packed;
|
||||
|
||||
struct bt_bass_cp_subgroup {
|
||||
uint32_t bis_sync;
|
||||
uint8_t metadata_len;
|
||||
uint8_t metadata[0];
|
||||
} __packed;
|
||||
|
||||
struct bt_bass_cp_add_src {
|
||||
uint8_t opcode;
|
||||
bt_addr_le_t addr;
|
||||
uint8_t adv_sid;
|
||||
uint8_t broadcast_id[BT_BASS_BROADCAST_ID_SIZE];
|
||||
uint8_t pa_sync;
|
||||
uint16_t pa_interval;
|
||||
uint8_t num_subgroups;
|
||||
struct bt_bass_cp_subgroup subgroups[0];
|
||||
} __packed;
|
||||
|
||||
struct bt_bass_cp_mod_src {
|
||||
uint8_t opcode;
|
||||
uint8_t src_id;
|
||||
uint8_t pa_sync;
|
||||
uint16_t pa_interval;
|
||||
uint8_t num_subgroups;
|
||||
struct bt_bass_cp_subgroup subgroups[0];
|
||||
} __packed;
|
||||
|
||||
struct bt_bass_cp_broadcase_code {
|
||||
uint8_t opcode;
|
||||
uint8_t src_id;
|
||||
uint8_t broadcast_code[16];
|
||||
} __packed;
|
||||
|
||||
struct bt_bass_cp_rem_src {
|
||||
uint8_t opcode;
|
||||
uint8_t src_id;
|
||||
} __packed;
|
||||
|
||||
union bt_bass_cp {
|
||||
uint8_t opcode;
|
||||
struct bt_bass_cp_scan_stop scan_stop;
|
||||
struct bt_bass_cp_scan_start scan_start;
|
||||
struct bt_bass_cp_add_src add_src;
|
||||
struct bt_bass_cp_mod_src mod_src;
|
||||
struct bt_bass_cp_broadcase_code broadcast_code;
|
||||
struct bt_bass_cp_rem_src rem_src;
|
||||
};
|
|
@ -32,7 +32,11 @@ config BT_L2CAP_TX_MTU
|
|||
default 253 if BT_BREDR
|
||||
default 69 if BT_MESH_GATT
|
||||
default 65 if BT_SMP
|
||||
default 64 if BT_AUDIO_UNICAST_SERVER || BT_AUDIO_UNICAST_CLIENT || BT_AUDIO_BROADCAST_SINK || BT_BASS || BT_BASS_CLIENT
|
||||
default 64 if BT_AUDIO_UNICAST_SERVER || \
|
||||
BT_AUDIO_UNICAST_CLIENT || \
|
||||
BT_AUDIO_BROADCAST_SINK || \
|
||||
BT_BAP_SCAN_DELEGATOR || \
|
||||
BT_BAP_BROADCAST_ASSISTANT
|
||||
default 49 if BT_HAS || BT_HAS_CLIENT
|
||||
default 23
|
||||
range 65 2000 if BT_SMP
|
||||
|
|
|
@ -93,12 +93,12 @@ zephyr_library_sources_ifdef(
|
|||
)
|
||||
|
||||
zephyr_library_sources_ifdef(
|
||||
CONFIG_BT_BASS
|
||||
bass.c
|
||||
CONFIG_BT_BAP_SCAN_DELEGATOR
|
||||
bap_scan_delegator.c
|
||||
)
|
||||
zephyr_library_sources_ifdef(
|
||||
CONFIG_BT_BASS_CLIENT
|
||||
bass_client.c
|
||||
CONFIG_BT_BAP_BROADCAST_ASSISTANT
|
||||
bap_broadcast_assistant.c
|
||||
)
|
||||
|
||||
zephyr_library_sources_ifdef(
|
||||
|
|
|
@ -1995,7 +1995,7 @@ ssize_t audio_ad_data_add(struct bt_data *data_array, const size_t data_array_si
|
|||
static const uint8_t ad_ext_uuid16[] = {
|
||||
IF_ENABLED(CONFIG_BT_MICP_MIC_DEV, (BT_UUID_16_ENCODE(BT_UUID_MICS_VAL),))
|
||||
IF_ENABLED(CONFIG_BT_ASCS, (BT_UUID_16_ENCODE(BT_UUID_ASCS_VAL),))
|
||||
IF_ENABLED(CONFIG_BT_BASS, (BT_UUID_16_ENCODE(BT_UUID_BASS_VAL),))
|
||||
IF_ENABLED(CONFIG_BT_BAP_SCAN_DELEGATOR, (BT_UUID_16_ENCODE(BT_UUID_BASS_VAL),))
|
||||
IF_ENABLED(CONFIG_BT_PACS, (BT_UUID_16_ENCODE(BT_UUID_PACS_VAL),))
|
||||
IF_ENABLED(CONFIG_BT_GTBS, (BT_UUID_16_ENCODE(BT_UUID_GTBS_VAL),))
|
||||
IF_ENABLED(CONFIG_BT_TBS, (BT_UUID_16_ENCODE(BT_UUID_TBS_VAL),))
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* @file
|
||||
* @brief Shell APIs for Bluetooth BASS client
|
||||
*
|
||||
* Copyright (c) 2020-2021 Nordic Semiconductor ASA
|
||||
* Copyright (c) 2020-2022 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -16,11 +16,11 @@
|
|||
#include <zephyr/bluetooth/gatt.h>
|
||||
#include <zephyr/bluetooth/bluetooth.h>
|
||||
#include <zephyr/bluetooth/hci.h>
|
||||
#include <zephyr/bluetooth/audio/bass.h>
|
||||
#include <zephyr/bluetooth/audio/bap.h>
|
||||
#include "bt.h"
|
||||
#include "../host/hci_core.h"
|
||||
|
||||
static void bass_client_discover_cb(struct bt_conn *conn, int err,
|
||||
static void bap_broadcast_assistant_discover_cb(struct bt_conn *conn, int err,
|
||||
uint8_t recv_state_count)
|
||||
{
|
||||
if (err != 0) {
|
||||
|
@ -32,7 +32,7 @@ static void bass_client_discover_cb(struct bt_conn *conn, int err,
|
|||
|
||||
}
|
||||
|
||||
static void bass_client_scan_cb(const struct bt_le_scan_recv_info *info,
|
||||
static void bap_broadcast_assistant_scan_cb(const struct bt_le_scan_recv_info *info,
|
||||
uint32_t broadcast_id)
|
||||
{
|
||||
char le_addr[BT_ADDR_LE_STR_LEN];
|
||||
|
@ -60,11 +60,13 @@ static bool metadata_entry(struct bt_data *data, void *user_data)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void bass_client_recv_state_cb(struct bt_conn *conn, int err,
|
||||
const struct bt_bass_recv_state *state)
|
||||
static void bap_broadcast_assistant_recv_state_cb(
|
||||
struct bt_conn *conn, int err,
|
||||
const struct bt_bap_scan_delegator_recv_state *state)
|
||||
{
|
||||
char le_addr[BT_ADDR_LE_STR_LEN];
|
||||
char bad_code[33];
|
||||
bool is_bad_code;
|
||||
|
||||
if (err != 0) {
|
||||
shell_error(ctx_shell, "BASS recv state read failed (%d)", err);
|
||||
|
@ -72,17 +74,18 @@ static void bass_client_recv_state_cb(struct bt_conn *conn, int err,
|
|||
}
|
||||
|
||||
bt_addr_le_to_str(&state->addr, le_addr, sizeof(le_addr));
|
||||
bin2hex(state->bad_code, BT_BASS_BROADCAST_CODE_SIZE,
|
||||
bin2hex(state->bad_code, BT_BAP_BROADCAST_CODE_SIZE,
|
||||
bad_code, sizeof(bad_code));
|
||||
|
||||
is_bad_code = state->encrypt_state == BT_BAP_BIG_ENC_STATE_BAD_CODE;
|
||||
shell_print(ctx_shell, "BASS recv state: src_id %u, addr %s, "
|
||||
"sid %u, sync_state %u, encrypt_state %u%s%s",
|
||||
state->src_id, le_addr, state->adv_sid,
|
||||
state->pa_sync_state, state->encrypt_state,
|
||||
state->encrypt_state == BT_BASS_BIG_ENC_STATE_BAD_CODE ? ", bad code" : "",
|
||||
bad_code);
|
||||
is_bad_code ? ", bad code" : "", bad_code);
|
||||
|
||||
for (int i = 0; i < state->num_subgroups; i++) {
|
||||
const struct bt_bass_subgroup *subgroup = &state->subgroups[i];
|
||||
const struct bt_bap_scan_delegator_subgroup *subgroup = &state->subgroups[i];
|
||||
struct net_buf_simple buf;
|
||||
|
||||
shell_print(ctx_shell, "\t[%d]: BIS sync %u, metadata_len %u",
|
||||
|
@ -94,7 +97,7 @@ static void bass_client_recv_state_cb(struct bt_conn *conn, int err,
|
|||
}
|
||||
|
||||
|
||||
if (state->pa_sync_state == BT_BASS_PA_STATE_INFO_REQ) {
|
||||
if (state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ) {
|
||||
struct bt_le_per_adv_sync *per_adv_sync = NULL;
|
||||
struct bt_le_ext_adv *ext_adv = NULL;
|
||||
|
||||
|
@ -158,12 +161,14 @@ static void bass_client_recv_state_cb(struct bt_conn *conn, int err,
|
|||
err);
|
||||
}
|
||||
} else {
|
||||
shell_error(ctx_shell, "Could not send PA to BASS server");
|
||||
shell_error(ctx_shell,
|
||||
"Could not send PA to Scan Delegator");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void bass_client_recv_state_removed_cb(struct bt_conn *conn, int err,
|
||||
static void bap_broadcast_assistant_recv_state_removed_cb(struct bt_conn *conn,
|
||||
int err,
|
||||
uint8_t src_id)
|
||||
{
|
||||
if (err != 0) {
|
||||
|
@ -174,7 +179,7 @@ static void bass_client_recv_state_removed_cb(struct bt_conn *conn, int err,
|
|||
}
|
||||
}
|
||||
|
||||
static void bass_client_scan_start_cb(struct bt_conn *conn, int err)
|
||||
static void bap_broadcast_assistant_scan_start_cb(struct bt_conn *conn, int err)
|
||||
{
|
||||
if (err != 0) {
|
||||
shell_error(ctx_shell, "BASS scan start failed (%d)", err);
|
||||
|
@ -183,7 +188,7 @@ static void bass_client_scan_start_cb(struct bt_conn *conn, int err)
|
|||
}
|
||||
}
|
||||
|
||||
static void bass_client_scan_stop_cb(struct bt_conn *conn, int err)
|
||||
static void bap_broadcast_assistant_scan_stop_cb(struct bt_conn *conn, int err)
|
||||
{
|
||||
if (err != 0) {
|
||||
shell_error(ctx_shell, "BASS scan stop failed (%d)", err);
|
||||
|
@ -192,7 +197,7 @@ static void bass_client_scan_stop_cb(struct bt_conn *conn, int err)
|
|||
}
|
||||
}
|
||||
|
||||
static void bass_client_add_src_cb(struct bt_conn *conn, int err)
|
||||
static void bap_broadcast_assistant_add_src_cb(struct bt_conn *conn, int err)
|
||||
{
|
||||
if (err != 0) {
|
||||
shell_error(ctx_shell, "BASS add source failed (%d)", err);
|
||||
|
@ -201,7 +206,7 @@ static void bass_client_add_src_cb(struct bt_conn *conn, int err)
|
|||
}
|
||||
}
|
||||
|
||||
static void bass_client_mod_src_cb(struct bt_conn *conn, int err)
|
||||
static void bap_broadcast_assistant_mod_src_cb(struct bt_conn *conn, int err)
|
||||
{
|
||||
if (err != 0) {
|
||||
shell_error(ctx_shell, "BASS modify source failed (%d)", err);
|
||||
|
@ -210,7 +215,8 @@ static void bass_client_mod_src_cb(struct bt_conn *conn, int err)
|
|||
}
|
||||
}
|
||||
|
||||
static void bass_client_broadcast_code_cb(struct bt_conn *conn, int err)
|
||||
static void bap_broadcast_assistant_broadcast_code_cb(struct bt_conn *conn,
|
||||
int err)
|
||||
{
|
||||
if (err != 0) {
|
||||
shell_error(ctx_shell, "BASS broadcast code failed (%d)", err);
|
||||
|
@ -219,7 +225,7 @@ static void bass_client_broadcast_code_cb(struct bt_conn *conn, int err)
|
|||
}
|
||||
}
|
||||
|
||||
static void bass_client_rem_src_cb(struct bt_conn *conn, int err)
|
||||
static void bap_broadcast_assistant_rem_src_cb(struct bt_conn *conn, int err)
|
||||
{
|
||||
if (err != 0) {
|
||||
shell_error(ctx_shell, "BASS remove source failed (%d)", err);
|
||||
|
@ -228,27 +234,27 @@ static void bass_client_rem_src_cb(struct bt_conn *conn, int err)
|
|||
}
|
||||
}
|
||||
|
||||
static struct bt_bass_client_cb cbs = {
|
||||
.discover = bass_client_discover_cb,
|
||||
.scan = bass_client_scan_cb,
|
||||
.recv_state = bass_client_recv_state_cb,
|
||||
.recv_state_removed = bass_client_recv_state_removed_cb,
|
||||
.scan_start = bass_client_scan_start_cb,
|
||||
.scan_stop = bass_client_scan_stop_cb,
|
||||
.add_src = bass_client_add_src_cb,
|
||||
.mod_src = bass_client_mod_src_cb,
|
||||
.broadcast_code = bass_client_broadcast_code_cb,
|
||||
.rem_src = bass_client_rem_src_cb,
|
||||
static struct bt_bap_broadcast_assistant_cb cbs = {
|
||||
.discover = bap_broadcast_assistant_discover_cb,
|
||||
.scan = bap_broadcast_assistant_scan_cb,
|
||||
.recv_state = bap_broadcast_assistant_recv_state_cb,
|
||||
.recv_state_removed = bap_broadcast_assistant_recv_state_removed_cb,
|
||||
.scan_start = bap_broadcast_assistant_scan_start_cb,
|
||||
.scan_stop = bap_broadcast_assistant_scan_stop_cb,
|
||||
.add_src = bap_broadcast_assistant_add_src_cb,
|
||||
.mod_src = bap_broadcast_assistant_mod_src_cb,
|
||||
.broadcast_code = bap_broadcast_assistant_broadcast_code_cb,
|
||||
.rem_src = bap_broadcast_assistant_rem_src_cb,
|
||||
};
|
||||
|
||||
static int cmd_bass_client_discover(const struct shell *sh, size_t argc,
|
||||
char **argv)
|
||||
static int cmd_bap_broadcast_assistant_discover(const struct shell *sh,
|
||||
size_t argc, char **argv)
|
||||
{
|
||||
int result;
|
||||
|
||||
bt_bass_client_register_cb(&cbs);
|
||||
bt_bap_broadcast_assistant_register_cb(&cbs);
|
||||
|
||||
result = bt_bass_client_discover(default_conn);
|
||||
result = bt_bap_broadcast_assistant_discover(default_conn);
|
||||
if (result) {
|
||||
shell_print(sh, "Fail: %d", result);
|
||||
}
|
||||
|
@ -256,8 +262,8 @@ static int cmd_bass_client_discover(const struct shell *sh, size_t argc,
|
|||
return result;
|
||||
}
|
||||
|
||||
static int cmd_bass_client_scan_start(const struct shell *sh, size_t argc,
|
||||
char **argv)
|
||||
static int cmd_bap_broadcast_assistant_scan_start(const struct shell *sh,
|
||||
size_t argc, char **argv)
|
||||
{
|
||||
int result;
|
||||
int start_scan = false;
|
||||
|
@ -271,7 +277,8 @@ static int cmd_bass_client_scan_start(const struct shell *sh, size_t argc,
|
|||
}
|
||||
}
|
||||
|
||||
result = bt_bass_client_scan_start(default_conn, (bool)start_scan);
|
||||
result = bt_bap_broadcast_assistant_scan_start(default_conn,
|
||||
(bool)start_scan);
|
||||
if (result) {
|
||||
shell_print(sh, "Fail: %d", result);
|
||||
}
|
||||
|
@ -279,12 +286,12 @@ static int cmd_bass_client_scan_start(const struct shell *sh, size_t argc,
|
|||
return result;
|
||||
}
|
||||
|
||||
static int cmd_bass_client_scan_stop(const struct shell *sh, size_t argc,
|
||||
char **argv)
|
||||
static int cmd_bap_broadcast_assistant_scan_stop(const struct shell *sh,
|
||||
size_t argc, char **argv)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = bt_bass_client_scan_stop(default_conn);
|
||||
result = bt_bap_broadcast_assistant_scan_stop(default_conn);
|
||||
if (result) {
|
||||
shell_print(sh, "Fail: %d", result);
|
||||
}
|
||||
|
@ -292,12 +299,12 @@ static int cmd_bass_client_scan_stop(const struct shell *sh, size_t argc,
|
|||
return result;
|
||||
}
|
||||
|
||||
static int cmd_bass_client_add_src(const struct shell *sh, size_t argc,
|
||||
char **argv)
|
||||
static int cmd_bap_broadcast_assistant_add_src(const struct shell *sh,
|
||||
size_t argc, char **argv)
|
||||
{
|
||||
int result;
|
||||
struct bt_bass_add_src_param param = { 0 };
|
||||
struct bt_bass_subgroup subgroup = { 0 };
|
||||
struct bt_bap_broadcast_assistant_add_src_param param = { 0 };
|
||||
struct bt_bap_scan_delegator_subgroup subgroup = { 0 };
|
||||
|
||||
result = bt_addr_le_from_str(argv[1], argv[2], ¶m.addr);
|
||||
if (result) {
|
||||
|
@ -328,7 +335,7 @@ static int cmd_bass_client_add_src(const struct shell *sh, size_t argc,
|
|||
if (argc > 6) {
|
||||
param.pa_interval = strtol(argv[6], NULL, 0);
|
||||
} else {
|
||||
param.pa_interval = BT_BASS_PA_INTERVAL_UNKNOWN;
|
||||
param.pa_interval = BT_BAP_PA_INTERVAL_UNKNOWN;
|
||||
}
|
||||
|
||||
/* TODO: Support multiple subgroups */
|
||||
|
@ -355,7 +362,7 @@ static int cmd_bass_client_add_src(const struct shell *sh, size_t argc,
|
|||
param.num_subgroups = 1;
|
||||
param.subgroups = &subgroup;
|
||||
|
||||
result = bt_bass_client_add_src(default_conn, ¶m);
|
||||
result = bt_bap_broadcast_assistant_add_src(default_conn, ¶m);
|
||||
if (result) {
|
||||
shell_print(sh, "Fail: %d", result);
|
||||
}
|
||||
|
@ -363,12 +370,12 @@ static int cmd_bass_client_add_src(const struct shell *sh, size_t argc,
|
|||
return result;
|
||||
}
|
||||
|
||||
static int cmd_bass_client_mod_src(const struct shell *sh, size_t argc,
|
||||
char **argv)
|
||||
static int cmd_bap_broadcast_assistant_mod_src(const struct shell *sh,
|
||||
size_t argc, char **argv)
|
||||
{
|
||||
int result;
|
||||
struct bt_bass_mod_src_param param = { 0 };
|
||||
struct bt_bass_subgroup subgroup = { 0 };
|
||||
struct bt_bap_broadcast_assistant_mod_src_param param = { 0 };
|
||||
struct bt_bap_scan_delegator_subgroup subgroup = { 0 };
|
||||
|
||||
param.src_id = strtol(argv[1], NULL, 0);
|
||||
if (param.src_id < 0 || param.src_id > UINT8_MAX) {
|
||||
|
@ -385,7 +392,7 @@ static int cmd_bass_client_mod_src(const struct shell *sh, size_t argc,
|
|||
if (argc > 3) {
|
||||
param.pa_interval = strtol(argv[3], NULL, 0);
|
||||
} else {
|
||||
param.pa_interval = BT_BASS_PA_INTERVAL_UNKNOWN;
|
||||
param.pa_interval = BT_BAP_PA_INTERVAL_UNKNOWN;
|
||||
}
|
||||
|
||||
/* TODO: Support multiple subgroups */
|
||||
|
@ -412,7 +419,7 @@ static int cmd_bass_client_mod_src(const struct shell *sh, size_t argc,
|
|||
param.num_subgroups = 1;
|
||||
param.subgroups = &subgroup;
|
||||
|
||||
result = bt_bass_client_mod_src(default_conn, ¶m);
|
||||
result = bt_bap_broadcast_assistant_mod_src(default_conn, ¶m);
|
||||
if (result) {
|
||||
shell_print(sh, "Fail: %d", result);
|
||||
}
|
||||
|
@ -420,12 +427,12 @@ static int cmd_bass_client_mod_src(const struct shell *sh, size_t argc,
|
|||
return result;
|
||||
}
|
||||
|
||||
static int cmd_bass_client_broadcast_code(const struct shell *sh,
|
||||
static int cmd_bap_broadcast_assistant_broadcast_code(const struct shell *sh,
|
||||
size_t argc, char **argv)
|
||||
{
|
||||
int result;
|
||||
int src_id;
|
||||
uint8_t broadcast_code[BT_BASS_BROADCAST_CODE_SIZE] = { 0 };
|
||||
uint8_t broadcast_code[BT_BAP_BROADCAST_CODE_SIZE] = { 0 };
|
||||
|
||||
src_id = strtol(argv[1], NULL, 0);
|
||||
if (src_id < 0 || src_id > UINT8_MAX) {
|
||||
|
@ -437,7 +444,8 @@ static int cmd_bass_client_broadcast_code(const struct shell *sh,
|
|||
broadcast_code[i] = strtol(argv[i + 2], NULL, 0);
|
||||
}
|
||||
|
||||
result = bt_bass_client_set_broadcast_code(default_conn, src_id,
|
||||
result = bt_bap_broadcast_assistant_set_broadcast_code(default_conn,
|
||||
src_id,
|
||||
broadcast_code);
|
||||
if (result) {
|
||||
shell_print(sh, "Fail: %d", result);
|
||||
|
@ -446,8 +454,8 @@ static int cmd_bass_client_broadcast_code(const struct shell *sh,
|
|||
return result;
|
||||
}
|
||||
|
||||
static int cmd_bass_client_rem_src(const struct shell *sh, size_t argc,
|
||||
char **argv)
|
||||
static int cmd_bap_broadcast_assistant_rem_src(const struct shell *sh,
|
||||
size_t argc, char **argv)
|
||||
{
|
||||
int result;
|
||||
int src_id;
|
||||
|
@ -458,7 +466,7 @@ static int cmd_bass_client_rem_src(const struct shell *sh, size_t argc,
|
|||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
result = bt_bass_client_rem_src(default_conn, src_id);
|
||||
result = bt_bap_broadcast_assistant_rem_src(default_conn, src_id);
|
||||
if (result) {
|
||||
shell_print(sh, "Fail: %d", result);
|
||||
}
|
||||
|
@ -466,7 +474,7 @@ static int cmd_bass_client_rem_src(const struct shell *sh, size_t argc,
|
|||
return result;
|
||||
}
|
||||
|
||||
static int cmd_bass_client_read_recv_state(const struct shell *sh,
|
||||
static int cmd_bap_broadcast_assistant_read_recv_state(const struct shell *sh,
|
||||
size_t argc, char **argv)
|
||||
{
|
||||
int result;
|
||||
|
@ -478,7 +486,7 @@ static int cmd_bass_client_read_recv_state(const struct shell *sh,
|
|||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
result = bt_bass_client_read_recv_state(default_conn, idx);
|
||||
result = bt_bap_broadcast_assistant_read_recv_state(default_conn, idx);
|
||||
if (result) {
|
||||
shell_print(sh, "Fail: %d", result);
|
||||
}
|
||||
|
@ -486,7 +494,8 @@ static int cmd_bass_client_read_recv_state(const struct shell *sh,
|
|||
return result;
|
||||
}
|
||||
|
||||
static int cmd_bass_client(const struct shell *sh, size_t argc, char **argv)
|
||||
static int cmd_bap_broadcast_assistant(const struct shell *sh, size_t argc,
|
||||
char **argv)
|
||||
{
|
||||
if (argc > 1) {
|
||||
shell_error(sh, "%s unknown parameter: %s",
|
||||
|
@ -498,39 +507,39 @@ static int cmd_bass_client(const struct shell *sh, size_t argc, char **argv)
|
|||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
SHELL_STATIC_SUBCMD_SET_CREATE(bass_client_cmds,
|
||||
SHELL_STATIC_SUBCMD_SET_CREATE(bap_broadcast_assistant_cmds,
|
||||
SHELL_CMD_ARG(discover, NULL,
|
||||
"Discover BASS on the server",
|
||||
cmd_bass_client_discover, 1, 0),
|
||||
cmd_bap_broadcast_assistant_discover, 1, 0),
|
||||
SHELL_CMD_ARG(scan_start, NULL,
|
||||
"Start scanning for broadcasters",
|
||||
cmd_bass_client_scan_start, 1, 0),
|
||||
cmd_bap_broadcast_assistant_scan_start, 1, 0),
|
||||
SHELL_CMD_ARG(scan_stop, NULL,
|
||||
"Stop scanning for BISs",
|
||||
cmd_bass_client_scan_stop, 1, 0),
|
||||
cmd_bap_broadcast_assistant_scan_stop, 1, 0),
|
||||
SHELL_CMD_ARG(add_src, NULL,
|
||||
"Add a source <address: XX:XX:XX:XX:XX:XX> "
|
||||
"<type: public/random> <adv_sid> <sync_pa> "
|
||||
"<broadcast_id> [<pa_interval>] [<sync_bis>] "
|
||||
"[<metadata>]",
|
||||
cmd_bass_client_add_src, 6, 3),
|
||||
cmd_bap_broadcast_assistant_add_src, 6, 3),
|
||||
SHELL_CMD_ARG(mod_src, NULL,
|
||||
"Set sync <src_id> <sync_pa> [<pa_interval>] "
|
||||
"[<sync_bis>] [<metadata>]",
|
||||
cmd_bass_client_mod_src, 3, 2),
|
||||
cmd_bap_broadcast_assistant_mod_src, 3, 2),
|
||||
SHELL_CMD_ARG(broadcast_code, NULL,
|
||||
"Send a space separated broadcast code of up to 16 bytes "
|
||||
"<src_id> [broadcast code]",
|
||||
cmd_bass_client_broadcast_code, 2, 16),
|
||||
cmd_bap_broadcast_assistant_broadcast_code, 2, 16),
|
||||
SHELL_CMD_ARG(rem_src, NULL,
|
||||
"Remove a source <src_id>",
|
||||
cmd_bass_client_rem_src, 2, 0),
|
||||
cmd_bap_broadcast_assistant_rem_src, 2, 0),
|
||||
SHELL_CMD_ARG(read_state, NULL,
|
||||
"Remove a source <index>",
|
||||
cmd_bass_client_read_recv_state, 2, 0),
|
||||
cmd_bap_broadcast_assistant_read_recv_state, 2, 0),
|
||||
SHELL_SUBCMD_SET_END
|
||||
);
|
||||
|
||||
SHELL_CMD_ARG_REGISTER(bass_client, &bass_client_cmds,
|
||||
"Bluetooth BASS client shell commands",
|
||||
cmd_bass_client, 1, 1);
|
||||
SHELL_CMD_ARG_REGISTER(bap_broadcast_assistant, &bap_broadcast_assistant_cmds,
|
||||
"Bluetooth BAP broadcast assistant client shell commands",
|
||||
cmd_bap_broadcast_assistant, 1, 1);
|
|
@ -1,8 +1,8 @@
|
|||
/**
|
||||
* @file
|
||||
* @brief Shell APIs for Bluetooth BASS
|
||||
* @brief Shell APIs for Bluetooth BAP scan delegator
|
||||
*
|
||||
* Copyright (c) 2020-2021 Nordic Semiconductor ASA
|
||||
* Copyright (c) 2020-2022 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -15,25 +15,27 @@
|
|||
#include <stdlib.h>
|
||||
#include <zephyr/bluetooth/gatt.h>
|
||||
#include <zephyr/bluetooth/bluetooth.h>
|
||||
#include <zephyr/bluetooth/audio/bass.h>
|
||||
#include <zephyr/bluetooth/audio/bap.h>
|
||||
#include "bt.h"
|
||||
|
||||
static void pa_synced(struct bt_bass_recv_state *recv_state,
|
||||
static void pa_synced(struct bt_bap_scan_delegator_recv_state *recv_state,
|
||||
const struct bt_le_per_adv_sync_synced_info *info)
|
||||
{
|
||||
shell_print(ctx_shell, "BASS receive state %p was PA synced",
|
||||
shell_print(ctx_shell,
|
||||
"BAP scan delegator receive state %p was PA synced",
|
||||
recv_state);
|
||||
}
|
||||
|
||||
static void pa_term(struct bt_bass_recv_state *recv_state,
|
||||
static void pa_term(struct bt_bap_scan_delegator_recv_state *recv_state,
|
||||
const struct bt_le_per_adv_sync_term_info *info)
|
||||
{
|
||||
shell_print(ctx_shell, "BASS receive state %p PA synced terminated",
|
||||
shell_print(ctx_shell,
|
||||
"BAP scan delegator receive state %p PA synced terminated",
|
||||
recv_state);
|
||||
|
||||
}
|
||||
|
||||
static void pa_recv(struct bt_bass_recv_state *recv_state,
|
||||
static void pa_recv(struct bt_bap_scan_delegator_recv_state *recv_state,
|
||||
const struct bt_le_per_adv_sync_recv_info *info,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
|
@ -49,26 +51,28 @@ static void pa_recv(struct bt_bass_recv_state *recv_state,
|
|||
|
||||
}
|
||||
|
||||
static struct bt_bass_cb cbs = {
|
||||
static struct bt_bap_scan_delegator_cb cbs = {
|
||||
.pa_synced = pa_synced,
|
||||
.pa_term = pa_term,
|
||||
.pa_recv = pa_recv
|
||||
};
|
||||
|
||||
static int cmd_bass_init(const struct shell *sh, size_t argc, char **argv)
|
||||
static int cmd_bap_scan_delegator_init(const struct shell *sh, size_t argc,
|
||||
char **argv)
|
||||
{
|
||||
bt_bass_register_cb(&cbs);
|
||||
bt_bap_scan_delegator_register_cb(&cbs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_bass_synced(const struct shell *sh, size_t argc, char **argv)
|
||||
static int cmd_bap_scan_delegator_synced(const struct shell *sh, size_t argc,
|
||||
char **argv)
|
||||
{
|
||||
int result;
|
||||
long src_id;
|
||||
long pa_sync_state;
|
||||
long bis_synced;
|
||||
long encrypted;
|
||||
uint32_t bis_syncs[CONFIG_BT_BASS_MAX_SUBGROUPS];
|
||||
uint32_t bis_syncs[CONFIG_BT_BAP_SCAN_DELEGATOR_MAX_SUBGROUPS];
|
||||
|
||||
src_id = strtol(argv[1], NULL, 0);
|
||||
if (src_id < 0 || src_id > UINT8_MAX) {
|
||||
|
@ -77,7 +81,8 @@ static int cmd_bass_synced(const struct shell *sh, size_t argc, char **argv)
|
|||
}
|
||||
|
||||
pa_sync_state = strtol(argv[2], NULL, 0);
|
||||
if (pa_sync_state < 0 || pa_sync_state > BT_BASS_PA_STATE_NO_PAST) {
|
||||
if (pa_sync_state < 0 ||
|
||||
pa_sync_state > BT_BAP_PA_STATE_NO_PAST) {
|
||||
shell_error(sh, "Invalid pa_sync_state %ld", pa_sync_state);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
@ -93,8 +98,8 @@ static int cmd_bass_synced(const struct shell *sh, size_t argc, char **argv)
|
|||
|
||||
encrypted = strtol(argv[4], NULL, 0);
|
||||
|
||||
result = bt_bass_set_sync_state(src_id, pa_sync_state, bis_syncs,
|
||||
encrypted);
|
||||
result = bt_bap_scan_delegator_set_sync_state(src_id, pa_sync_state,
|
||||
bis_syncs, encrypted);
|
||||
if (result != 0) {
|
||||
shell_print(sh, "Fail: %d", result);
|
||||
}
|
||||
|
@ -102,7 +107,8 @@ static int cmd_bass_synced(const struct shell *sh, size_t argc, char **argv)
|
|||
return result;
|
||||
}
|
||||
|
||||
static int cmd_bass(const struct shell *sh, size_t argc, char **argv)
|
||||
static int cmd_bap_scan_delegator(const struct shell *sh, size_t argc,
|
||||
char **argv)
|
||||
{
|
||||
if (argc > 1) {
|
||||
shell_error(sh, "%s unknown parameter: %s",
|
||||
|
@ -114,15 +120,16 @@ static int cmd_bass(const struct shell *sh, size_t argc, char **argv)
|
|||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
SHELL_STATIC_SUBCMD_SET_CREATE(bass_cmds,
|
||||
SHELL_STATIC_SUBCMD_SET_CREATE(bap_scan_delegator_cmds,
|
||||
SHELL_CMD_ARG(init, NULL,
|
||||
"Initialize the service and register callbacks",
|
||||
cmd_bass_init, 1, 0),
|
||||
cmd_bap_scan_delegator_init, 1, 0),
|
||||
SHELL_CMD_ARG(synced, NULL,
|
||||
"Set server scan state <src_id> <pa_synced> <bis_syncs> "
|
||||
"<enc_state>", cmd_bass_synced, 5, 0),
|
||||
"<enc_state>", cmd_bap_scan_delegator_synced, 5, 0),
|
||||
SHELL_SUBCMD_SET_END
|
||||
);
|
||||
|
||||
SHELL_CMD_ARG_REGISTER(bass, &bass_cmds, "Bluetooth BASS shell commands",
|
||||
cmd_bass, 1, 1);
|
||||
SHELL_CMD_ARG_REGISTER(bap_scan_delegator, &bap_scan_delegator_cmds,
|
||||
"Bluetooth BAP scan delegator shell commands",
|
||||
cmd_bap_scan_delegator, 1, 1);
|
|
@ -99,8 +99,8 @@ CONFIG_BT_OTS_MAX_OBJ_CNT=0x30
|
|||
CONFIG_BT_OTS_CLIENT=y
|
||||
|
||||
# Broadcast Audio Scan Service and client
|
||||
CONFIG_BT_BASS=y
|
||||
CONFIG_BT_BASS_CLIENT=y
|
||||
CONFIG_BT_BAP_SCAN_DELEGATOR=y
|
||||
CONFIG_BT_BAP_BROADCAST_ASSISTANT=y
|
||||
|
||||
# Hearing Access
|
||||
CONFIG_BT_HAS=y
|
||||
|
@ -140,8 +140,8 @@ CONFIG_BT_AUDIO_DEBUG_BROADCAST_SOURCE=y
|
|||
CONFIG_BT_DEBUG_ASCS=y
|
||||
CONFIG_BT_DEBUG_PACS=y
|
||||
CONFIG_BT_AUDIO_DEBUG_STREAM=y
|
||||
CONFIG_BT_DEBUG_BASS=y
|
||||
CONFIG_BT_DEBUG_BASS_CLIENT=y
|
||||
CONFIG_BT_DEBUG_BAP_SCAN_DELEGATOR=y
|
||||
CONFIG_BT_DEBUG_BAP_BROADCAST_ASSISTANT=y
|
||||
CONFIG_BT_DEBUG_HAS=y
|
||||
CONFIG_BT_DEBUG_HAS_CLIENT=y
|
||||
CONFIG_BT_DEBUG_CAP_ACCEPTOR=y
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
* Copyright (c) 2021-2022 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_BT_BASS_CLIENT
|
||||
#ifdef CONFIG_BT_BAP_BROADCAST_ASSISTANT
|
||||
|
||||
#include <zephyr/bluetooth/bluetooth.h>
|
||||
#include <zephyr/bluetooth/hci.h>
|
||||
#include <zephyr/bluetooth/audio/bass.h>
|
||||
#include <zephyr/bluetooth/audio/bap.h>
|
||||
#include "../../../../../subsys/bluetooth/host/hci_core.h"
|
||||
#include "common.h"
|
||||
|
||||
|
@ -46,7 +46,7 @@ static const char *phy2str(uint8_t phy)
|
|||
}
|
||||
}
|
||||
|
||||
static void bass_client_discover_cb(struct bt_conn *conn, int err,
|
||||
static void bap_broadcast_assistant_discover_cb(struct bt_conn *conn, int err,
|
||||
uint8_t recv_state_count)
|
||||
{
|
||||
if (err != 0) {
|
||||
|
@ -58,7 +58,7 @@ static void bass_client_discover_cb(struct bt_conn *conn, int err,
|
|||
g_discovery_complete = true;
|
||||
}
|
||||
|
||||
static void bass_client_scan_cb(const struct bt_le_scan_recv_info *info,
|
||||
static void bap_broadcast_assistant_scan_cb(const struct bt_le_scan_recv_info *info,
|
||||
uint32_t broadcast_id)
|
||||
{
|
||||
char le_addr[BT_ADDR_LE_STR_LEN];
|
||||
|
@ -87,8 +87,9 @@ static bool metadata_entry(struct bt_data *data, void *user_data)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void bass_client_recv_state_cb(struct bt_conn *conn, int err,
|
||||
const struct bt_bass_recv_state *state)
|
||||
static void bap_broadcast_assistant_recv_state_cb(
|
||||
struct bt_conn *conn, int err,
|
||||
const struct bt_bap_scan_delegator_recv_state *state)
|
||||
{
|
||||
char le_addr[BT_ADDR_LE_STR_LEN];
|
||||
char bad_code[33];
|
||||
|
@ -99,16 +100,16 @@ static void bass_client_recv_state_cb(struct bt_conn *conn, int err,
|
|||
}
|
||||
|
||||
bt_addr_le_to_str(&state->addr, le_addr, sizeof(le_addr));
|
||||
(void)bin2hex(state->bad_code, BT_BASS_BROADCAST_CODE_SIZE, bad_code,
|
||||
(void)bin2hex(state->bad_code, BT_BAP_BROADCAST_CODE_SIZE, bad_code,
|
||||
sizeof(bad_code));
|
||||
printk("BASS recv state: src_id %u, addr %s, sid %u, sync_state %u, "
|
||||
"encrypt_state %u%s%s\n", state->src_id, le_addr, state->adv_sid,
|
||||
state->pa_sync_state, state->encrypt_state,
|
||||
state->encrypt_state == BT_BASS_BIG_ENC_STATE_BAD_CODE ? ", bad code" : "",
|
||||
state->encrypt_state == BT_BAP_BIG_ENC_STATE_BAD_CODE ? ", bad code" : "",
|
||||
bad_code);
|
||||
|
||||
for (int i = 0; i < state->num_subgroups; i++) {
|
||||
const struct bt_bass_subgroup *subgroup = &state->subgroups[i];
|
||||
const struct bt_bap_scan_delegator_subgroup *subgroup = &state->subgroups[i];
|
||||
struct net_buf_simple buf;
|
||||
|
||||
printk("\t[%d]: BIS sync %u, metadata_len %u\n",
|
||||
|
@ -120,7 +121,7 @@ static void bass_client_recv_state_cb(struct bt_conn *conn, int err,
|
|||
}
|
||||
|
||||
|
||||
if (state->pa_sync_state == BT_BASS_PA_STATE_INFO_REQ) {
|
||||
if (state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ) {
|
||||
err = bt_le_per_adv_sync_transfer(g_pa_sync, conn,
|
||||
BT_UUID_BASS_VAL);
|
||||
if (err != 0) {
|
||||
|
@ -129,13 +130,13 @@ static void bass_client_recv_state_cb(struct bt_conn *conn, int err,
|
|||
}
|
||||
}
|
||||
|
||||
g_state_synced = state->pa_sync_state == BT_BASS_PA_STATE_SYNCED;
|
||||
g_state_synced = state->pa_sync_state == BT_BAP_PA_STATE_SYNCED;
|
||||
|
||||
g_src_id = state->src_id;
|
||||
g_cb = true;
|
||||
}
|
||||
|
||||
static void bass_client_recv_state_removed_cb(struct bt_conn *conn, int err,
|
||||
static void bap_broadcast_assistant_recv_state_removed_cb(struct bt_conn *conn, int err,
|
||||
uint8_t src_id)
|
||||
{
|
||||
if (err != 0) {
|
||||
|
@ -147,7 +148,7 @@ static void bass_client_recv_state_removed_cb(struct bt_conn *conn, int err,
|
|||
g_cb = true;
|
||||
}
|
||||
|
||||
static void bass_client_scan_start_cb(struct bt_conn *conn, int err)
|
||||
static void bap_broadcast_assistant_scan_start_cb(struct bt_conn *conn, int err)
|
||||
{
|
||||
if (err != 0) {
|
||||
FAIL("BASS scan start failed (%d)\n", err);
|
||||
|
@ -158,7 +159,7 @@ static void bass_client_scan_start_cb(struct bt_conn *conn, int err)
|
|||
g_write_complete = true;
|
||||
}
|
||||
|
||||
static void bass_client_scan_stop_cb(struct bt_conn *conn, int err)
|
||||
static void bap_broadcast_assistant_scan_stop_cb(struct bt_conn *conn, int err)
|
||||
{
|
||||
if (err != 0) {
|
||||
FAIL("BASS scan stop failed (%d)\n", err);
|
||||
|
@ -169,7 +170,7 @@ static void bass_client_scan_stop_cb(struct bt_conn *conn, int err)
|
|||
g_write_complete = true;
|
||||
}
|
||||
|
||||
static void bass_client_add_src_cb(struct bt_conn *conn, int err)
|
||||
static void bap_broadcast_assistant_add_src_cb(struct bt_conn *conn, int err)
|
||||
{
|
||||
if (err != 0) {
|
||||
FAIL("BASS add source failed (%d)\n", err);
|
||||
|
@ -180,7 +181,7 @@ static void bass_client_add_src_cb(struct bt_conn *conn, int err)
|
|||
g_write_complete = true;
|
||||
}
|
||||
|
||||
static void bass_client_mod_src_cb(struct bt_conn *conn, int err)
|
||||
static void bap_broadcast_assistant_mod_src_cb(struct bt_conn *conn, int err)
|
||||
{
|
||||
if (err != 0) {
|
||||
FAIL("BASS modify source failed (%d)\n", err);
|
||||
|
@ -191,7 +192,7 @@ static void bass_client_mod_src_cb(struct bt_conn *conn, int err)
|
|||
g_write_complete = true;
|
||||
}
|
||||
|
||||
static void bass_client_broadcast_code_cb(struct bt_conn *conn, int err)
|
||||
static void bap_broadcast_assistant_broadcast_code_cb(struct bt_conn *conn, int err)
|
||||
{
|
||||
if (err != 0) {
|
||||
FAIL("BASS broadcast code failed (%d)\n", err);
|
||||
|
@ -202,7 +203,7 @@ static void bass_client_broadcast_code_cb(struct bt_conn *conn, int err)
|
|||
g_write_complete = true;
|
||||
}
|
||||
|
||||
static void bass_client_rem_src_cb(struct bt_conn *conn, int err)
|
||||
static void bap_broadcast_assistant_rem_src_cb(struct bt_conn *conn, int err)
|
||||
{
|
||||
if (err != 0) {
|
||||
FAIL("BASS remove source failed (%d)\n", err);
|
||||
|
@ -213,17 +214,17 @@ static void bass_client_rem_src_cb(struct bt_conn *conn, int err)
|
|||
g_write_complete = true;
|
||||
}
|
||||
|
||||
static struct bt_bass_client_cb bass_cbs = {
|
||||
.discover = bass_client_discover_cb,
|
||||
.scan = bass_client_scan_cb,
|
||||
.recv_state = bass_client_recv_state_cb,
|
||||
.recv_state_removed = bass_client_recv_state_removed_cb,
|
||||
.scan_start = bass_client_scan_start_cb,
|
||||
.scan_stop = bass_client_scan_stop_cb,
|
||||
.add_src = bass_client_add_src_cb,
|
||||
.mod_src = bass_client_mod_src_cb,
|
||||
.broadcast_code = bass_client_broadcast_code_cb,
|
||||
.rem_src = bass_client_rem_src_cb,
|
||||
static struct bt_bap_broadcast_assistant_cb broadcast_assistant_cbs = {
|
||||
.discover = bap_broadcast_assistant_discover_cb,
|
||||
.scan = bap_broadcast_assistant_scan_cb,
|
||||
.recv_state = bap_broadcast_assistant_recv_state_cb,
|
||||
.recv_state_removed = bap_broadcast_assistant_recv_state_removed_cb,
|
||||
.scan_start = bap_broadcast_assistant_scan_start_cb,
|
||||
.scan_stop = bap_broadcast_assistant_scan_stop_cb,
|
||||
.add_src = bap_broadcast_assistant_add_src_cb,
|
||||
.mod_src = bap_broadcast_assistant_mod_src_cb,
|
||||
.broadcast_code = bap_broadcast_assistant_broadcast_code_cb,
|
||||
.rem_src = bap_broadcast_assistant_rem_src_cb,
|
||||
};
|
||||
|
||||
static void connected(struct bt_conn *conn, uint8_t err)
|
||||
|
@ -284,26 +285,9 @@ static void term_cb(struct bt_le_per_adv_sync *sync,
|
|||
g_pa_synced = false;
|
||||
}
|
||||
|
||||
static void recv_cb(struct bt_le_per_adv_sync *sync,
|
||||
const struct bt_le_per_adv_sync_recv_info *info,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
char le_addr[BT_ADDR_LE_STR_LEN];
|
||||
char data_str[129];
|
||||
|
||||
bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));
|
||||
(void)bin2hex(buf->data, buf->len, data_str, sizeof(data_str));
|
||||
|
||||
printk("PER_ADV_SYNC[%u]: [DEVICE]: %s, tx_power %i, "
|
||||
"RSSI %i, CTE %u, data length %u, data: %s\n",
|
||||
bt_le_per_adv_sync_get_index(sync), le_addr, info->tx_power,
|
||||
info->rssi, info->cte_type, buf->len, data_str);
|
||||
}
|
||||
|
||||
static struct bt_le_per_adv_sync_cb sync_callbacks = {
|
||||
.synced = sync_cb,
|
||||
.term = term_cb,
|
||||
.recv = recv_cb
|
||||
};
|
||||
|
||||
static void test_exchange_mtu(void)
|
||||
|
@ -317,7 +301,7 @@ static void test_bass_discover(void)
|
|||
int err;
|
||||
|
||||
printk("Discovering BASS\n");
|
||||
err = bt_bass_client_discover(g_conn);
|
||||
err = bt_bap_broadcast_assistant_discover(g_conn);
|
||||
if (err != 0) {
|
||||
FAIL("Failed to discover BASS %d\n", err);
|
||||
return;
|
||||
|
@ -333,7 +317,7 @@ static void test_bass_scan_start(void)
|
|||
|
||||
printk("Starting scan\n");
|
||||
g_write_complete = false;
|
||||
err = bt_bass_client_scan_start(g_conn, true);
|
||||
err = bt_bap_broadcast_assistant_scan_start(g_conn, true);
|
||||
if (err != 0) {
|
||||
FAIL("Could not write scan start to BASS (err %d)\n", err);
|
||||
return;
|
||||
|
@ -349,7 +333,7 @@ static void test_bass_scan_stop(void)
|
|||
|
||||
printk("Stopping scan\n");
|
||||
g_write_complete = false;
|
||||
err = bt_bass_client_scan_stop(g_conn);
|
||||
err = bt_bap_broadcast_assistant_scan_stop(g_conn);
|
||||
if (err != 0) {
|
||||
FAIL("Could not write scan stop to BASS (err %d)\n", err);
|
||||
return;
|
||||
|
@ -381,8 +365,8 @@ static void test_bass_create_pa_sync(void)
|
|||
static void test_bass_add_source(void)
|
||||
{
|
||||
int err;
|
||||
struct bt_bass_add_src_param add_src_param = { 0 };
|
||||
struct bt_bass_subgroup subgroup = { 0 };
|
||||
struct bt_bap_broadcast_assistant_add_src_param add_src_param = { 0 };
|
||||
struct bt_bap_scan_delegator_subgroup subgroup = { 0 };
|
||||
|
||||
printk("Adding source\n");
|
||||
g_cb = g_write_complete = false;
|
||||
|
@ -395,7 +379,7 @@ static void test_bass_add_source(void)
|
|||
add_src_param.subgroups = &subgroup;
|
||||
subgroup.bis_sync = 0;
|
||||
subgroup.metadata_len = 0;
|
||||
err = bt_bass_client_add_src(g_conn, &add_src_param);
|
||||
err = bt_bap_broadcast_assistant_add_src(g_conn, &add_src_param);
|
||||
if (err != 0) {
|
||||
FAIL("Could not add source (err %d)\n", err);
|
||||
return;
|
||||
|
@ -408,8 +392,8 @@ static void test_bass_add_source(void)
|
|||
static void test_bass_mod_source(void)
|
||||
{
|
||||
int err;
|
||||
struct bt_bass_mod_src_param mod_src_param = { 0 };
|
||||
struct bt_bass_subgroup subgroup = { 0 };
|
||||
struct bt_bap_broadcast_assistant_mod_src_param mod_src_param = { 0 };
|
||||
struct bt_bap_scan_delegator_subgroup subgroup = { 0 };
|
||||
|
||||
printk("Modify source\n");
|
||||
g_cb = g_write_complete = false;
|
||||
|
@ -420,7 +404,7 @@ static void test_bass_mod_source(void)
|
|||
mod_src_param.pa_interval = g_broadcaster_info.interval;
|
||||
subgroup.bis_sync = 0;
|
||||
subgroup.metadata_len = 0;
|
||||
err = bt_bass_client_mod_src(g_conn, &mod_src_param);
|
||||
err = bt_bap_broadcast_assistant_mod_src(g_conn, &mod_src_param);
|
||||
if (err != 0) {
|
||||
FAIL("Could not modify source (err %d)\n", err);
|
||||
return;
|
||||
|
@ -434,7 +418,7 @@ static void test_bass_mod_source(void)
|
|||
|
||||
static void test_bass_broadcast_code(void)
|
||||
{
|
||||
uint8_t broadcast_code[BT_BASS_BROADCAST_CODE_SIZE];
|
||||
uint8_t broadcast_code[BT_BAP_BROADCAST_CODE_SIZE];
|
||||
int err;
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(broadcast_code); i++) {
|
||||
|
@ -443,7 +427,7 @@ static void test_bass_broadcast_code(void)
|
|||
|
||||
printk("Adding broadcast code\n");
|
||||
g_write_complete = false;
|
||||
err = bt_bass_client_set_broadcast_code(g_conn, g_src_id,
|
||||
err = bt_bap_broadcast_assistant_set_broadcast_code(g_conn, g_src_id,
|
||||
broadcast_code);
|
||||
if (err != 0) {
|
||||
FAIL("Could not add broadcast code (err %d)\n", err);
|
||||
|
@ -460,7 +444,7 @@ static void test_bass_remove_source(void)
|
|||
|
||||
printk("Removing source\n");
|
||||
g_cb = g_write_complete = false;
|
||||
err = bt_bass_client_rem_src(g_conn, g_src_id);
|
||||
err = bt_bap_broadcast_assistant_rem_src(g_conn, g_src_id);
|
||||
if (err != 0) {
|
||||
FAIL("Could not remove source (err %d)\n", err);
|
||||
return;
|
||||
|
@ -482,7 +466,7 @@ static void test_main(void)
|
|||
|
||||
bt_conn_cb_register(&conn_callbacks);
|
||||
bt_gatt_cb_register(&gatt_callbacks);
|
||||
bt_bass_client_register_cb(&bass_cbs);
|
||||
bt_bap_broadcast_assistant_register_cb(&broadcast_assistant_cbs);
|
||||
bt_le_per_adv_sync_cb_register(&sync_callbacks);
|
||||
|
||||
printk("Starting scan\n");
|
||||
|
@ -506,12 +490,12 @@ static void test_main(void)
|
|||
test_bass_broadcast_code();
|
||||
test_bass_remove_source();
|
||||
|
||||
PASS("BASS client Passed\n");
|
||||
PASS("BAP broadcast assistant Passed\n");
|
||||
}
|
||||
|
||||
static const struct bst_test_instance test_bass[] = {
|
||||
{
|
||||
.test_id = "bass_client",
|
||||
.test_id = "bap_broadcast_assistant",
|
||||
.test_post_init_f = test_init,
|
||||
.test_tick_f = test_tick,
|
||||
.test_main_f = test_main
|
||||
|
@ -519,16 +503,16 @@ static const struct bst_test_instance test_bass[] = {
|
|||
BSTEST_END_MARKER
|
||||
};
|
||||
|
||||
struct bst_test_list *test_bass_client_install(struct bst_test_list *tests)
|
||||
struct bst_test_list *test_bap_broadcast_assistant_install(struct bst_test_list *tests)
|
||||
{
|
||||
return bst_add_tests(tests, test_bass);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
struct bst_test_list *test_bass_client_install(struct bst_test_list *tests)
|
||||
struct bst_test_list *test_bap_broadcast_assistant_install(struct bst_test_list *tests)
|
||||
{
|
||||
return tests;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BT_BASS_CLIENT */
|
||||
#endif /* CONFIG_BT_BAP_BROADCAST_ASSISTANT */
|
|
@ -1,11 +1,11 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
* Copyright (c) 2021-2022 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_BT_BASS
|
||||
#include <zephyr/bluetooth/audio/bass.h>
|
||||
#ifdef CONFIG_BT_BAP_SCAN_DELEGATOR
|
||||
#include <zephyr/bluetooth/audio/bap.h>
|
||||
#include "common.h"
|
||||
|
||||
extern enum bst_result_t bst_result;
|
||||
|
@ -15,28 +15,28 @@ static volatile bool g_pa_synced;
|
|||
static struct bt_conn *g_conn;
|
||||
static bool g_connected;
|
||||
|
||||
static void pa_synced(struct bt_bass_recv_state *recv_state,
|
||||
static void pa_synced(struct bt_bap_scan_delegator_recv_state *recv_state,
|
||||
const struct bt_le_per_adv_sync_synced_info *info)
|
||||
{
|
||||
printk("Receive state %p synced\n", recv_state);
|
||||
g_pa_synced = true;
|
||||
}
|
||||
|
||||
static void pa_term(struct bt_bass_recv_state *recv_state,
|
||||
static void pa_term(struct bt_bap_scan_delegator_recv_state *recv_state,
|
||||
const struct bt_le_per_adv_sync_term_info *info)
|
||||
{
|
||||
printk("Receive state %p sync terminated\n", recv_state);
|
||||
g_pa_synced = false;
|
||||
}
|
||||
|
||||
static void pa_recv(struct bt_bass_recv_state *recv_state,
|
||||
static void pa_recv(struct bt_bap_scan_delegator_recv_state *recv_state,
|
||||
const struct bt_le_per_adv_sync_recv_info *info,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
printk("Receive state %p received data\n", recv_state);
|
||||
}
|
||||
|
||||
static struct bt_bass_cb bass_cb = {
|
||||
static struct bt_bap_scan_delegator_cb scan_delegator_cb = {
|
||||
.pa_synced = pa_synced,
|
||||
.pa_term = pa_term,
|
||||
.pa_recv = pa_recv
|
||||
|
@ -75,7 +75,7 @@ static void test_main(void)
|
|||
|
||||
printk("Bluetooth initialized\n");
|
||||
|
||||
bt_bass_register_cb(&bass_cb);
|
||||
bt_bap_scan_delegator_register_cb(&scan_delegator_cb);
|
||||
bt_conn_cb_register(&conn_callbacks);
|
||||
|
||||
err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, AD_SIZE, NULL, 0);
|
||||
|
@ -90,12 +90,12 @@ static void test_main(void)
|
|||
|
||||
WAIT_FOR_COND(g_pa_synced);
|
||||
|
||||
PASS("BASS passed\n");
|
||||
PASS("BAP Scan Delegator passed\n");
|
||||
}
|
||||
|
||||
static const struct bst_test_instance test_bass[] = {
|
||||
static const struct bst_test_instance test_scan_delegator[] = {
|
||||
{
|
||||
.test_id = "bass",
|
||||
.test_id = "bap_scan_delegator",
|
||||
.test_post_init_f = test_init,
|
||||
.test_tick_f = test_tick,
|
||||
.test_main_f = test_main
|
||||
|
@ -103,14 +103,14 @@ static const struct bst_test_instance test_bass[] = {
|
|||
BSTEST_END_MARKER
|
||||
};
|
||||
|
||||
struct bst_test_list *test_bass_install(struct bst_test_list *tests)
|
||||
struct bst_test_list *test_scan_delegator_install(struct bst_test_list *tests)
|
||||
{
|
||||
return bst_add_tests(tests, test_bass);
|
||||
return bst_add_tests(tests, test_scan_delegator);
|
||||
}
|
||||
#else
|
||||
struct bst_test_list *test_bass_install(struct bst_test_list *tests)
|
||||
struct bst_test_list *test_scan_delegator_install(struct bst_test_list *tests)
|
||||
{
|
||||
return tests;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BT_BASS */
|
||||
#endif /* CONFIG_BT_BAP_SCAN_DELEGATOR */
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
extern enum bst_result_t bst_result;
|
||||
|
||||
/* TODO: Deprecate in favor of broadcast_source_test */
|
||||
|
||||
#define BROADCAST_ID_ENCODE(broadcast_id) \
|
||||
(((broadcast_id) >> 0) & 0xFF), \
|
||||
(((broadcast_id) >> 8) & 0xFF), \
|
||||
|
|
|
@ -21,8 +21,8 @@ extern struct bst_test_list *test_unicast_client_install(struct bst_test_list *t
|
|||
extern struct bst_test_list *test_unicast_server_install(struct bst_test_list *tests);
|
||||
extern struct bst_test_list *test_broadcast_source_install(struct bst_test_list *tests);
|
||||
extern struct bst_test_list *test_broadcast_sink_install(struct bst_test_list *tests);
|
||||
extern struct bst_test_list *test_bass_install(struct bst_test_list *tests);
|
||||
extern struct bst_test_list *test_bass_client_install(struct bst_test_list *tests);
|
||||
extern struct bst_test_list *test_scan_delegator_install(struct bst_test_list *tests);
|
||||
extern struct bst_test_list *test_bap_broadcast_assistant_install(struct bst_test_list *tests);
|
||||
extern struct bst_test_list *test_bass_broadcaster_install(struct bst_test_list *tests);
|
||||
extern struct bst_test_list *test_cap_acceptor_install(struct bst_test_list *tests);
|
||||
extern struct bst_test_list *test_cap_initiator_install(struct bst_test_list *tests);
|
||||
|
@ -47,8 +47,8 @@ bst_test_install_t test_installers[] = {
|
|||
test_unicast_server_install,
|
||||
test_broadcast_source_install,
|
||||
test_broadcast_sink_install,
|
||||
test_bass_install,
|
||||
test_bass_client_install,
|
||||
test_scan_delegator_install,
|
||||
test_bap_broadcast_assistant_install,
|
||||
test_bass_broadcaster_install,
|
||||
test_cap_acceptor_install,
|
||||
test_cap_initiator_install,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Copyright (c) 2020-2021 Nordic Semiconductor ASA
|
||||
# Copyright (c) 2020-2022 Nordic Semiconductor ASA
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
|
@ -27,16 +27,19 @@ cd ${BSIM_OUT_PATH}/bin
|
|||
printf "\n\n======== Running BASS and BASS client test =========\n\n"
|
||||
|
||||
Execute ./bs_${BOARD}_tests_bluetooth_bsim_bt_bsim_test_audio_prj_conf \
|
||||
-v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=bass -rs=24
|
||||
-v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=bap_scan_delegator \
|
||||
-rs=24
|
||||
|
||||
Execute ./bs_${BOARD}_tests_bluetooth_bsim_bt_bsim_test_audio_prj_conf \
|
||||
-v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=bass_client -rs=46
|
||||
-v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 \
|
||||
-testid=bap_broadcast_assistant -rs=46
|
||||
|
||||
Execute ./bs_${BOARD}_tests_bluetooth_bsim_bt_bsim_test_audio_prj_conf \
|
||||
-v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=bass_broadcaster -rs=69
|
||||
|
||||
# Simulation time should be larger than the WAIT_TIME in common.h
|
||||
Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -D=3 -sim_length=60e6 $@
|
||||
Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -D=3 \
|
||||
-sim_length=60e6 $@
|
||||
|
||||
for PROCESS_ID in $PROCESS_IDS; do
|
||||
wait $PROCESS_ID || let "EXIT_CODE=$?"
|
||||
|
|
|
@ -118,9 +118,8 @@ CONFIG_BT_OTS_SECONDARY_SVC=y
|
|||
CONFIG_BT_OTS_MAX_OBJ_CNT=50
|
||||
CONFIG_BT_OTS_CLIENT=y
|
||||
|
||||
# BASS
|
||||
CONFIG_BT_BASS=y
|
||||
CONFIG_BT_BASS_CLIENT=y
|
||||
CONFIG_BT_BAP_SCAN_DELEGATOR=y
|
||||
CONFIG_BT_BAP_BROADCAST_ASSISTANT=y
|
||||
|
||||
# IAS
|
||||
CONFIG_BT_IAS=y
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue