Channel direction was actually a source of confusion since the spec does actually define the data path direction from controller point of view meaning input actually means transmit and output receive, also direction can be configured with different QoS settings. To make these APIs less confusing and allow QoS to be configured independently they are now split into RX (receiving) and TX (transmission) settings including its data path. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
406 lines
11 KiB
C
406 lines
11 KiB
C
/** @file
|
|
* @brief Bluetooth ISO handling
|
|
*/
|
|
|
|
/*
|
|
* Copyright (c) 2020 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
#ifndef ZEPHYR_INCLUDE_BLUETOOTH_ISO_H_
|
|
#define ZEPHYR_INCLUDE_BLUETOOTH_ISO_H_
|
|
|
|
/**
|
|
* @brief ISO
|
|
* @defgroup bt_iso ISO
|
|
* @ingroup bluetooth
|
|
* @{
|
|
*/
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include <sys/atomic.h>
|
|
#include <bluetooth/buf.h>
|
|
#include <bluetooth/conn.h>
|
|
#include <bluetooth/hci.h>
|
|
|
|
/** @def BT_ISO_CHAN_SEND_RESERVE
|
|
* @brief Headroom needed for outgoing buffers
|
|
*/
|
|
#define BT_ISO_CHAN_SEND_RESERVE (CONFIG_BT_HCI_RESERVE + \
|
|
BT_HCI_ISO_HDR_SIZE + \
|
|
BT_HCI_ISO_DATA_HDR_SIZE)
|
|
|
|
struct bt_iso_chan;
|
|
|
|
/** @brief Life-span states of ISO channel. Used only by internal APIs
|
|
* dealing with setting channel to proper state depending on operational
|
|
* context.
|
|
*/
|
|
enum {
|
|
/** Channel disconnected */
|
|
BT_ISO_DISCONNECTED,
|
|
/** Channel bound to a connection */
|
|
BT_ISO_BOUND,
|
|
/** Channel in connecting state */
|
|
BT_ISO_CONNECT,
|
|
/** Channel ready for upper layer traffic on it */
|
|
BT_ISO_CONNECTED,
|
|
/** Channel in disconnecting state */
|
|
BT_ISO_DISCONNECT,
|
|
};
|
|
|
|
/** @brief ISO Channel structure. */
|
|
struct bt_iso_chan {
|
|
/** Channel connection reference */
|
|
struct bt_conn *conn;
|
|
/** Channel operations reference */
|
|
struct bt_iso_chan_ops *ops;
|
|
/** Channel QoS reference */
|
|
struct bt_iso_chan_qos *qos;
|
|
sys_snode_t node;
|
|
uint8_t state;
|
|
bt_security_t required_sec_level;
|
|
};
|
|
|
|
/** @brief ISO Channel IO QoS structure. */
|
|
struct bt_iso_chan_io_qos {
|
|
/** Channel interval in us. Value range 0x0000FF - 0x0FFFFFF. */
|
|
uint32_t interval;
|
|
/** Channel Latency in ms. Value range 0x0005 - 0x0FA0. */
|
|
uint16_t latency;
|
|
/** Channel SDU. Value range 0x0000 - 0x0FFF. */
|
|
uint16_t sdu;
|
|
/** Channel PHY - See BT_GAP_LE_PHY for values.
|
|
* Setting BT_GAP_LE_PHY_NONE is invalid.
|
|
*/
|
|
uint8_t phy;
|
|
/** Channel Retransmission Number. Value range 0x00 - 0x0F. */
|
|
uint8_t rtn;
|
|
/** Channel data path reference.
|
|
* Setting to NULL default to HCI data path.
|
|
*/
|
|
struct bt_iso_chan_path *path;
|
|
};
|
|
|
|
/** @brief ISO Channel QoS structure. */
|
|
struct bt_iso_chan_qos {
|
|
/** @brief Channel peripherals sleep clock accuracy Only for CIS
|
|
*
|
|
* Shall be worst case sleep clock accuracy of all the peripherals.
|
|
* If unknown for the peripherals, this should be set to BT_GAP_SCA_UNKNOWN.
|
|
*/
|
|
uint8_t sca;
|
|
/** Channel packing mode. 0 for unpacked, 1 for packed. */
|
|
uint8_t packing;
|
|
/** Channel framing mode. 0 for unframed, 1 for framed. */
|
|
uint8_t framing;
|
|
/** Channel Receiving QoS:
|
|
* Setting NULL disables data path BT_HCI_DATAPATH_DIR_CTLR_TO_HOST
|
|
*/
|
|
struct bt_iso_chan_io_qos *rx;
|
|
/** Channel Transmission QoS:
|
|
* Setting NULL disables data path BT_HCI_DATAPATH_DIR_HOST_TO_CTRL
|
|
*/
|
|
struct bt_iso_chan_io_qos *tx;
|
|
};
|
|
|
|
/** @brief ISO Channel Data Path structure. */
|
|
struct bt_iso_chan_path {
|
|
/** Default path ID */
|
|
uint8_t pid;
|
|
/** Coding Format */
|
|
uint8_t format;
|
|
/** Company ID */
|
|
uint16_t cid;
|
|
/** Vendor-defined Codec ID */
|
|
uint16_t vid;
|
|
/** Controller Delay */
|
|
uint32_t delay;
|
|
/** Codec Configuration length*/
|
|
uint8_t cc_len;
|
|
/** Codec Configuration */
|
|
uint8_t cc[0];
|
|
};
|
|
|
|
/** Opaque type representing an Broadcast Isochronous Group (BIG). */
|
|
struct bt_iso_big;
|
|
|
|
struct bt_iso_big_create_param {
|
|
/** Array of pointers to BIS channels */
|
|
struct bt_iso_chan **bis_channels;
|
|
|
|
/** Number channels in @p bis_channels */
|
|
uint8_t num_bis;
|
|
|
|
/** Whether or not to encrypt the streams. */
|
|
bool encryption;
|
|
|
|
/** @brief Broadcast code
|
|
*
|
|
* The code used to derive the session key that is used to encrypt and
|
|
* decrypt BIS payloads.
|
|
*/
|
|
uint8_t bcode[16];
|
|
};
|
|
|
|
struct bt_iso_big_sync_param {
|
|
/** Array of pointers to BIS channels */
|
|
struct bt_iso_chan **bis_channels;
|
|
|
|
/** Number channels in @p bis_channels */
|
|
uint8_t num_bis;
|
|
|
|
/** Bitfield of the BISes to sync to */
|
|
uint32_t bis_bitfield;
|
|
|
|
/** @brief Maximum subevents
|
|
*
|
|
* The MSE (Maximum Subevents) parameter is the maximum number of subevents that a
|
|
* Controller should use to receive data payloads in each interval for a BIS
|
|
*/
|
|
uint32_t mse;
|
|
|
|
/** Synchronization timeout for the BIG (N * 10 MS) */
|
|
uint16_t sync_timeout;
|
|
|
|
/** Whether or not the streams of the BIG are encrypted */
|
|
bool encryption;
|
|
|
|
/** @brief Broadcast code
|
|
*
|
|
* The code used to derive the session key that is used to encrypt and
|
|
* decrypt BIS payloads.
|
|
*/
|
|
uint8_t bcode[16];
|
|
};
|
|
|
|
struct bt_iso_biginfo {
|
|
/** Address of the advertiser */
|
|
const bt_addr_le_t *addr;
|
|
|
|
/** Advertiser SID */
|
|
uint8_t sid;
|
|
|
|
/** Number of BISes in the BIG */
|
|
uint8_t num_bis;
|
|
|
|
/** Maximum number of subevents in each isochronous event */
|
|
uint8_t sub_evt_count;
|
|
|
|
/** Interval between two BIG anchor point (N * 1.25 ms) */
|
|
uint16_t iso_interval;
|
|
|
|
/** The number of new payloads in each BIS event */
|
|
uint8_t burst_number;
|
|
|
|
/** Offset used for pre-transmissions */
|
|
uint8_t offset;
|
|
|
|
/** The number of times a payload is transmitted in a BIS event */
|
|
uint8_t rep_count;
|
|
|
|
/** Maximum size, in octets, of the payload */
|
|
uint16_t max_pdu;
|
|
|
|
/** The interval, in microseconds, of periodic SDUs. */
|
|
uint32_t sdu_interval;
|
|
|
|
/** Maximum size of an SDU, in octets. */
|
|
uint16_t max_sdu;
|
|
|
|
/** Channel PHY */
|
|
uint8_t phy;
|
|
|
|
/** Channel framing mode */
|
|
uint8_t framing;
|
|
|
|
/** Whether or not the BIG is encrypted */
|
|
bool encryption;
|
|
};
|
|
|
|
/** @brief ISO Channel operations structure. */
|
|
struct bt_iso_chan_ops {
|
|
/** @brief Channel connected callback
|
|
*
|
|
* If this callback is provided it will be called whenever the
|
|
* connection completes.
|
|
*
|
|
* @param chan The channel that has been connected
|
|
*/
|
|
void (*connected)(struct bt_iso_chan *chan);
|
|
|
|
/** @brief Channel disconnected callback
|
|
*
|
|
* If this callback is provided it will be called whenever the
|
|
* channel is disconnected, including when a connection gets
|
|
* rejected.
|
|
*
|
|
* @param chan The channel that has been Disconnected
|
|
*/
|
|
void (*disconnected)(struct bt_iso_chan *chan);
|
|
|
|
/** @brief Channel alloc_buf callback
|
|
*
|
|
* If this callback is provided the channel will use it to allocate
|
|
* buffers to store incoming data.
|
|
*
|
|
* @param chan The channel requesting a buffer.
|
|
*
|
|
* @return Allocated buffer.
|
|
*/
|
|
struct net_buf *(*alloc_buf)(struct bt_iso_chan *chan);
|
|
|
|
/** @brief Channel recv callback
|
|
*
|
|
* @param chan The channel receiving data.
|
|
* @param buf Buffer containing incoming data.
|
|
*/
|
|
void (*recv)(struct bt_iso_chan *chan, struct net_buf *buf);
|
|
};
|
|
|
|
/** @brief ISO Server structure. */
|
|
struct bt_iso_server {
|
|
/** Required minimim security level */
|
|
bt_security_t sec_level;
|
|
|
|
/** @brief Server accept callback
|
|
*
|
|
* This callback is called whenever a new incoming connection requires
|
|
* authorization.
|
|
*
|
|
* @param conn The connection that is requesting authorization
|
|
* @param chan Pointer to receive the allocated channel
|
|
*
|
|
* @return 0 in case of success or negative value in case of error.
|
|
*/
|
|
int (*accept)(struct bt_conn *conn, struct bt_iso_chan **chan);
|
|
};
|
|
|
|
/** @brief Register ISO server.
|
|
*
|
|
* Register ISO server, each new connection is authorized using the accept()
|
|
* callback which in case of success shall allocate the channel structure
|
|
* to be used by the new connection.
|
|
*
|
|
* @param server Server structure.
|
|
*
|
|
* @return 0 in case of success or negative value in case of error.
|
|
*/
|
|
int bt_iso_server_register(struct bt_iso_server *server);
|
|
|
|
/** @brief Bind ISO channels
|
|
*
|
|
* Bind ISO channels with existing ACL connections, Channel objects passed
|
|
* (over an address of it) shouldn't be instantiated in application as
|
|
* standalone.
|
|
*
|
|
* @param conns Array of ACL connection objects
|
|
* @param num_conns Number of connection objects
|
|
* @param chans Array of ISO Channel objects to be created
|
|
*
|
|
* @return 0 in case of success or negative value in case of error.
|
|
*/
|
|
int bt_iso_chan_bind(struct bt_conn **conns, uint8_t num_conns,
|
|
struct bt_iso_chan **chans);
|
|
|
|
/** @brief Unbind ISO channel
|
|
*
|
|
* Unbind ISO channel from ACL connection, channel must be in BT_ISO_BOUND
|
|
* state.
|
|
*
|
|
* Note: Channels which the ACL connection has been disconnected are unbind
|
|
* automatically.
|
|
*
|
|
* @param chan Channel object.
|
|
*
|
|
* @return 0 in case of success or negative value in case of error.
|
|
*/
|
|
int bt_iso_chan_unbind(struct bt_iso_chan *chan);
|
|
|
|
/** @brief Connect ISO channels
|
|
*
|
|
* Connect ISO channels, once the connection is completed each channel
|
|
* connected() callback will be called. If the connection is rejected
|
|
* disconnected() callback is called instead.
|
|
* Channel object passed (over an address of it) as second parameter shouldn't
|
|
* be instantiated in application as standalone.
|
|
*
|
|
* @param chans Array of ISO channel objects
|
|
* @param num_chans Number of channel objects
|
|
*
|
|
* @return 0 in case of success or negative value in case of error.
|
|
*/
|
|
int bt_iso_chan_connect(struct bt_iso_chan **chans, uint8_t num_chans);
|
|
|
|
/** @brief Disconnect ISO channel
|
|
*
|
|
* Disconnect ISO channel, if the connection is pending it will be
|
|
* canceled and as a result the channel disconnected() callback is called.
|
|
* Regarding to input parameter, to get details see reference description
|
|
* to bt_iso_chan_connect() API above.
|
|
*
|
|
* @param chan Channel object.
|
|
*
|
|
* @return 0 in case of success or negative value in case of error.
|
|
*/
|
|
int bt_iso_chan_disconnect(struct bt_iso_chan *chan);
|
|
|
|
/** @brief Send data to ISO channel
|
|
*
|
|
* Send data from buffer to the channel. If credits are not available, buf will
|
|
* be queued and sent as and when credits are received from peer.
|
|
* Regarding to first input parameter, to get details see reference description
|
|
* to bt_iso_chan_connect() API above.
|
|
*
|
|
* @param chan Channel object.
|
|
* @param buf Buffer containing data to be sent.
|
|
*
|
|
* @return Bytes sent in case of success or negative value in case of error.
|
|
*/
|
|
int bt_iso_chan_send(struct bt_iso_chan *chan, struct net_buf *buf);
|
|
|
|
/** @brief Creates a BIG as a broadcaster
|
|
*
|
|
* @param[in] padv Pointer to the periodic advertising object the BIGInfo shall be sent on.
|
|
* @param[in] param The parameters used to create and enable the BIG. The QOS parameters are
|
|
* determined by the QOS field of the first BIS in the BIS list of this
|
|
* parameter.
|
|
* @param[out] out_big Broadcast Isochronous Group object on success.
|
|
*
|
|
* @return 0 in case of success or negative value in case of error.
|
|
*/
|
|
int bt_iso_big_create(struct bt_le_ext_adv *padv, struct bt_iso_big_create_param *param,
|
|
struct bt_iso_big **out_big);
|
|
|
|
/** @brief Terminates a BIG as a broadcaster or receiver
|
|
*
|
|
* @param big Pointer to the BIG structure.
|
|
*
|
|
* @return 0 in case of success or negative value in case of error.
|
|
*/
|
|
int bt_iso_big_terminate(struct bt_iso_big *big);
|
|
|
|
/** @brief Creates a BIG as a receiver
|
|
*
|
|
* @param[in] sync Pointer to the periodic advertising sync object the BIGInfo was received on.
|
|
* @param[in] param The parameters used to create and enable the BIG sync.
|
|
* @param[out] out_big Broadcast Isochronous Group object on success.
|
|
*
|
|
* @return 0 in case of success or negative value in case of error.
|
|
*/
|
|
int bt_iso_big_sync(struct bt_le_per_adv_sync *sync, struct bt_iso_big_sync_param *param,
|
|
struct bt_iso_big **out_big);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_ISO_H_ */
|