/* @file * @brief Internal APIs for Audio Endpoint handling * Copyright (c) 2020 Intel Corporation * Copyright (c) 2022-2023 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include #include #include #include #include #include #include #include #include "ascs_internal.h" #include "bap_stream.h" #if defined(CONFIG_BT_BAP_UNICAST_CLIENT) #define UNICAST_GROUP_CNT CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_COUNT #define UNICAST_GROUP_STREAM_CNT CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT #else /* !CONFIG_BT_BAP_UNICAST_CLIENT */ #define UNICAST_GROUP_CNT 0 #define UNICAST_GROUP_STREAM_CNT 0 #endif /* CONFIG_BT_BAP_UNICAST_CLIENT */ #if defined(CONFIG_BT_BAP_BROADCAST_SOURCE) #define BROADCAST_STREAM_CNT CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT #else /* !CONFIG_BT_BAP_BROADCAST_SOURCE */ #define BROADCAST_STREAM_CNT 0 #endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */ /* Temp struct declarations to handle circular dependencies */ struct bt_bap_unicast_group; struct bt_bap_broadcast_source; struct bt_bap_broadcast_sink; struct bt_bap_ep { uint8_t dir; uint8_t cig_id; uint8_t cis_id; struct bt_ascs_ase_status status; struct bt_bap_stream *stream; struct bt_audio_codec_cfg codec_cfg; struct bt_bap_qos_cfg qos; struct bt_bap_qos_cfg_pref qos_pref; struct bt_bap_iso *iso; /* unicast stopped reason */ uint8_t reason; /* Used by the unicast server and client */ bool receiver_ready; /* TODO: Create a union to reduce memory usage */ struct bt_bap_unicast_group *unicast_group; struct bt_bap_broadcast_source *broadcast_source; struct bt_bap_broadcast_sink *broadcast_sink; }; struct bt_bap_unicast_group_cig_param { uint32_t c_to_p_interval; uint32_t p_to_c_interval; uint16_t c_to_p_latency; uint16_t p_to_c_latency; uint8_t framing; uint8_t packing; #if defined(CONFIG_BT_ISO_TEST_PARAMS) uint8_t c_to_p_ft; uint8_t p_to_c_ft; uint16_t iso_interval; #endif /* CONFIG_BT_ISO_TEST_PARAMS */ }; struct bt_bap_unicast_group { /* Group-wide QoS used to create the CIG */ struct bt_bap_unicast_group_cig_param cig_param; /* Unicast group fields */ uint8_t index; bool allocated; /* Used to determine whether any stream in this group has been started which will prevent * reconfiguring it */ bool has_been_connected; struct bt_iso_cig *cig; /* The ISO API for CIG creation requires an array of pointers to ISO channels */ struct bt_iso_chan *cis[UNICAST_GROUP_STREAM_CNT]; sys_slist_t streams; }; #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 struct bt_audio_broadcast_stream_data { /** Codec Specific Data len */ size_t data_len; /** Codec Specific Data */ uint8_t data[CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE]; }; #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */ struct bt_bap_broadcast_source { uint8_t stream_count; uint8_t packing; bool encryption; struct bt_iso_big *big; struct bt_bap_qos_cfg *qos; #if defined(CONFIG_BT_ISO_TEST_PARAMS) /* Stored advanced parameters */ uint8_t irc; uint8_t pto; uint16_t iso_interval; #endif /* CONFIG_BT_ISO_TEST_PARAMS */ #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 /* The codec specific configured data for each stream in the subgroup */ struct bt_audio_broadcast_stream_data stream_data[BROADCAST_STREAM_CNT]; #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */ uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE]; /* The complete codec specific configured data for each stream in the subgroup. * This contains both the subgroup and the BIS-specific data for each stream. */ struct bt_audio_codec_cfg codec_cfg[BROADCAST_STREAM_CNT]; /* The subgroups containing the streams used to create the broadcast source */ sys_slist_t subgroups; }; enum bt_bap_broadcast_sink_flag { /** Sink has been initialized */ BT_BAP_BROADCAST_SINK_FLAG_INITIALIZED, /** BIGInfo has been received */ BT_BAP_BROADCAST_SINK_FLAG_BIGINFO_RECEIVED, /** Periodic Advertising is syncing */ BT_BAP_BROADCAST_SINK_FLAG_SYNCING, /** Broadcast sink instance is scanning */ BT_BAP_BROADCAST_SINK_FLAG_SCANNING, /** The BIG is encrypted */ BT_BAP_BROADCAST_SINK_FLAG_BIG_ENCRYPTED, /** The Scan Delegator Source ID is valid */ BT_BAP_BROADCAST_SINK_FLAG_SRC_ID_VALID, /** Total number of flags */ BT_BAP_BROADCAST_SINK_FLAG_NUM_FLAGS, }; struct bt_bap_broadcast_sink_subgroup { uint32_t bis_indexes; }; struct bt_bap_broadcast_sink_bis { uint8_t index; struct bt_iso_chan *chan; struct bt_audio_codec_cfg codec_cfg; }; #if defined(CONFIG_BT_BAP_BROADCAST_SINK) struct bt_bap_broadcast_sink { uint8_t index; /* index of broadcast_snks array */ uint8_t stream_count; uint8_t bass_src_id; uint8_t subgroup_count; uint16_t iso_interval; uint16_t biginfo_num_bis; uint32_t broadcast_id; /* 24 bit */ uint32_t indexes_bitfield; uint32_t valid_indexes_bitfield; /* based on codec support */ struct bt_bap_qos_cfg qos_cfg; struct bt_le_per_adv_sync *pa_sync; struct bt_iso_big *big; struct bt_bap_broadcast_sink_bis bis[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT]; struct bt_bap_broadcast_sink_subgroup subgroups[CONFIG_BT_BAP_BROADCAST_SNK_SUBGROUP_COUNT]; const struct bt_bap_scan_delegator_recv_state *recv_state; /* The streams used to create the broadcast sink */ sys_slist_t streams; /** Flags */ ATOMIC_DEFINE(flags, BT_BAP_BROADCAST_SINK_FLAG_NUM_FLAGS); }; #endif /* CONFIG_BT_BAP_BROADCAST_SINK */ static inline const char *bt_bap_ep_state_str(uint8_t state) { switch (state) { case BT_BAP_EP_STATE_IDLE: return "idle"; case BT_BAP_EP_STATE_CODEC_CONFIGURED: return "codec-configured"; case BT_BAP_EP_STATE_QOS_CONFIGURED: return "qos-configured"; case BT_BAP_EP_STATE_ENABLING: return "enabling"; case BT_BAP_EP_STATE_STREAMING: return "streaming"; case BT_BAP_EP_STATE_DISABLING: return "disabling"; case BT_BAP_EP_STATE_RELEASING: return "releasing"; default: return "unknown"; } } bool bt_bap_ep_is_broadcast_snk(const struct bt_bap_ep *ep); bool bt_bap_ep_is_broadcast_src(const struct bt_bap_ep *ep); bool bt_bap_ep_is_unicast_client(const struct bt_bap_ep *ep);