Skip to content

Commit 26e1e80

Browse files
committed
Bluetooth: CAP: Implement unicast to broadcast handover
Implement the unicast to broadcast handover procedure, as per the Bluetooth CAP specificiation. Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
1 parent 4d9cc0a commit 26e1e80

File tree

9 files changed

+1224
-24
lines changed

9 files changed

+1224
-24
lines changed

include/zephyr/bluetooth/audio/bap.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1672,6 +1672,32 @@ int bt_bap_unicast_group_add_streams(struct bt_bap_unicast_group *unicast_group,
16721672
*/
16731673
int bt_bap_unicast_group_delete(struct bt_bap_unicast_group *unicast_group);
16741674

1675+
/** Callback function for bt_bap_unicast_group_foreach_stream()
1676+
*
1677+
* @param stream The audio stream
1678+
* @param user_data User data
1679+
*
1680+
* @retval true Stop iterating.
1681+
* @retval false Continue iterating.
1682+
*/
1683+
typedef bool (*bt_bap_unicast_group_foreach_stream_func_t)(struct bt_bap_stream *stream,
1684+
void *user_data);
1685+
1686+
/**
1687+
* @brief Iterate through all streams in a unicast group
1688+
*
1689+
* @param unicast_group The unicast group
1690+
* @param func The callback function
1691+
* @param user_data User specified data that sent to the callback function
1692+
*
1693+
* @retval 0 Success (even if no streams exists in the group).
1694+
* @retval -ECANCELED Iteration was stopped by the callback function before complete.
1695+
* @retval -EINVAL @p unicast_group or @p func were NULL.
1696+
*/
1697+
int bt_bap_unicast_group_foreach_stream(struct bt_bap_unicast_group *unicast_group,
1698+
bt_bap_unicast_group_foreach_stream_func_t func,
1699+
void *user_data);
1700+
16751701
/** Unicast Client callback structure */
16761702
struct bt_bap_unicast_client_cb {
16771703
/**

include/zephyr/bluetooth/audio/cap.h

Lines changed: 89 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,12 @@ struct bt_cap_initiator_cb {
147147
*/
148148
void (*broadcast_stopped)(struct bt_cap_broadcast_source *source, uint8_t reason);
149149
#endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */
150+
#if defined(CONFIG_BT_CAP_HANDOVER_SUPPORTED)
151+
/**
152+
* @brief The unicast to broadcast handover procedure has finished
153+
*/
154+
void (*unicast_to_broadcast_complete)(int err, struct bt_conn *conn);
155+
#endif /* CONFIG_BT_CAP_HANDOVER_SUPPORTED */
150156
};
151157

152158
/**
@@ -398,6 +404,32 @@ int bt_cap_unicast_group_add_streams(struct bt_cap_unicast_group *unicast_group,
398404
*/
399405
int bt_cap_unicast_group_delete(struct bt_cap_unicast_group *unicast_group);
400406

407+
/** Callback function for bt_bap_unicast_group_foreach_stream()
408+
*
409+
* @param stream The audio stream
410+
* @param user_data User data
411+
*
412+
* @retval true Stop iterating.
413+
* @retval false Continue iterating.
414+
*/
415+
typedef bool (*bt_cap_unicast_group_foreach_stream_func_t)(struct bt_cap_stream *stream,
416+
void *user_data);
417+
418+
/**
419+
* @brief Iterate through all streams in a unicast group
420+
*
421+
* @param unicast_group The unicast group
422+
* @param func The callback function
423+
* @param user_data User specified data that sent to the callback function
424+
*
425+
* @retval 0 Success (even if no streams exists in the group).
426+
* @retval -ECANCELED Iteration was stopped by the callback function before complete.
427+
* @retval -EINVAL @p unicast_group or @p func were NULL.
428+
*/
429+
int bt_cap_unicast_group_foreach_stream(struct bt_cap_unicast_group *unicast_group,
430+
bt_cap_unicast_group_foreach_stream_func_t func,
431+
void *user_data);
432+
401433
/** Stream specific parameters for the bt_cap_initiator_unicast_audio_start() function */
402434
struct bt_cap_unicast_audio_start_stream_param {
403435
/** Coordinated or ad-hoc set member. */
@@ -783,21 +815,43 @@ int bt_cap_initiator_broadcast_get_base(struct bt_cap_broadcast_source *broadcas
783815

784816
/** Parameters for bt_cap_initiator_unicast_to_broadcast() */
785817
struct bt_cap_unicast_to_broadcast_param {
818+
/** The type of the set. */
819+
enum bt_cap_set_type type;
820+
786821
/** The source unicast group with the streams. */
787-
struct bt_bap_unicast_group *unicast_group;
822+
struct bt_cap_unicast_group *unicast_group;
823+
824+
/** The advertising set to use for the broadcast source */
825+
/* TBD: Is this necessary? Should we, or the app, start the source? */
826+
struct bt_le_ext_adv *adv;
827+
828+
/** Quality of Service configuration for the broadcast streams.
829+
*
830+
* Shall be valid for the duration of the broadcast source object.
831+
*/
832+
struct bt_bap_qos_cfg *qos;
833+
834+
/**
835+
* @brief Broadcast Source packing mode.
836+
*
837+
* @ref BT_ISO_PACKING_SEQUENTIAL or @ref BT_ISO_PACKING_INTERLEAVED.
838+
*
839+
* @note This is a recommendation to the controller, which the controller may ignore.
840+
*/
841+
uint8_t packing;
788842

789843
/**
790844
* @brief Whether or not to encrypt the streams.
791845
*
792-
* If set to true, then the broadcast code in @p broadcast_code
793-
* will be used to encrypt the streams.
846+
* If set to true, then the broadcast code in
847+
* @p bt_cap_unicast_to_broadcast_param.broadcast_code will be used to encrypt the streams.
794848
*/
795849
bool encrypt;
796850

797851
/**
798852
* @brief 16-octet broadcast code.
799853
*
800-
* Only valid if @p encrypt is true.
854+
* Only valid if @p bt_cap_unicast_to_broadcast_param.encrypt is true.
801855
*
802856
* If the value is a string or a the value is less than 16 octets,
803857
* the remaining octets shall be 0.
@@ -807,6 +861,35 @@ struct bt_cap_unicast_to_broadcast_param {
807861
* [42 72 6F 61 64 63 61 73 74 20 43 6F 64 65 00 00]
808862
*/
809863
uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE];
864+
865+
#if defined(CONFIG_BT_ISO_TEST_PARAMS) || defined(__DOXYGEN__)
866+
/**
867+
* @brief Immediate Repetition Count
868+
*
869+
* The number of times the scheduled payloads are transmitted in a given event.
870+
*
871+
* Value range from @ref BT_ISO_IRC_MIN to @ref BT_ISO_IRC_MAX.
872+
*/
873+
uint8_t irc;
874+
875+
/**
876+
* @brief Pre-transmission offset
877+
*
878+
* Offset used for pre-transmissions.
879+
*
880+
* Value range from @ref BT_ISO_PTO_MIN to @ref BT_ISO_PTO_MAX.
881+
*/
882+
uint8_t pto;
883+
884+
/**
885+
* @brief ISO interval
886+
*
887+
* Time between consecutive BIS anchor points.
888+
*
889+
* Value range from @ref BT_ISO_ISO_INTERVAL_MIN to @ref BT_ISO_ISO_INTERVAL_MAX.
890+
*/
891+
uint16_t iso_interval;
892+
#endif /* CONFIG_BT_ISO_TEST_PARAMS */
810893
};
811894

812895
/**
@@ -815,10 +898,7 @@ struct bt_cap_unicast_to_broadcast_param {
815898
* The streams in the unicast group will be stopped and the unicast group
816899
* will be deleted. This can only be done for source streams.
817900
*
818-
* @note @kconfig{CONFIG_BT_CAP_INITIATOR},
819-
* @kconfig{CONFIG_BT_BAP_UNICAST_CLIENT} and
820-
* @kconfig{CONFIG_BT_BAP_BROADCAST_SOURCE} must be enabled for this function
821-
* to be enabled.
901+
* @kconfig_dep{CONFIG_BT_CAP_HANDOVER_SUPPORTED}
822902
*
823903
* @param param The parameters for the handover.
824904
* @param source The resulting broadcast source.
@@ -859,10 +939,7 @@ struct bt_cap_broadcast_to_unicast_param {
859939
* The streams in the broadcast source will be stopped and the broadcast source
860940
* will be deleted.
861941
*
862-
* @note @kconfig{CONFIG_BT_CAP_INITIATOR},
863-
* @kconfig{CONFIG_BT_BAP_UNICAST_CLIENT} and
864-
* @kconfig{CONFIG_BT_BAP_BROADCAST_SOURCE} must be enabled for this function
865-
* to be enabled.
942+
* @kconfig_dep{CONFIG_BT_CAP_HANDOVER_SUPPORTED}
866943
*
867944
* @param[in] param The parameters for the handover.
868945
* @param[out] unicast_group The resulting broadcast source.

subsys/bluetooth/audio/Kconfig.cap

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,7 @@ config BT_CAP_COMMANDER
4848
BT_MCC
4949
help
5050
Enabling this will enable the CAP Initiator role.
51+
52+
config BT_CAP_HANDOVER_SUPPORTED
53+
def_bool BT_CAP_COMMANDER && BT_CAP_INITIATOR && BT_BAP_BROADCAST_ASSISTANT && \
54+
BT_BAP_BROADCAST_SOURCE && BT_BAP_UNICAST_CLIENT

subsys/bluetooth/audio/bap_unicast_client.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3143,6 +3143,33 @@ int bt_bap_unicast_group_delete(struct bt_bap_unicast_group *unicast_group)
31433143
return 0;
31443144
}
31453145

3146+
int bt_bap_unicast_group_foreach_stream(struct bt_bap_unicast_group *unicast_group,
3147+
bt_bap_unicast_group_foreach_stream_func_t func,
3148+
void *user_data)
3149+
{
3150+
struct bt_bap_stream *stream, *next;
3151+
3152+
if (unicast_group == NULL) {
3153+
LOG_DBG("unicast_group is NULL");
3154+
return -EINVAL;
3155+
}
3156+
3157+
if (func == NULL) {
3158+
LOG_DBG("func is NULL");
3159+
return -EINVAL;
3160+
}
3161+
3162+
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&unicast_group->streams, stream, next, _node) {
3163+
const bool stop = func(stream, user_data);
3164+
3165+
if (stop) {
3166+
return -ECANCELED;
3167+
}
3168+
}
3169+
3170+
return 0;
3171+
}
3172+
31463173
int bt_bap_unicast_client_config(struct bt_bap_stream *stream,
31473174
const struct bt_audio_codec_cfg *codec_cfg)
31483175
{

0 commit comments

Comments
 (0)