tests: Bluetooth: Audio: Add CAP unicast start BSIM test

The test only works partially until the controller and
babblesim supports ISO, as it needs that in order to
perform the unicast start procedure.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
Emil Gydesen 2022-08-18 13:37:59 +02:00 committed by Carles Cufí
commit e4d0725112
2 changed files with 551 additions and 13 deletions

View file

@ -15,6 +15,11 @@
extern enum bst_result_t bst_result;
#define SINK_CONTEXT BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED | \
BT_AUDIO_CONTEXT_TYPE_MEDIA | \
BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL
#define SOURCE_CONTEXT BT_AUDIO_CONTEXT_TYPE_NOTIFICATIONS
CREATE_FLAG(flag_broadcaster_found);
CREATE_FLAG(flag_base_received);
CREATE_FLAG(flag_pa_synced);
@ -24,8 +29,16 @@ CREATE_FLAG(flag_pa_sync_lost);
static struct bt_bap_broadcast_sink *g_broadcast_sink;
static struct bt_cap_stream broadcast_sink_streams[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT];
static struct bt_bap_lc3_preset broadcast_preset_16_2_1 = BT_BAP_LC3_BROADCAST_PRESET_16_2_1(
BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED);
static struct bt_bap_lc3_preset unicast_preset_16_2_1 =
BT_BAP_LC3_UNICAST_PRESET_16_2_1(BT_AUDIO_LOCATION_FRONT_LEFT,
SINK_CONTEXT);
static struct bt_bap_lc3_preset broadcast_preset_16_2_1 =
BT_BAP_LC3_BROADCAST_PRESET_16_2_1(BT_AUDIO_LOCATION_FRONT_LEFT,
BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED);
static const struct bt_codec_qos_pref unicast_qos_pref =
BT_CODEC_QOS_PREF(true, BT_GAP_LE_PHY_2M, 0u, 60u, 20000u, 40000u, 20000u, 40000u);
static K_SEM_DEFINE(sem_broadcast_started, 0U, ARRAY_SIZE(broadcast_sink_streams));
static K_SEM_DEFINE(sem_broadcast_stopped, 0U, ARRAY_SIZE(broadcast_sink_streams));
@ -37,6 +50,13 @@ static K_SEM_DEFINE(sem_broadcast_stopped, 0U, ARRAY_SIZE(broadcast_sink_streams
static const uint32_t bis_index_mask = BIT_MASK(ARRAY_SIZE(broadcast_sink_streams) + 1U);
static uint32_t bis_index_bitfield;
#define UNICAST_CHANNEL_COUNT_1 BIT(0)
static struct bt_cap_stream unicast_streams[CONFIG_BT_ASCS_ASE_SNK_COUNT +
CONFIG_BT_ASCS_ASE_SRC_COUNT];
CREATE_FLAG(flag_unicast_stream_configured);
static bool scan_recv_cb(const struct bt_le_scan_recv_info *info,
struct net_buf_simple *ad,
uint32_t broadcast_id)
@ -185,6 +205,34 @@ static void recv_cb(struct bt_bap_stream *stream, const struct bt_iso_recv_info
static struct bt_bap_stream_ops broadcast_stream_ops = {
.started = started_cb, .stopped = stopped_cb, .recv = recv_cb};
static void unicast_stream_enabled_cb(struct bt_bap_stream *stream)
{
struct bt_bap_ep_info ep_info;
int err;
printk("Enabled: stream %p\n", stream);
err = bt_bap_ep_get_info(stream->ep, &ep_info);
if (err != 0) {
FAIL("Failed to get ep info: %d\n", err);
return;
}
if (ep_info.dir == BT_AUDIO_DIR_SINK) {
/* Automatically do the receiver start ready operation */
err = bt_bap_stream_start(stream);
if (err != 0) {
FAIL("Failed to start stream: %d\n", err);
return;
}
}
}
static struct bt_bap_stream_ops unicast_stream_ops = {
.enabled = unicast_stream_enabled_cb,
};
/* TODO: Expand with CAP service data */
static const struct bt_data cap_acceptor_ad[] = {
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
@ -193,15 +241,258 @@ static const struct bt_data cap_acceptor_ad[] = {
static struct bt_csip_set_member_svc_inst *csip_set_member;
static struct bt_bap_stream *unicast_stream_alloc(void)
{
for (size_t i = 0; i < ARRAY_SIZE(unicast_streams); i++) {
struct bt_bap_stream *stream = &unicast_streams[i].bap_stream;
if (!stream->conn) {
return stream;
}
}
return NULL;
}
static int unicast_server_config(struct bt_conn *conn, const struct bt_bap_ep *ep,
enum bt_audio_dir dir, const struct bt_codec *codec,
struct bt_bap_stream **stream,
struct bt_codec_qos_pref *const pref)
{
printk("ASE Codec Config: conn %p ep %p dir %u\n", conn, ep, dir);
print_codec(codec);
*stream = unicast_stream_alloc();
if (*stream == NULL) {
printk("No streams available\n");
return -ENOMEM;
}
printk("ASE Codec Config stream %p\n", *stream);
SET_FLAG(flag_unicast_stream_configured);
*pref = unicast_qos_pref;
return 0;
}
static int unicast_server_reconfig(struct bt_bap_stream *stream, enum bt_audio_dir dir,
const struct bt_codec *codec,
struct bt_codec_qos_pref *const pref)
{
printk("ASE Codec Reconfig: stream %p\n", stream);
print_codec(codec);
*pref = unicast_qos_pref;
/* We only support one QoS at the moment, reject changes */
return -ENOEXEC;
}
static int unicast_server_qos(struct bt_bap_stream *stream, const struct bt_codec_qos *qos)
{
printk("QoS: stream %p qos %p\n", stream, qos);
print_qos(qos);
return 0;
}
static int unicast_server_enable(struct bt_bap_stream *stream, const struct bt_codec_data *meta,
size_t meta_count)
{
printk("Enable: stream %p meta_count %zu\n", stream, meta_count);
return 0;
}
static int unicast_server_start(struct bt_bap_stream *stream)
{
printk("Start: stream %p\n", stream);
return 0;
}
static bool valid_metadata_type(uint8_t type, uint8_t len)
{
switch (type) {
case BT_AUDIO_METADATA_TYPE_PREF_CONTEXT:
case BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT:
if (len != 2) {
return false;
}
return true;
case BT_AUDIO_METADATA_TYPE_STREAM_LANG:
if (len != 3) {
return false;
}
return true;
case BT_AUDIO_METADATA_TYPE_PARENTAL_RATING:
if (len != 1) {
return false;
}
return true;
case BT_AUDIO_METADATA_TYPE_EXTENDED: /* 1 - 255 octets */
case BT_AUDIO_METADATA_TYPE_VENDOR: /* 1 - 255 octets */
if (len < 1) {
return false;
}
return true;
case BT_AUDIO_METADATA_TYPE_CCID_LIST: /* 2 - 254 octets */
if (len < 2) {
return false;
}
return true;
case BT_AUDIO_METADATA_TYPE_PROGRAM_INFO: /* 0 - 255 octets */
case BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI: /* 0 - 255 octets */
return true;
default:
return false;
}
}
static int unicast_server_metadata(struct bt_bap_stream *stream, const struct bt_codec_data *meta,
size_t meta_count)
{
printk("Metadata: stream %p meta_count %zu\n", stream, meta_count);
for (size_t i = 0; i < meta_count; i++) {
if (!valid_metadata_type(meta->data.type, meta->data.data_len)) {
printk("Invalid metadata type %u or length %u\n",
meta->data.type, meta->data.data_len);
return -EINVAL;
}
}
return 0;
}
static int unicast_server_disable(struct bt_bap_stream *stream)
{
printk("Disable: stream %p\n", stream);
return 0;
}
static int unicast_server_stop(struct bt_bap_stream *stream)
{
printk("Stop: stream %p\n", stream);
return 0;
}
static int unicast_server_release(struct bt_bap_stream *stream)
{
printk("Release: stream %p\n", stream);
return 0;
}
static struct bt_bap_unicast_server_cb unicast_server_cbs = {
.config = unicast_server_config,
.reconfig = unicast_server_reconfig,
.qos = unicast_server_qos,
.enable = unicast_server_enable,
.start = unicast_server_start,
.metadata = unicast_server_metadata,
.disable = unicast_server_disable,
.stop = unicast_server_stop,
.release = unicast_server_release,
};
static void set_location(void)
{
int err;
if (IS_ENABLED(CONFIG_BT_PAC_SNK_LOC)) {
err = bt_pacs_set_location(BT_AUDIO_DIR_SINK,
BT_AUDIO_LOCATION_FRONT_CENTER);
if (err != 0) {
FAIL("Failed to set sink location (err %d)\n", err);
return;
}
}
if (IS_ENABLED(CONFIG_BT_PAC_SRC_LOC)) {
err = bt_pacs_set_location(BT_AUDIO_DIR_SOURCE,
BT_AUDIO_LOCATION_FRONT_LEFT |
BT_AUDIO_LOCATION_FRONT_RIGHT);
if (err != 0) {
FAIL("Failed to set source location (err %d)\n", err);
return;
}
}
printk("Location successfully set\n");
}
static int set_supported_contexts(void)
{
int err;
if (IS_ENABLED(CONFIG_BT_PAC_SNK)) {
err = bt_pacs_set_supported_contexts(BT_AUDIO_DIR_SINK, SINK_CONTEXT);
if (err != 0) {
printk("Failed to set sink supported contexts (err %d)\n",
err);
return err;
}
}
if (IS_ENABLED(CONFIG_BT_PAC_SRC)) {
err = bt_pacs_set_supported_contexts(BT_AUDIO_DIR_SOURCE, SOURCE_CONTEXT);
if (err != 0) {
printk("Failed to set source supported contexts (err %d)\n",
err);
return err;
}
}
printk("Supported contexts successfully set\n");
return 0;
}
static void set_available_contexts(void)
{
int err;
err = bt_pacs_set_available_contexts(BT_AUDIO_DIR_SINK, SINK_CONTEXT);
if (IS_ENABLED(CONFIG_BT_PAC_SNK) && err != 0) {
FAIL("Failed to set sink available contexts (err %d)\n", err);
return;
}
err = bt_pacs_set_available_contexts(BT_AUDIO_DIR_SOURCE, SOURCE_CONTEXT);
if (IS_ENABLED(CONFIG_BT_PAC_SRC) && err != 0) {
FAIL("Failed to set source available contexts (err %d)\n", err);
return;
}
printk("Available contexts successfully set\n");
}
static void init(void)
{
struct bt_csip_set_member_register_param csip_set_member_param = {
const struct bt_csip_set_member_register_param csip_set_member_param = {
.set_size = 3,
.rank = 1,
.lockable = true,
/* Using the CSIP_SET_MEMBER test sample SIRK */
.set_sirk = { 0xcd, 0xcc, 0x72, 0xdd, 0x86, 0x8c, 0xcd, 0xce,
0x22, 0xfd, 0xa1, 0x21, 0x09, 0x7d, 0x7d, 0x45 },
0x22, 0xfd, 0xa1, 0x21, 0x09, 0x7d, 0x7d, 0x45 },
};
int err;
@ -215,8 +506,7 @@ static void init(void)
printk("Bluetooth initialized\n");
if (IS_ENABLED(CONFIG_BT_CAP_ACCEPTOR_SET_MEMBER)) {
err = bt_cap_acceptor_register(&csip_set_member_param,
&csip_set_member);
err = bt_cap_acceptor_register(&csip_set_member_param, &csip_set_member);
if (err != 0) {
FAIL("CAP acceptor failed to register (err %d)\n", err);
return;
@ -224,8 +514,32 @@ static void init(void)
}
if (IS_ENABLED(CONFIG_BT_BAP_UNICAST_SERVER)) {
static struct bt_pacs_cap unicast_cap = {
.codec = &unicast_preset_16_2_1.codec,
};
err = bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &unicast_cap);
if (err != 0) {
FAIL("Broadcast capability register failed (err %d)\n",
err);
return;
}
err = bt_bap_unicast_server_register_cb(&unicast_server_cbs);
if (err != 0) {
FAIL("Failed to register unicast server callbacks (err %d)\n",
err);
return;
}
for (size_t i = 0U; i < ARRAY_SIZE(unicast_streams); i++) {
bt_cap_stream_ops_register(&unicast_streams[i], &unicast_stream_ops);
}
err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, cap_acceptor_ad,
ARRAY_SIZE(cap_acceptor_ad), NULL, 0);
ARRAY_SIZE(cap_acceptor_ad), NULL, 0);
if (err != 0) {
FAIL("Advertising failed to start (err %d)\n", err);
return;
@ -233,11 +547,11 @@ static void init(void)
}
if (IS_ENABLED(CONFIG_BT_BAP_BROADCAST_SINK)) {
static struct bt_pacs_cap cap = {
static struct bt_pacs_cap broadcast_cap = {
.codec = &broadcast_preset_16_2_1.codec,
};
err = bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &cap);
err = bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &broadcast_cap);
if (err != 0) {
FAIL("Broadcast capability register failed (err %d)\n",
err);
@ -256,6 +570,10 @@ static void init(void)
&broadcast_stream_ops);
}
}
set_supported_contexts();
set_available_contexts();
set_location();
}
static void test_cap_acceptor_unicast(void)

View file

@ -9,35 +9,50 @@
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/audio/bap_lc3_preset.h>
#include <zephyr/bluetooth/audio/cap.h>
#include <zephyr/bluetooth/audio/bap.h>
#include "common.h"
#include "bap_unicast_common.h"
#if defined(CONFIG_BT_BAP_BROADCAST_SOURCE)
#define BROADCAST_STREMT_CNT CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT
#else
#define BROADCAST_STREMT_CNT 0
#endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */
/* When BROADCAST_ENQUEUE_COUNT > 1 we can enqueue enough buffers to ensure that
* the controller is never idle
*/
#define BROADCAST_ENQUEUE_COUNT 2U
#define TOTAL_BUF_NEEDED (BROADCAST_ENQUEUE_COUNT * CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT)
#define TOTAL_BUF_NEEDED (BROADCAST_ENQUEUE_COUNT * BROADCAST_STREMT_CNT)
BUILD_ASSERT(CONFIG_BT_ISO_TX_BUF_COUNT >= TOTAL_BUF_NEEDED,
"CONFIG_BT_ISO_TX_BUF_COUNT should be at least "
"BROADCAST_ENQUEUE_COUNT * CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT");
"BROADCAST_ENQUEUE_COUNT * BROADCAST_STREMT_CNT");
NET_BUF_POOL_FIXED_DEFINE(tx_pool,
TOTAL_BUF_NEEDED,
BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), 8, NULL);
extern enum bst_result_t bst_result;
static struct bt_cap_stream broadcast_source_streams[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT];
static struct bt_cap_stream broadcast_source_streams[BROADCAST_STREMT_CNT];
static struct bt_cap_stream *broadcast_streams[ARRAY_SIZE(broadcast_source_streams)];
static struct bt_bap_lc3_preset broadcast_preset_16_2_1 = BT_BAP_LC3_BROADCAST_PRESET_16_2_1(
BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_MEDIA);
static struct bt_bap_lc3_preset unicast_preset_16_2_1 =
BT_BAP_LC3_UNICAST_PRESET_16_2_1(BT_AUDIO_LOCATION_FRONT_LEFT,
BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED);
static struct bt_cap_stream unicast_client_streams[CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT];
static struct bt_bap_ep *unicast_sink_eps[CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT];
static K_SEM_DEFINE(sem_broadcast_started, 0U, ARRAY_SIZE(broadcast_streams));
static K_SEM_DEFINE(sem_broadcast_stopped, 0U, ARRAY_SIZE(broadcast_streams));
CREATE_FLAG(flag_discovered);
CREATE_FLAG(flag_started);
CREATE_FLAG(flag_mtu_exchanged);
CREATE_FLAG(flag_sink_discovered);
CREATE_FLAG(flag_broadcast_stopping);
static void broadcast_started_cb(struct bt_bap_stream *stream)
@ -100,6 +115,63 @@ static struct bt_bap_stream_ops broadcast_stream_ops = {.started = broadcast_sta
.stopped = broadcast_stopped_cb,
.sent = broadcast_sent_cb};
static void unicast_stream_configured(struct bt_bap_stream *stream,
const struct bt_codec_qos_pref *pref)
{
printk("Configured stream %p\n", stream);
/* TODO: The preference should be used/taken into account when
* setting the QoS
*/
}
static void unicast_stream_qos_set(struct bt_bap_stream *stream)
{
printk("QoS set stream %p\n", stream);
}
static void unicast_stream_enabled(struct bt_bap_stream *stream)
{
printk("Enabled stream %p\n", stream);
}
static void unicast_stream_started(struct bt_bap_stream *stream)
{
printk("Started stream %p\n", stream);
}
static void unicast_stream_metadata_updated(struct bt_bap_stream *stream)
{
printk("Metadata updated stream %p\n", stream);
}
static void unicast_stream_disabled(struct bt_bap_stream *stream)
{
printk("Disabled stream %p\n", stream);
}
static void unicast_stream_stopped(struct bt_bap_stream *stream, uint8_t reason)
{
printk("Stopped stream with reason 0x%02X%p\n", stream, reason);
}
static void unicast_stream_released(struct bt_bap_stream *stream)
{
printk("Released stream %p\n", stream);
}
static struct bt_bap_stream_ops unicast_stream_ops = {
.configured = unicast_stream_configured,
.qos_set = unicast_stream_qos_set,
.enabled = unicast_stream_enabled,
.started = unicast_stream_started,
.metadata_updated = unicast_stream_metadata_updated,
.disabled = unicast_stream_disabled,
.stopped = unicast_stream_stopped,
.released = unicast_stream_released,
};
static void cap_discovery_complete_cb(struct bt_conn *conn, int err,
const struct bt_csip_set_coordinator_csis_inst *csis_inst)
{
@ -124,10 +196,77 @@ static void cap_discovery_complete_cb(struct bt_conn *conn, int err,
SET_FLAG(flag_discovered);
}
static void unicast_start_complete_cb(struct bt_bap_unicast_group *unicast_group,
int err, struct bt_conn *conn)
{
if (err != 0) {
FAIL("Failed to start (failing conn %p): %d", conn, err);
return;
}
SET_FLAG(flag_started);
}
static struct bt_cap_initiator_cb cap_cb = {
.unicast_discovery_complete = cap_discovery_complete_cb
.unicast_discovery_complete = cap_discovery_complete_cb,
.unicast_start_complete = unicast_start_complete_cb,
};
static void add_remote_sink(struct bt_bap_ep *ep, uint8_t index)
{
printk("Sink #%u: ep %p\n", index, ep);
unicast_sink_eps[index] = ep;
}
static void print_remote_codec(struct bt_codec *codec, int index, enum bt_audio_dir dir)
{
printk("#%u: codec %p dir 0x%02x\n", index, codec, dir);
print_codec(codec);
}
static void discover_sink_cb(struct bt_conn *conn, struct bt_codec *codec, struct bt_bap_ep *ep,
struct bt_bap_unicast_client_discover_params *params)
{
static bool codec_found;
static bool endpoint_found;
if (params->err != 0) {
FAIL("Discovery failed: %d\n", params->err);
return;
}
if (codec != NULL) {
print_remote_codec(codec, params->num_caps, params->dir);
codec_found = true;
return;
}
if (ep != NULL) {
if (params->dir == BT_AUDIO_DIR_SINK) {
add_remote_sink(ep, params->num_eps);
endpoint_found = true;
} else {
FAIL("Invalid param dir: %u\n", params->dir);
}
return;
}
printk("Sink discover complete\n");
(void)memset(params, 0, sizeof(*params));
if (endpoint_found && codec_found) {
SET_FLAG(flag_sink_discovered);
} else {
FAIL("Did not discover endpoint and codec\n");
}
}
static void att_mtu_updated(struct bt_conn *conn, uint16_t tx, uint16_t rx)
{
printk("MTU exchanged\n");
@ -157,6 +296,13 @@ static void init(void)
return;
}
for (size_t i = 0; i < ARRAY_SIZE(broadcast_streams); i++) {
bt_cap_stream_ops_register(&unicast_client_streams[i],
&unicast_stream_ops);
}
}
if (IS_ENABLED(CONFIG_BT_BAP_BROADCAST_SINK)) {
(void)memset(broadcast_source_streams, 0,
sizeof(broadcast_source_streams));
@ -182,6 +328,23 @@ static void scan_and_connect(void)
WAIT_FOR_FLAG(flag_connected);
}
static void discover_sink(void)
{
static struct bt_bap_unicast_client_discover_params params;
int err;
params.func = discover_sink_cb;
params.dir = BT_AUDIO_DIR_SINK;
err = bt_bap_unicast_client_discover(default_conn, &params);
if (err != 0) {
printk("Failed to discover sink: %d\n", err);
return;
}
WAIT_FOR_FLAG(flag_sink_discovered);
}
static void discover_cas(void)
{
int err;
@ -197,8 +360,59 @@ static void discover_cas(void)
WAIT_FOR_FLAG(flag_discovered);
}
static void unicast_group_create(struct bt_bap_unicast_group **out_unicast_group)
{
struct bt_bap_unicast_group_stream_param group_stream_params;
struct bt_bap_unicast_group_stream_pair_param pair_params;
struct bt_bap_unicast_group_param group_param;
int err;
group_stream_params.qos = &unicast_preset_16_2_1.qos;
group_stream_params.stream = &unicast_client_streams[0].bap_stream;
pair_params.tx_param = &group_stream_params;
pair_params.rx_param = NULL;
group_param.packing = BT_ISO_PACKING_SEQUENTIAL;
group_param.params_count = 1;
group_param.params = &pair_params;
err = bt_bap_unicast_group_create(&group_param, out_unicast_group);
if (err != 0) {
FAIL("Failed to create group: %d\n", err);
return;
}
}
static void unicast_audio_start(struct bt_bap_unicast_group *unicast_group)
{
struct bt_cap_unicast_audio_start_stream_param stream_param[1];
struct bt_cap_unicast_audio_start_param param;
int err;
param.type = BT_CAP_SET_TYPE_AD_HOC;
param.count = 1u;
param.stream_params = stream_param;
stream_param[0].member.member = default_conn;
stream_param[0].stream = &unicast_client_streams[0];
stream_param[0].ep = unicast_sink_eps[0];
stream_param[0].codec = &unicast_preset_16_2_1.codec;
stream_param[0].qos = &unicast_preset_16_2_1.qos;
UNSET_FLAG(flag_started);
err = bt_cap_initiator_unicast_audio_start(&param, unicast_group);
if (err != 0) {
FAIL("Failed to start unicast audio: %d\n", err);
return;
}
WAIT_FOR_FLAG(flag_started);
}
static void test_cap_initiator_unicast(void)
{
struct bt_bap_unicast_group *unicast_group;
init();
scan_and_connect();
@ -207,6 +421,12 @@ static void test_cap_initiator_unicast(void)
discover_cas();
discover_sink();
unicast_group_create(&unicast_group);
unicast_audio_start(unicast_group);
PASS("CAP initiator unicast passed\n");
}