/** * @file * @brief Bluetooth ISO handling */ /* * Copyright (c) 2020 Intel Corporation * Copyright (c) 2021-2024 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ #ifndef ZEPHYR_INCLUDE_BLUETOOTH_ISO_H_ #define ZEPHYR_INCLUDE_BLUETOOTH_ISO_H_ /** * @brief Isochronous channels (ISO) * @defgroup bt_iso Isochronous channels (ISO) * * @since 2.3 * @version 0.8.0 * * @ingroup bluetooth * @{ */ #include #include #include #include #include #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif /** * @brief Headroom needed for outgoing ISO SDUs */ #define BT_ISO_CHAN_SEND_RESERVE BT_BUF_ISO_SIZE(0) /** * @brief Helper to calculate needed buffer size for ISO SDUs. * Useful for creating buffer pools. * * @param mtu Required ISO SDU size * * @return Needed buffer size to match the requested ISO SDU MTU. */ #define BT_ISO_SDU_BUF_SIZE(mtu) BT_BUF_ISO_SIZE(mtu) /** * Convert BIS index to bit * * The BIS indexes start from 0x01, so the lowest allowed bit is * BIT(0) that represents index 0x01. To synchronize to e.g. BIS * indexes 0x01 and 0x02, the bitfield value should be BIT(0) | BIT(1). * As a general notation, to sync to BIS index N use BIT(N - 1). */ #define BT_ISO_BIS_INDEX_BIT(x) (BIT((x) - 1)) /** Value to set the ISO data path over HCi. */ #define BT_ISO_DATA_PATH_HCI 0x00 /** Unknown SDU interval */ #define BT_ISO_SDU_INTERVAL_UNKNOWN 0x000000U /** Minimum interval value in microseconds */ #define BT_ISO_SDU_INTERVAL_MIN 0x0000FFU /** Maximum interval value in microseconds */ #define BT_ISO_SDU_INTERVAL_MAX 0x0FFFFFU /** Minimum ISO interval (N * 1.25 ms) */ #define BT_ISO_ISO_INTERVAL_MIN 0x0004U /** Maximum ISO interval (N * 1.25 ms) */ #define BT_ISO_ISO_INTERVAL_MAX 0x0C80U /** Minimum latency value in milliseconds */ #define BT_ISO_LATENCY_MIN 0x0005 /** Maximum latency value in milliseconds */ #define BT_ISO_LATENCY_MAX 0x0FA0 /** Packets will be sent sequentially between the channels in the group */ #define BT_ISO_PACKING_SEQUENTIAL 0x00 /** Packets will be sent interleaved between the channels in the group */ #define BT_ISO_PACKING_INTERLEAVED 0x01 /** Packets may be framed or unframed */ #define BT_ISO_FRAMING_UNFRAMED 0x00 /** Packets are always framed */ #define BT_ISO_FRAMING_FRAMED 0x01 /** Maximum number of isochronous channels in a single group */ #define BT_ISO_MAX_GROUP_ISO_COUNT 0x1F /** Minimum SDU size */ #define BT_ISO_MIN_SDU 0x0001 /** Maximum SDU size */ #define BT_ISO_MAX_SDU 0x0FFF /** Minimum PDU size */ #define BT_ISO_CONNECTED_PDU_MIN 0x0000U /** Minimum PDU size */ #define BT_ISO_BROADCAST_PDU_MIN 0x0001U /** Maximum PDU size */ #define BT_ISO_PDU_MAX 0x00FBU /** Minimum burst number */ #define BT_ISO_BN_MIN 0x01U /** Maximum burst number */ #define BT_ISO_BN_MAX 0x0FU /** Minimum flush timeout */ #define BT_ISO_FT_MIN 0x01U /** Maximum flush timeout */ #define BT_ISO_FT_MAX 0xFFU /** Minimum number of subevents */ #define BT_ISO_NSE_MIN 0x01U /** Maximum number of subevents */ #define BT_ISO_NSE_MAX 0x1FU /** Minimum BIG sync timeout value (N * 10 ms) */ #define BT_ISO_SYNC_TIMEOUT_MIN 0x000A /** Maximum BIG sync timeout value (N * 10 ms) */ #define BT_ISO_SYNC_TIMEOUT_MAX 0x4000 /** Controller controlled maximum subevent count value */ #define BT_ISO_SYNC_MSE_ANY 0x00 /** Minimum BIG sync maximum subevent count value */ #define BT_ISO_SYNC_MSE_MIN 0x01 /** Maximum BIG sync maximum subevent count value */ #define BT_ISO_SYNC_MSE_MAX 0x1F /** Maximum connected ISO retransmission value */ #define BT_ISO_CONNECTED_RTN_MAX 0xFF /** Maximum broadcast ISO retransmission value */ #define BT_ISO_BROADCAST_RTN_MAX 0x1E /** Broadcast code size */ #define BT_ISO_BROADCAST_CODE_SIZE 16 /** Lowest BIS index */ #define BT_ISO_BIS_INDEX_MIN 0x01 /** Highest BIS index */ #define BT_ISO_BIS_INDEX_MAX 0x1F /** Minimum Immediate Repetition Count */ #define BT_ISO_IRC_MIN 0x01U /** Maximum Immediate Repetition Count */ #define BT_ISO_IRC_MAX 0x0FU /** Minimum pre-transmission offset */ #define BT_ISO_PTO_MIN 0x00U /** Maximum pre-transmission offset */ #define BT_ISO_PTO_MAX 0x0FU /** No subinterval */ #define BT_ISO_SUBINTERVAL_NONE 0x00000000U /** Unknown subinterval */ #define BT_ISO_SUBINTERVAL_UNKNOWN 0xFFFFFFFFU /** * @brief Check if ISO BIS bitfield is valid (BT_ISO_BIS_INDEX_BIT(1)|..|BT_ISO_BIS_INDEX_BIT(31)) * * @param _bis_bitfield BIS index bitfield (uint32) */ #define BT_ISO_VALID_BIS_BITFIELD(_bis_bitfield) \ ((_bis_bitfield) != 0U && (_bis_bitfield) <= BIT_MASK(BT_ISO_BIS_INDEX_MAX)) /** * @brief Life-span states of ISO channel. Used only by internal APIs dealing with setting channel * to proper state depending on operational context. */ enum bt_iso_state { /** Channel disconnected */ BT_ISO_STATE_DISCONNECTED, /** Channel is pending ACL encryption before connecting */ BT_ISO_STATE_ENCRYPT_PENDING, /** Channel in connecting state */ BT_ISO_STATE_CONNECTING, /** Channel ready for upper layer traffic on it */ BT_ISO_STATE_CONNECTED, /** Channel in disconnecting state */ BT_ISO_STATE_DISCONNECTING, }; /** * @brief ISO Channel Type. */ enum bt_iso_chan_type { BT_ISO_CHAN_TYPE_NONE, /**< No channel type */ BT_ISO_CHAN_TYPE_CONNECTED, /**< Connected */ BT_ISO_CHAN_TYPE_BROADCASTER, /**< Isochronous broadcaster */ BT_ISO_CHAN_TYPE_SYNC_RECEIVER /**< Synchronized receiver */ }; /** @brief ISO Channel structure. */ struct bt_iso_chan { /** Channel connection reference */ struct bt_conn *iso; /** Channel operations reference */ struct bt_iso_chan_ops *ops; /** Channel QoS reference */ struct bt_iso_chan_qos *qos; /** Channel state */ enum bt_iso_state state; #if (defined(CONFIG_BT_SMP) && defined(CONFIG_BT_ISO_UNICAST)) || defined(__DOXYGEN__) /** * @brief The required security level of the channel * * This value can be set as the central before connecting a CIS * with bt_iso_chan_connect(). * The value is overwritten to @ref bt_iso_server::sec_level for the * peripheral once a channel has been accepted. * * Only available when @kconfig{CONFIG_BT_SMP} is enabled. */ bt_security_t required_sec_level; #endif /* CONFIG_BT_SMP && CONFIG_BT_ISO_UNICAST */ /** @internal Node used internally by the stack */ sys_snode_t node; }; /** @brief ISO Channel IO QoS structure. */ struct bt_iso_chan_io_qos { /** * @brief Channel SDU. * * Value range is @ref BT_ISO_MIN_SDU to @ref BT_ISO_MAX_SDU. */ uint16_t sdu; /** * @brief Channel PHY - See the BT_GAP_LE_PHY_* values. * * Setting @ref BT_GAP_LE_PHY_NONE is invalid. */ uint8_t phy; /** * @brief Channel Retransmission Number. * * This value is ignored if any advanced ISO parameters are set. */ uint8_t rtn; /** * @brief Channel data path reference * * Setting to NULL default to HCI data path (same as setting path.pid * to @ref BT_ISO_DATA_PATH_HCI). */ struct bt_iso_chan_path *path; #if defined(CONFIG_BT_ISO_TEST_PARAMS) || defined(__DOXYGEN__) /** * @brief Maximum PDU size * * Maximum size, in octets, of the payload from link layer to link layer. * * Value range @ref BT_ISO_CONNECTED_PDU_MIN to @ref BT_ISO_PDU_MAX for connected ISO. * * Value range @ref BT_ISO_BROADCAST_PDU_MIN to @ref BT_ISO_PDU_MAX for broadcast ISO. */ uint16_t max_pdu; /** * @brief Burst number * * Value range @ref BT_ISO_BN_MIN to @ref BT_ISO_BN_MAX. */ uint8_t burst_number; #endif /* CONFIG_BT_ISO_TEST_PARAMS */ }; /** @brief ISO Channel QoS structure. */ struct bt_iso_chan_qos { /** * @brief Channel Receiving QoS. * * Setting NULL disables data path @ref BT_HCI_DATAPATH_DIR_CTLR_TO_HOST. * * Can only be set for a connected isochronous channel, or a broadcast isochronous receiver. */ struct bt_iso_chan_io_qos *rx; /** * @brief Channel Transmission QoS * * Setting NULL disables data path @ref BT_HCI_DATAPATH_DIR_HOST_TO_CTLR. * * Can only be set for a connected isochronous channel, or a broadcast * isochronous transmitter. */ struct bt_iso_chan_io_qos *tx; #if defined(CONFIG_BT_ISO_TEST_PARAMS) || defined(__DOXYGEN__) /** * @brief Number of subevents * * Maximum number of subevents in each CIS or BIS event. * * Value range @ref BT_ISO_NSE_MIN to @ref BT_ISO_NSE_MAX. */ uint8_t num_subevents; #endif /* CONFIG_BT_ISO_TEST_PARAMS */ }; /** @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; /** Pointer to an array containing the Codec Configuration */ uint8_t *cc; }; /** ISO packet status flag bits */ enum { /** The ISO packet is valid. */ BT_ISO_FLAGS_VALID = BIT(0), /** * @brief The ISO packet may possibly contain errors. * * May be caused by a failed CRC check or if missing a part of the SDU. */ BT_ISO_FLAGS_ERROR = BIT(1), /** The ISO packet was lost. */ BT_ISO_FLAGS_LOST = BIT(2), /** * @brief Timestamp is valid * * If not set, then the bt_iso_recv_info.ts value is not valid, and * should not be used. */ BT_ISO_FLAGS_TS = BIT(3) }; /** @brief ISO Meta Data structure for received ISO packets. */ struct bt_iso_recv_info { /** * @brief ISO timestamp * * Only valid if @p flags has the @ref BT_ISO_FLAGS_TS bit set. */ uint32_t ts; /** ISO packet sequence number of the first fragment in the SDU */ uint16_t seq_num; /** ISO packet flags bitfield (BT_ISO_FLAGS_*) */ uint8_t flags; }; /** @brief ISO Meta Data structure for transmitted ISO packets. */ struct bt_iso_tx_info { /** CIG reference point or BIG anchor point of a transmitted SDU, in microseconds. */ uint32_t ts; /** Time offset, in microseconds */ uint32_t offset; /** Packet sequence number */ uint16_t seq_num; }; /** Opaque type representing an Connected Isochronous Group (CIG). */ struct bt_iso_cig; /** @brief Connected Isochronous Group (CIG) parameters */ struct bt_iso_cig_param { /** @brief Array of pointers to CIS channels */ struct bt_iso_chan **cis_channels; /** * @brief Number of channels in @p cis_channels * * Maximum number of channels in a single group is @ref BT_ISO_MAX_GROUP_ISO_COUNT */ uint8_t num_cis; /** * @brief Channel interval in us for SDUs sent from Central to Peripheral. * * Value range @ref BT_ISO_SDU_INTERVAL_MIN to @ref BT_ISO_SDU_INTERVAL_MAX. */ uint32_t c_to_p_interval; /** * @brief Channel interval in us for SDUs sent from Peripheral to Central. * * Value range @ref BT_ISO_SDU_INTERVAL_MIN to @ref BT_ISO_SDU_INTERVAL_MAX. */ uint32_t p_to_c_interval; /** * @brief Channel Latency in ms for SDUs sent from Central to Peripheral * * Value range @ref BT_ISO_LATENCY_MIN to @ref BT_ISO_LATENCY_MAX. * * This value is ignored if any advanced ISO parameters are set. */ uint16_t c_to_p_latency; /** * @brief Channel Latency in ms for SDUs sent from Peripheral to Central * * Value range @ref BT_ISO_LATENCY_MIN to @ref BT_ISO_LATENCY_MAX. * * This value is ignored if any advanced ISO parameters are set. */ uint16_t p_to_c_latency; /** * @brief Channel peripherals sleep clock accuracy Only for CIS * * Shall be worst case sleep clock accuracy of all the peripherals. * For possible values see the BT_GAP_SCA_* values. * If unknown for the peripherals, this should be set to @ref BT_GAP_SCA_UNKNOWN. */ uint8_t sca; /** * @brief Channel packing mode. * * @ref BT_ISO_PACKING_SEQUENTIAL or @ref BT_ISO_PACKING_INTERLEAVED */ uint8_t packing; /** * @brief Channel framing mode. * * @ref BT_ISO_FRAMING_UNFRAMED for unframed and @ref BT_ISO_FRAMING_FRAMED for framed. */ uint8_t framing; #if defined(CONFIG_BT_ISO_TEST_PARAMS) || defined(__DOXYGEN__) /** * @brief Central to Peripheral flush timeout * * The flush timeout in multiples of ISO_Interval for each payload sent * from the Central to Peripheral. * * Value range from @ref BT_ISO_FT_MIN to @ref BT_ISO_FT_MAX */ uint8_t c_to_p_ft; /** * @brief Peripheral to Central flush timeout * * The flush timeout in multiples of ISO_Interval for each payload sent * from the Peripheral to Central. * * Value range from @ref BT_ISO_FT_MIN to @ref BT_ISO_FT_MAX. */ uint8_t p_to_c_ft; /** * @brief ISO interval * * Time between consecutive CIS anchor points. * * Value range from @ref BT_ISO_ISO_INTERVAL_MIN to @ref BT_ISO_ISO_INTERVAL_MAX. */ uint16_t iso_interval; #endif /* CONFIG_BT_ISO_TEST_PARAMS */ }; /** ISO connection parameters structure */ struct bt_iso_connect_param { /** The ISO channel to connect */ struct bt_iso_chan *iso_chan; /** The ACL connection */ struct bt_conn *acl; }; /** Opaque type representing a Broadcast Isochronous Group (BIG). */ struct bt_iso_big; /** @brief Broadcast Isochronous Group (BIG) creation parameters */ struct bt_iso_big_create_param { /** Array of pointers to BIS channels */ struct bt_iso_chan **bis_channels; /** * @brief Number of channels in @p bis_channels * * Maximum number of channels in a single group is @ref BT_ISO_MAX_GROUP_ISO_COUNT */ uint8_t num_bis; /** * @brief Channel interval in us. * * Value range @ref BT_ISO_SDU_INTERVAL_MIN to @ref BT_ISO_SDU_INTERVAL_MAX. */ uint32_t interval; /** * @brief Channel Latency in ms. * * Value range @ref BT_ISO_LATENCY_MIN to @ref BT_ISO_LATENCY_MAX. * * This value is ignored if any advanced ISO parameters are set. */ uint16_t latency; /** * @brief Channel packing mode. * * @ref BT_ISO_PACKING_SEQUENTIAL or @ref BT_ISO_PACKING_INTERLEAVED */ uint8_t packing; /** * @brief Channel framing mode. * * @ref BT_ISO_FRAMING_UNFRAMED for unframed and @ref BT_ISO_FRAMING_FRAMED for framed. */ uint8_t framing; /** 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. * * If the value is a string or the value is less than 16 octets, * the remaining octets shall be 0. * * Example: * The string "Broadcast Code" shall be * [42 72 6F 61 64 63 61 73 74 20 43 6F 64 65 00 00] */ uint8_t bcode[BT_ISO_BROADCAST_CODE_SIZE]; #if defined(CONFIG_BT_ISO_TEST_PARAMS) || defined(__DOXYGEN__) /** * @brief Immediate Repetition Count * * The number of times the scheduled payloads are transmitted in a given event. * * Value range from @ref BT_ISO_IRC_MIN to @ref BT_ISO_IRC_MAX. */ uint8_t irc; /** * @brief Pre-transmission offset * * Offset used for pre-transmissions. * * Value range from @ref BT_ISO_PTO_MIN to @ref BT_ISO_PTO_MAX. */ uint8_t pto; /** * @brief ISO interval * * Time between consecutive BIS anchor points. * * Value range from @ref BT_ISO_ISO_INTERVAL_MIN to @ref BT_ISO_ISO_INTERVAL_MAX. */ uint16_t iso_interval; #endif /* CONFIG_BT_ISO_TEST_PARAMS */ }; /** @brief Broadcast Isochronous Group (BIG) Sync Parameters */ struct bt_iso_big_sync_param { /** Array of pointers to BIS channels */ struct bt_iso_chan **bis_channels; /** * @brief Number channels in @p bis_channels * * Maximum number of channels in a single group is @ref BT_ISO_MAX_GROUP_ISO_COUNT */ uint8_t num_bis; /** * @brief Bitfield of the BISes to sync to * * Use @ref BT_ISO_BIS_INDEX_BIT to convert BIS indexes to a bitfield. * * To synchronize to e.g. BIS indexes 0x01 and 0x02, this can be set to * BT_ISO_BIS_INDEX_BIT(0x01) | BT_ISO_BIS_INDEX_BIT(0x02). */ 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. * * Value range is @ref BT_ISO_SYNC_MSE_MIN to @ref BT_ISO_SYNC_MSE_MAX, or * @ref BT_ISO_SYNC_MSE_ANY to let the controller choose. */ uint32_t mse; /** * @brief Synchronization timeout for the BIG (N * 10 MS) * * Value range is @ref BT_ISO_SYNC_TIMEOUT_MIN to @ref BT_ISO_SYNC_TIMEOUT_MAX. */ 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. * * If the value is a string or a the value is less than 16 octets, * the remaining octets shall be 0. * * Example: * The string "Broadcast Code" shall be * [42 72 6F 61 64 63 61 73 74 20 43 6F 64 65 00 00] */ uint8_t bcode[BT_ISO_BROADCAST_CODE_SIZE]; }; /** @brief Broadcast Isochronous Group (BIG) information */ 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. * * For a peripheral, the QoS values (see @ref bt_iso_chan_io_qos) * are set when this is called. The peripheral does not have any * information about the RTN though. * * @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 or when setting security fails. * * @param chan The channel that has been Disconnected * @param reason BT_HCI_ERR_* reason for the disconnection. */ void (*disconnected)(struct bt_iso_chan *chan, uint8_t reason); /** * @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. * @param info Pointer to the metadata for the buffer. The lifetime of the * pointer is linked to the lifetime of the net_buf. * Metadata such as sequence number and timestamp can be * provided by the bluetooth controller. */ void (*recv)(struct bt_iso_chan *chan, const struct bt_iso_recv_info *info, struct net_buf *buf); /** * @brief Channel sent callback * * This callback will be called once the controller marks the SDU * as completed. When the controller does so is implementation * dependent. It could be after the SDU is enqueued for transmission, * or after it is sent on air or flushed. * * @param chan The channel which has sent data. */ void (*sent)(struct bt_iso_chan *chan); }; /** @brief ISO Accept Info Structure */ struct bt_iso_accept_info { /** The ACL connection that is requesting authorization */ struct bt_conn *acl; /** * @brief The ID of the connected isochronous group (CIG) on the central * * The ID is unique per ACL */ uint8_t cig_id; /** * @brief The ID of the connected isochronous stream (CIS) on the central * * This ID is unique within a CIG */ uint8_t cis_id; }; /** @brief ISO Server structure. */ struct bt_iso_server { #if defined(CONFIG_BT_SMP) || defined(__DOXYGEN__) /** * @brief Required minimum security level. * * Only available when @kconfig{CONFIG_BT_SMP} is enabled. */ bt_security_t sec_level; #endif /* CONFIG_BT_SMP */ /** * @brief Server accept callback * * This callback is called whenever a new incoming connection requires authorization. * * @param info The ISO accept information structure * @param chan Pointer to receive the allocated channel * * @return 0 in case of success or negative value in case of error. */ int (*accept)(const struct bt_iso_accept_info *info, 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 Unregister ISO server. * * Unregister previously registered ISO server. * * @param server Server structure. * * @return 0 in case of success or negative value in case of error. */ int bt_iso_server_unregister(struct bt_iso_server *server); /** * @brief Creates a CIG as a central * * This can called at any time, even before connecting to a remote device. * This must be called before any connected isochronous stream (CIS) channel can be connected. * * Once a CIG is created, the channels supplied in the @p param can be * connected using bt_iso_chan_connect(). * * @param[in] param The parameters used to create and enable the CIG. * @param[out] out_cig Connected Isochronous Group object on success. * * @return 0 in case of success or negative value in case of error. */ int bt_iso_cig_create(const struct bt_iso_cig_param *param, struct bt_iso_cig **out_cig); /** * @brief Reconfigure a CIG as a central * * This function can be used to update a CIG. It will update the group specific * parameters, and, if supplied, change the QoS parameters of the individual * CIS. If the cis_channels in @p param contains CIS that was not originally * in the call to bt_iso_cig_create(), these will be added to the group. * It is not possible to remove any CIS from the group after creation. * * This can be called at any time before connecting an ISO to a remote device. * Once any CIS in the group has connected, the group cannot be changed. * * Once a CIG is created, the channels supplied in the @p param can be * connected using bt_iso_chan_connect(). * * @param cig Connected Isochronous Group object. * @param param The parameters used to reconfigure the CIG. * * @return 0 in case of success or negative value in case of error. */ int bt_iso_cig_reconfigure(struct bt_iso_cig *cig, const struct bt_iso_cig_param *param); /** * @brief Terminates a CIG as a central * * All the CIS in the CIG shall be disconnected first. * * @param cig Pointer to the CIG structure. * * @return 0 in case of success or negative value in case of error. */ int bt_iso_cig_terminate(struct bt_iso_cig *cig); /** * @brief Connect ISO channels on ACL connections * * Connect ISO channels. The ISO channels must have been initialized in a CIG * first by calling bt_iso_cig_create(). * * Once the connection is completed the channels' connected() callback will be * called. If the connection is rejected disconnected() callback is called * instead. * * This function will also setup the ISO data path based on the @p path * parameter of the @ref bt_iso_chan_io_qos for each channel. * * @param param Pointer to a connect parameter array with the ISO and ACL pointers. * @param count Number of connect parameters. * * @retval 0 Successfully started the connecting procedure. * * @retval -EINVAL Invalid parameters were supplied. * * @retval -EBUSY Some ISO channels are already being connected. * It is not possible to have multiple outstanding connection requests. * May also be returned if @kconfig{CONFIG_BT_SMP} is enabled and a * pairing procedure is already in progress. * * @retval -ENOBUFS Not buffers available to send request to controller or if * @kconfig{CONFIG_BT_SMP} is enabled and no more keys could be stored. * * @retval -ENOMEM If @kconfig{CONFIG_BT_SMP} is enabled and no more keys * could be stored. * * @retval -EIO Controller rejected the request or if @kconfig{CONFIG_BT_SMP} * is enabled and pairing has timed out. * * @retval -ENOTCONN If @kconfig{CONFIG_BT_SMP} is enabled the ACL is not * connected. */ int bt_iso_chan_connect(const struct bt_iso_connect_param *param, size_t count); /** * @brief Disconnect connected ISO channel * * Disconnect connected ISO channel. * * If the device is a central and the connection is pending it will be * canceled and as a result the channel bt_iso_chan_ops.disconnected() callback is called. * * If the device is a peripheral and the connection is pending it will be rejected, as a peripheral * shall wait for a CIS Established event (which may trigger a bt_iso_chan_ops.disconnected() * callback in case of an error). * * Regarding to input parameter, to get details see reference description * to bt_iso_chan_connect() API. * * @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 without timestamp * * 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. * * @note Buffer ownership is transferred to the stack in case of success, in * case of an error the caller retains the ownership of the buffer. * * @param chan Channel object. * @param buf Buffer containing data to be sent. * @param seq_num Packet Sequence number. This value shall be incremented for * each call to this function and at least once per SDU * interval for a specific channel. * * @return Number of octets 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, uint16_t seq_num); /** * @brief Send data to ISO channel with timestamp * * 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. * * @note Buffer ownership is transferred to the stack in case of success, in * case of an error the caller retains the ownership of the buffer. * * @param chan Channel object. * @param buf Buffer containing data to be sent. * @param seq_num Packet Sequence number. This value shall be incremented for * each call to this function and at least once per SDU * interval for a specific channel. * @param ts Timestamp of the SDU in microseconds (us). * This value can be used to transmit multiple * SDUs in the same SDU interval in a CIG or BIG. * * @return Number of octets sent in case of success or negative value in case of error. */ int bt_iso_chan_send_ts(struct bt_iso_chan *chan, struct net_buf *buf, uint16_t seq_num, uint32_t ts); /** @brief ISO Unicast TX Info Structure */ struct bt_iso_unicast_tx_info { /** The transport latency in us */ uint32_t latency; /** The flush timeout (N * 1.25 ms) */ uint32_t flush_timeout; /** The maximum PDU size in octets */ uint16_t max_pdu; /** The transport PHY */ uint8_t phy; /** The burst number */ uint8_t bn; /** The maximum SDU size in octets * * May be set to @ref bt_iso_unicast_tx_info.max_pdu for peripherals if unknown */ uint16_t max_sdu; /** The SDU interval in microseconds * * May be set to @ref BT_ISO_SDU_INTERVAL_UNKNOWN for if unknown. */ uint32_t sdu_interval; }; /** @brief ISO Unicast Info Structure */ struct bt_iso_unicast_info { /** The maximum time in us for all PDUs of all CIS in a CIG event */ uint32_t cig_sync_delay; /** The maximum time in us for all PDUs of this CIS in a CIG event */ uint32_t cis_sync_delay; /** * @brief The subinterval in microseconds * * Will be @ref BT_ISO_SUBINTERVAL_NONE if there is no subinterval (NSE = 1). * Will be @ref BT_ISO_SUBINTERVAL_UNKNOWN if unknown. */ uint32_t subinterval; /** @brief TX information for the central to peripheral data path */ struct bt_iso_unicast_tx_info central; /** TX information for the peripheral to central data */ struct bt_iso_unicast_tx_info peripheral; }; /** @brief ISO Broadcaster Info Structure */ struct bt_iso_broadcaster_info { /** The maximum time in us for all PDUs of all BIS in a BIG event */ uint32_t sync_delay; /** The transport latency in us */ uint32_t latency; /** Pre-transmission offset (N * 1.25 ms) */ uint32_t pto; /** The maximum PDU size in octets */ uint16_t max_pdu; /** The transport PHY */ uint8_t phy; /** The burst number */ uint8_t bn; /** Number of times a payload is transmitted in a BIS event */ uint8_t irc; }; /** @brief ISO Synchronized Receiver Info Structure */ struct bt_iso_sync_receiver_info { /** The transport latency in us */ uint32_t latency; /** Pre-transmission offset (N * 1.25 ms) */ uint32_t pto; /** The maximum PDU size in octets */ uint16_t max_pdu; /** The burst number */ uint8_t bn; /** Number of times a payload is transmitted in a BIS event */ uint8_t irc; }; /** ISO channel Info Structure */ struct bt_iso_info { /** Channel Type. */ enum bt_iso_chan_type type; /** The ISO interval (N * 1.25 ms) */ uint16_t iso_interval; /** The maximum number of subevents in each ISO event */ uint8_t max_subevent; /** * @brief True if the channel is able to send data * * This is always true when @p type is @ref BT_ISO_CHAN_TYPE_BROADCASTER, * and never true when @p type is @ref BT_ISO_CHAN_TYPE_SYNC_RECEIVER. */ bool can_send; /** * @brief True if the channel is able to recv data * * This is always true when @p type is @ref BT_ISO_CHAN_TYPE_SYNC_RECEIVER, * and never true when @p type is @ref BT_ISO_CHAN_TYPE_BROADCASTER. */ bool can_recv; /** Connection Type specific Info.*/ union { #if defined(CONFIG_BT_ISO_UNICAST) || defined(__DOXYGEN__) /** Unicast specific Info. * Only available when @kconfig{CONFIG_BT_ISO_UNICAST} is enabled. */ struct bt_iso_unicast_info unicast; #endif /* CONFIG_BT_ISO_UNICAST */ #if defined(CONFIG_BT_ISO_BROADCASTER) || defined(__DOXYGEN__) /** Broadcaster specific Info. * Only available when @kconfig{CONFIG_BT_ISO_BROADCASTER} is enabled. */ struct bt_iso_broadcaster_info broadcaster; #endif /* CONFIG_BT_ISO_BROADCASTER */ #if defined(CONFIG_BT_ISO_SYNC_RECEIVER) || defined(__DOXYGEN__) /** Sync receiver specific Info. * Only available when @kconfig{CONFIG_BT_ISO_SYNC_RECEIVER} is enabled. */ struct bt_iso_sync_receiver_info sync_receiver; #endif /* CONFIG_BT_ISO_SYNC_RECEIVER */ }; }; /** * @brief Get ISO channel info * * @param chan Channel object. * @param info Channel info object. * * @return Zero on success or (negative) error code on failure. */ int bt_iso_chan_get_info(const struct bt_iso_chan *chan, struct bt_iso_info *info); /** * @brief Get ISO transmission timing info * * @details Reads timing information for transmitted ISO packet on an ISO channel. * The HCI_LE_Read_ISO_TX_Sync HCI command is used to retrieve this information * from the controller. * * @note An SDU must have already been successfully transmitted on the ISO channel * for this function to return successfully. * * @param[in] chan Channel object. * @param[out] info Transmit info object. * * @return Zero on success or (negative) error code on failure. */ int bt_iso_chan_get_tx_sync(const struct bt_iso_chan *chan, struct bt_iso_tx_info *info); /** * @brief Struct to hold the Broadcast Isochronous Group callbacks * * These can be registered for usage with bt_iso_big_register_cb(). */ struct bt_iso_big_cb { /** * @brief The BIG has started and all of the streams are ready for data * * @param big The started BIG */ void (*started)(struct bt_iso_big *big); /** * @brief The BIG has stopped and none of the streams are ready for data * * @param big The stopped BIG * @param reason The reason why the BIG stopped (see the BT_HCI_ERR_* values) */ void (*stopped)(struct bt_iso_big *big, uint8_t reason); /** @internal Internally used field for list handling */ sys_snode_t _node; }; /** * @brief Registers callbacks for Broadcast Sources * * @param cb Pointer to the callback structure. * * @retval 0 on success * @retval -EINVAL if @p cb is NULL * @retval -EEXIST if @p cb is already registered */ int bt_iso_big_register_cb(struct bt_iso_big_cb *cb); /** * @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_ */