blob: 9dd7a45e89c116742ccc92febb8a4c3e6fb8f08f [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0-or-later
/*
*
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2022 Intel Corporation.
* Copyright 2024 NXP
*
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#define _GNU_SOURCE
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <glib.h>
#include "lib/bluetooth.h"
#include "lib/uuid.h"
#include "src/shared/util.h"
#include "src/shared/io.h"
#include "src/shared/tester.h"
#include "src/shared/queue.h"
#include "src/shared/att.h"
#include "src/shared/gatt-db.h"
#include "src/shared/gatt-client.h"
#include "src/shared/bap.h"
#include "src/shared/lc3.h"
struct test_config {
struct bt_bap_pac_qos pqos;
struct iovec cc;
struct iovec base;
struct bt_bap_qos qos;
bool snk;
bool src;
bool vs;
uint8_t state;
bt_bap_state_func_t state_func;
uint8_t streams;
};
struct test_data {
struct bt_gatt_client *client;
struct gatt_db *db;
struct bt_bap *bap;
struct bt_bap_pac *snk;
struct bt_bap_pac *src;
struct bt_bap_pac *bsrc;
struct bt_bap_pac *bsnk;
struct iovec *base;
struct iovec *caps;
struct test_config *cfg;
struct queue *streams;
size_t iovcnt;
struct iovec *iov;
};
/*
* Frequencies: 8Khz 11Khz 16Khz 22Khz 24Khz 32Khz 44.1Khz 48Khz
* Duration: 7.5 ms 10 ms
* Channel count: 3
* Frame length: 26-240
*/
static struct iovec lc3_caps = LC3_CAPABILITIES(LC3_FREQ_ANY, LC3_DURATION_ANY,
3u, 26, 240);
#define iov_data(args...) ((const struct iovec[]) { args })
#define define_test(name, setup, function, _cfg, args...) \
do { \
const struct iovec iov[] = { args }; \
static struct test_data data; \
data.caps = &lc3_caps; \
data.cfg = _cfg; \
data.iovcnt = ARRAY_SIZE(iov_data(args)); \
data.iov = util_iov_dup(iov, ARRAY_SIZE(iov_data(args))); \
data.streams = queue_new(); \
tester_add(name, &data, setup, function, \
test_teardown); \
} while (0)
static void client_ready_cb(bool success, uint8_t att_ecode, void *user_data)
{
if (!success)
tester_setup_failed();
else
tester_setup_complete();
}
/* GATT Discover All procedure */
static const struct iovec setup_data[] = {
/* ATT: Exchange MTU Response (0x03) len 2
* Server RX MTU: 64
*/
IOV_DATA(0x02, 0x40, 0x00),
/* ATT: Exchange MTU Request (0x02) len 2
* Client RX MTU: 64
*/
IOV_DATA(0x03, 0x40, 0x00),
/* ATT: Read By Type Request (0x08) len 6
* Handle range: 0x0001-0xffff
* Attribute type: Server Supported Features (0x2b3a)
*/
IOV_DATA(0x08, 0x01, 0x00, 0xff, 0xff, 0x3a, 0x2b),
/* ATT: Error Response (0x01) len 4
* Read By Type Request (0x08)
* Handle: 0x0001
* Error: Attribute Not Found (0x0a)
*/
IOV_DATA(0x01, 0x08, 0x01, 0x00, 0x0a),
/*
* ATT: Read By Group Type Request (0x10) len 6
* Handle range: 0x0001-0xffff
* Attribute group type: Primary Service (0x2800)
*/
IOV_DATA(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
/*
* ATT: Read By Group Type Response (0x11) len 37
* Attribute data length: 6
* Attribute group list: 2 entries
* Handle range: 0x0001-0x0013
* UUID: Published Audio Capabilities (0x1850)
* Handle range: 0x0014-0x0023
* UUID: Audio Stream Control (0x184e)
*/
IOV_DATA(0x11, 0x06,
0x01, 0x00, 0x13, 0x00, 0x50, 0x18,
0x14, 0x00, 0x23, 0x00, 0x4e, 0x18),
/* ATT: Read By Group Type Request (0x10) len 6
* Handle range: 0x0024-0xffff
* Attribute group type: Primary Service (0x2800)
*/
IOV_DATA(0x10, 0x24, 0x00, 0xff, 0xff, 0x00, 0x28),
/* ATT: Error Response (0x01) len 4
* Read By Group Type Request (0x10)
* Handle: 0x0024
* Error: Attribute Not Found (0x0a)
*/
IOV_DATA(0x01, 0x10, 0x24, 0x00, 0x0a),
/* ATT: Read By Group Type Request (0x10) len 6
* Handle range: 0x0001-0xffff
* Attribute group type: Secondary Service (0x2801)
*/
IOV_DATA(0x10, 0x01, 0x00, 0xff, 0xff, 0x01, 0x28),
/* ATT: Error Response (0x01) len 4
* Read By Group Type Request (0x10)
* Handle: 0x0001
* Error: Attribute Not Found (0x0a)
*/
IOV_DATA(0x01, 0x10, 0x01, 0x00, 0x0a),
/* ATT: Read By Type Request (0x08) len 6
* Handle range: 0x0001-0x0023
* Attribute group type: Include (0x2802)
*/
IOV_DATA(0x08, 0x01, 0x00, 0x23, 0x00, 0x02, 0x28),
/* ATT: Error Response (0x01) len 4
* Read By Group Type Request (0x10)
* Handle: 0x0001
* Error: Attribute Not Found (0x0a)
*/
IOV_DATA(0x01, 0x08, 0x01, 0x00, 0x0a),
/* ATT: Read By Type Request (0x08) len 6
* Handle range: 0x0001-0x0023
* Attribute type: Characteristic (0x2803)
*/
IOV_DATA(0x08, 0x01, 0x00, 0x23, 0x00, 0x03, 0x28),
/* ATT: Read By Type Response (0x09) len 57
* Attribute data length: 7
* Attribute data list: 8 entries
* Handle: 0x0002
* Value: 120300c92b
* Properties: 0x12
* Read (0x02)
* Notify (0x10)
* Value Handle: 0x0003
* Value UUID: Sink PAC (0x2bc9)
* Handle: 0x0005
* Value: 120600ca2b
* Properties: 0x12
* Read (0x02)
* Notify (0x10)
* Value Handle: 0x0006
* Value UUID: Sink Audio Locations (0x2bca)
* Handle: 0x0008
* Value: 120900cb2b
* Properties: 0x12
* Read (0x02)
* Notify (0x10)
* Value Handle: 0x0009
* Value UUID: Source PAC (0x2bcb)
* Handle: 0x000b
* Value: 120c00cc2b
* Properties: 0x12
* Read (0x02)
* Notify (0x10)
* Value Handle: 0x000c
* Value UUID: Source Audio Locations (0x2bcc)
* Handle: 0x000e
* Value: 120f00cd2b
* Properties: 0x12
* Read (0x02)
* Notify (0x10)
* Value Handle: 0x000f
* Value UUID: Available Audio Contexts (0x2bcd)
* Handle: 0x0011
* Value: 121200ce2b
* Properties: 0x12
* Read (0x02)
* Notify (0x10)
* Value Handle: 0x0012
* Value UUID: Supported Audio Contexts (0x2bce)
* Handle: 0x0015
* Value: 121600c42b
* Properties: 0x12
* Read (0x02)
* Notify (0x10)
* Value Handle: 0x0016
* Value UUID: Sink ASE (0x2bc4)
* Handle: 0x0018
* Value: 121900c42b
* Properties: 0x12
* Read (0x02)
* Notify (0x10)
* Value Handle: 0x0019
* Value UUID: Sink ASE (0x2bc4)
*/
IOV_DATA(0x09, 0x07,
0x02, 0x00, 0x12, 0x03, 0x00, 0xc9, 0x2b,
0x05, 0x00, 0x12, 0x06, 0x00, 0xca, 0x2b,
0x08, 0x00, 0x12, 0x09, 0x00, 0xcb, 0x2b,
0x0b, 0x00, 0x12, 0x0c, 0x00, 0xcc, 0x2b,
0x0e, 0x00, 0x12, 0x0f, 0x00, 0xcd, 0x2b,
0x11, 0x00, 0x12, 0x12, 0x00, 0xce, 0x2b,
0x15, 0x00, 0x12, 0x16, 0x00, 0xc4, 0x2b,
0x18, 0x00, 0x12, 0x19, 0x00, 0xc4, 0x2b),
/* ATT: Read By Type Request (0x08) len 6
* Handle range: 0x0001-0x0023
* Attribute type: Characteristic (0x2803)
*/
IOV_DATA(0x08, 0x19, 0x00, 0x23, 0x00, 0x03, 0x28),
/* ATT: Read By Type Response (0x09) len 22
* Attribute data length: 7
* Attribute data list: 3 entries
* Handle: 0x001b
* Value: 121c00c52b
* Properties: 0x12
* Read (0x02)
* Notify (0x10)
* Value Handle: 0x001c
* Value UUID: Source ASE (0x2bc5)
* Handle: 0x001e
* Value: 121f00c52b
* Properties: 0x12
* Read (0x02)
* Notify (0x10)
* Value Handle: 0x001f
* Value UUID: Source ASE (0x2bc5)
* Handle: 0x0021
* Value: 182200c62b
* Properties: 0x18
* Write (0x08)
* Notify (0x10)
* Value Handle: 0x0022
* Value UUID: ASE Control Point (0x2bc6)
*/
IOV_DATA(0x09, 0x07,
0x1b, 0x00, 0x12, 0x1c, 0x00, 0xc5, 0x2b,
0x1e, 0x00, 0x12, 0x1f, 0x00, 0xc5, 0x2b,
0x21, 0x00, 0x18, 0x22, 0x00, 0xc6, 0x2b),
/* ATT: Read By Type Request (0x08) len 6
* Handle range: 0x0022-0x0023
* Attribute type: Characteristic (0x2803)
*/
IOV_DATA(0x08, 0x22, 0x00, 0x23, 0x00, 0x03, 0x28),
/* ATT: Error Response (0x01) len 4
* Read By Type Request (0x08)
* Handle: 0x0022
* Error: Attribute Not Found (0x0a)
*/
IOV_DATA(0x01, 0x08, 0x23, 0x00, 0x0a),
/* ACL Data TX: Handle 42 flags 0x00 dlen 11
* ATT: Read By Type Request (0x08) len 6
* Handle range: 0x0001-0xffff
* Attribute type: Database Hash (0x2b2a)
*/
IOV_DATA(0x08, 0x01, 0x00, 0xff, 0xff, 0x2a, 0x2b),
/* ATT: Error Response (0x01) len 4
* Read By Type Request (0x08)
* Handle: 0x0001
* Error: Attribute Not Found (0x0a)
*/
IOV_DATA(0x01, 0x08, 0x01, 0x00, 0x0a),
};
static void print_debug(const char *str, void *user_data)
{
const char *prefix = user_data;
if (tester_use_debug())
tester_debug("%s%s", prefix, str);
}
static void test_setup(const void *user_data)
{
struct test_data *data = (void *)user_data;
struct bt_att *att;
struct gatt_db *db;
struct io *io;
io = tester_setup_io(setup_data, ARRAY_SIZE(setup_data));
g_assert(io);
att = bt_att_new(io_get_fd(io), false);
g_assert(att);
bt_att_set_debug(att, BT_ATT_DEBUG, print_debug, "bt_att:", NULL);
db = gatt_db_new();
g_assert(db);
data->client = bt_gatt_client_new(db, att, 64, 0);
g_assert(data->client);
bt_gatt_client_set_debug(data->client, print_debug, "bt_gatt_client:",
NULL);
bt_gatt_client_ready_register(data->client, client_ready_cb, data,
NULL);
bt_att_unref(att);
gatt_db_unref(db);
}
static void test_complete_cb(const void *user_data)
{
tester_test_passed();
}
static void bap_disable(struct bt_bap_stream *stream,
uint8_t code, uint8_t reason,
void *user_data)
{
if (code)
tester_test_failed();
}
static void bap_start(struct bt_bap_stream *stream,
uint8_t code, uint8_t reason,
void *user_data)
{
if (code)
tester_test_failed();
}
static void bap_enable(struct bt_bap_stream *stream,
uint8_t code, uint8_t reason,
void *user_data)
{
struct test_data *data = user_data;
unsigned int id = 0;
if (code) {
tester_test_failed();
return;
}
switch (data->cfg->state) {
case BT_BAP_STREAM_STATE_ENABLING:
return;
case BT_BAP_STREAM_STATE_DISABLING:
id = bt_bap_stream_disable(stream, true, bap_disable,
data);
break;
case BT_BAP_STREAM_STATE_STREAMING:
if (data->cfg->snk)
return;
id = bt_bap_stream_start(stream, bap_start, data);
break;
}
g_assert(id);
}
static void bap_qos(struct bt_bap_stream *stream,
uint8_t code, uint8_t reason,
void *user_data)
{
struct test_data *data = user_data;
if (code) {
tester_test_failed();
return;
}
if (data->cfg->state > BT_BAP_STREAM_STATE_QOS) {
unsigned int qos_id;
qos_id = bt_bap_stream_enable(stream, true, NULL,
bap_enable, data);
g_assert(qos_id);
}
}
static void bap_config(struct bt_bap_stream *stream,
uint8_t code, uint8_t reason,
void *user_data)
{
struct test_data *data = user_data;
if (code) {
tester_test_failed();
return;
}
if (data->cfg->state > BT_BAP_STREAM_STATE_CONFIG) {
unsigned int qos_id;
qos_id = bt_bap_stream_qos(stream, &data->cfg->qos,
bap_qos, data);
g_assert(qos_id);
}
}
static bool pac_found(struct bt_bap_pac *lpac, struct bt_bap_pac *rpac,
void *user_data)
{
struct test_data *data = user_data;
unsigned int config_id;
struct bt_bap_stream *stream;
stream = bt_bap_stream_new(data->bap, lpac, rpac,
&data->cfg->qos,
&data->cfg->cc);
g_assert(stream);
queue_push_tail(data->streams, stream);
config_id = bt_bap_stream_config(stream, &data->cfg->qos,
&data->cfg->cc, bap_config, data);
g_assert(config_id);
return true;
}
static void bap_ready(struct bt_bap *bap, void *user_data)
{
bt_bap_foreach_pac(bap, BT_BAP_SINK, pac_found, user_data);
bt_bap_foreach_pac(bap, BT_BAP_SOURCE, pac_found, user_data);
}
static void test_client_config(struct test_data *data)
{
if (!data->cfg)
return;
if (data->cfg->src) {
if (data->cfg->vs)
data->snk = bt_bap_add_vendor_pac(data->db,
"test-bap-snk",
BT_BAP_SINK, 0x0ff,
0x0001, 0x0001,
NULL, data->caps, NULL);
else
data->snk = bt_bap_add_pac(data->db, "test-bap-snk",
BT_BAP_SINK, LC3_ID,
NULL, data->caps, NULL);
g_assert(data->snk);
}
if (data->cfg->snk) {
if (data->cfg->vs)
data->src = bt_bap_add_vendor_pac(data->db,
"test-bap-src",
BT_BAP_SOURCE, 0x0ff,
0x0001, 0x0001,
NULL, data->caps, NULL);
else
data->src = bt_bap_add_pac(data->db, "test-bap-src",
BT_BAP_SOURCE, LC3_ID,
NULL, data->caps, NULL);
g_assert(data->src);
}
}
static void test_client(const void *user_data)
{
struct test_data *data = (void *)user_data;
struct io *io;
io = tester_setup_io(data->iov, data->iovcnt);
g_assert(io);
tester_io_set_complete_func(test_complete_cb);
data->db = gatt_db_new();
g_assert(data->db);
test_client_config(data);
data->bap = bt_bap_new(data->db, bt_gatt_client_get_db(data->client));
g_assert(data->bap);
bt_bap_set_debug(data->bap, print_debug, "bt_bap:", NULL);
bt_bap_ready_register(data->bap, bap_ready, data, NULL);
if (data->cfg && data->cfg->state_func)
bt_bap_state_register(data->bap, data->cfg->state_func, NULL,
data, NULL);
bt_bap_attach(data->bap, data->client);
}
static int pac_config(struct bt_bap_stream *stream, struct iovec *cfg,
struct bt_bap_qos *qos, bt_bap_pac_config_t cb,
void *user_data)
{
cb(stream, 0);
return 0;
}
static struct bt_bap_pac_ops bcast_pac_ops = {
.config = pac_config,
};
static void bsrc_pac_added(struct bt_bap_pac *pac, void *user_data)
{
struct test_data *data = user_data;
struct bt_bap_stream *stream;
bt_bap_pac_set_ops(pac, &bcast_pac_ops, NULL);
for (uint8_t i = 0; i < data->cfg->streams; i++) {
stream = bt_bap_stream_new(data->bap, pac, NULL,
&data->cfg->qos,
&data->cfg->cc);
g_assert(stream);
queue_push_tail(data->streams, stream);
bt_bap_stream_config(stream, &data->cfg->qos,
&data->cfg->cc, NULL, data);
}
}
static void bsrc_state_cfg(struct bt_bap_stream *stream, uint8_t old_state,
uint8_t new_state, void *user_data)
{
struct test_data *data = user_data;
switch (new_state) {
case BT_BAP_STREAM_STATE_CONFIG:
data->base = bt_bap_stream_get_base(stream);
g_assert(data->base);
g_assert(data->base->iov_len == data->cfg->base.iov_len);
g_assert(memcmp(data->base->iov_base, data->cfg->base.iov_base,
data->base->iov_len) == 0);
tester_test_passed();
break;
}
}
static void bsnk_pac_added(struct bt_bap_pac *pac, void *user_data)
{
struct test_data *data = user_data;
struct bt_bap_pac *lpac;
struct iovec *cc;
struct bt_bap_codec codec = {0};
struct bt_bap_stream *stream;
uint8_t bis_idx = 1;
bt_bap_pac_set_ops(pac, &bcast_pac_ops, NULL);
if (data->cfg->vs)
codec.id = 0xff;
else
codec.id = LC3_ID;
for (uint8_t i = 0; i < data->cfg->streams; i++) {
bt_bap_verify_bis(data->bap, bis_idx++, &codec,
&data->cfg->cc, NULL, &lpac, &cc);
g_assert(lpac);
g_assert(pac == lpac);
g_assert(cc);
stream = bt_bap_stream_new(data->bap,
pac, NULL, &data->cfg->qos, cc);
g_assert(stream);
queue_push_tail(data->streams, stream);
bt_bap_stream_config(stream, &data->cfg->qos,
cc, NULL, NULL);
util_iov_free(cc, 1);
}
}
static void bsnk_state(struct bt_bap_stream *stream, uint8_t old_state,
uint8_t new_state, void *user_data)
{
struct test_data *data = user_data;
struct iovec *cc;
switch (new_state) {
case BT_BAP_STREAM_STATE_CONFIG:
/* Check that stream has been configured as expected */
cc = bt_bap_stream_get_config(stream);
g_assert(cc);
g_assert(cc->iov_len == data->cfg->cc.iov_len);
g_assert(memcmp(cc->iov_base, data->cfg->cc.iov_base,
cc->iov_len) == 0);
tester_test_passed();
break;
}
}
static void test_bcast_config(struct test_data *data)
{
if (!data->cfg)
return;
if (data->cfg->src) {
bt_bap_pac_register(data->bap, bsrc_pac_added,
NULL, data, NULL);
if (data->cfg->vs)
data->bsrc = bt_bap_add_vendor_pac(data->db,
"test-bap-bsrc",
BT_BAP_BCAST_SOURCE,
0x0ff, 0x0000, 0x0000,
NULL, data->caps,
NULL);
else
data->bsrc = bt_bap_add_pac(data->db, "test-bap-bsrc",
BT_BAP_BCAST_SOURCE,
LC3_ID,
NULL, data->caps,
NULL);
g_assert(data->bsrc);
}
if (data->cfg->snk) {
bt_bap_pac_register(data->bap, bsnk_pac_added,
NULL, data, NULL);
if (data->cfg->vs)
data->bsnk = bt_bap_add_vendor_pac(data->db,
"test-bap-bsnk",
BT_BAP_BCAST_SINK,
0xff, 0x0000, 0x0000,
NULL, data->caps,
NULL);
else
data->bsnk = bt_bap_add_pac(data->db, "test-bap-bsnk",
BT_BAP_BCAST_SINK,
LC3_ID,
NULL, data->caps,
NULL);
g_assert(data->bsnk);
}
}
static void test_bcast(const void *user_data)
{
struct test_data *data = (void *)user_data;
data->db = gatt_db_new();
g_assert(data->db);
data->bap = bt_bap_new(data->db, data->db);
g_assert(data->bap);
bt_bap_set_debug(data->bap, print_debug, "bt_bap:", NULL);
bt_bap_attach_broadcast(data->bap);
if (data->cfg && data->cfg->state_func)
bt_bap_state_register(data->bap, data->cfg->state_func, NULL,
data, NULL);
test_bcast_config(data);
}
static void test_teardown(const void *user_data)
{
struct test_data *data = (void *)user_data;
bt_bap_unref(data->bap);
bt_gatt_client_unref(data->client);
util_iov_free(data->iov, data->iovcnt);
util_iov_free(data->base, 1);
bt_bap_remove_pac(data->snk);
bt_bap_remove_pac(data->src);
bt_bap_remove_pac(data->bsrc);
bt_bap_remove_pac(data->bsnk);
gatt_db_unref(data->db);
queue_destroy(data->streams, NULL);
tester_teardown_complete();
}
/* ATT: Read Request (0x0a) len 2
* Handle: 0x0003 Type: Sink PAC (0x2bc9)
* ATT: Read Response (0x0b) len 24
* Value: 010600000000100301ff0002020302030305041e00f00000
* Handle: 0x0003 Type: Sink PAC (0x2bc9)
* Number of PAC(s): 1
* PAC #0:
* Codec: LC3 (0x06)
* Codec Specific Capabilities #0: len 0x03 type 0x01
* Sampling Frequencies: 0x00ff
* 8 Khz (0x0001)
* 11.25 Khz (0x0002)
* 16 Khz (0x0004)
* 22.05 Khz (0x0008)
* 24 Khz (0x0010)
* 32 Khz (0x0020)
* 44.1 Khz (0x0040)
* 48 Khz (0x0080)
* Codec Specific Capabilities #1: len 0x02 type 0x02
* Frame Duration: 0x0003
* 7.5 ms (0x01)
* 10 ms (0x02)
* Codec Specific Capabilities #2: len 0x02 type 0x03
* Audio Channel Count: 0x03
* 1 channel (0x01)
* 2 channels (0x02)
* Codec Specific Capabilities #3: len 0x05 type 0x04
* Frame Length: 30 (0x001e) - 240 (0x00f0)
* ATT: Read Request (0x0a) len 2
* Handle: 0x0006 Type: Sink Audio Location (0x2bca)
* ATT: Read Response (0x0b) len 4
* Value: 03000000
* Handle: 0x0006 Type: Sink Audio Locations (0x2bca)
* Location: 0x00000003
* Front Left (0x00000001)
* Front Right (0x00000002)
*/
#define DISC_SNK_PAC(_caps...) \
IOV_DATA(0x0a, 0x03, 0x00), \
IOV_DATA(0x0b, 0x01, _caps), \
IOV_DATA(0x0a, 0x06, 0x00), \
IOV_DATA(0x0b, 0x03, 0x00, 0x00, 0x00)
#define DISC_SNK_LC3 \
DISC_SNK_PAC(0x06, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x01, \
0xff, 0x00, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x05, 0x04, \
0x1e, 0x00, 0xf0, 0x00, 0x00)
/* ATT: Read Request (0x0a) len 2
* Handle: 0x0009 Type: Source PAC (0x2bcb)
* ATT: Read Response (0x0b) len 24
* Value: 010600000000100301ff0002020302030305041e00f00000
* Handle: 0x0009 Type: Source PAC (0x2bcb)
* Number of PAC(s): 1
* PAC #0:
* Codec: LC3 (0x06)
* Codec Specific Capabilities #0: len 0x03 type 0x01
* Sampling Frequencies: 0x00ff
* 8 Khz (0x0001)
* 11.25 Khz (0x0002)
* 16 Khz (0x0004)
* 22.05 Khz (0x0008)
* 24 Khz (0x0010)
* 32 Khz (0x0020)
* 44.1 Khz (0x0040)
* 48 Khz (0x0080)
* Codec Specific Capabilities #1: len 0x02 type 0x02
* Frame Duration: 0x0003
* 7.5 ms (0x01)
* 10 ms (0x02)
* Codec Specific Capabilities #2: len 0x02 type 0x03
* Audio Channel Count: 0x03
* 1 channel (0x01)
* 2 channels (0x02)
* Codec Specific Capabilities #3: len 0x05 type 0x04
* Frame Length: 30 (0x001e) - 240 (0x00f0)
* ATT: Read Request (0x0a) len 2
* Handle: 0x000c Type: Source Audio Location (0x2bcc)
* ATT: Read Response (0x0b) len 4
* Value: 03000000
* Handle: 0x000c Type: Source Audio Locations (0x2bcc)
* Location: 0x00000003
* Front Left (0x00000001)
* Front Right (0x00000002)
*/
#define DISC_SRC_PAC(_caps...) \
DISC_SNK_PAC(_caps), \
IOV_DATA(0x0a, 0x09, 0x00), \
IOV_DATA(0x0b, 0x01, _caps), \
IOV_DATA(0x0a, 0x0c, 0x00), \
IOV_DATA(0x0b, 0x03, 0x00, 0x00, 0x00)
#define DISC_SRC_LC3 \
DISC_SRC_PAC(0x06, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x01, \
0xff, 0x00, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x05, 0x04, \
0x1e, 0x00, 0xf0, 0x00, 0x00)
/* ATT: Read Request (0x0a) len 2
* Handle: 0x000f Type: Available Audio Contexts (0x2bcd)
* ATT: Read Response (0x0b) len 4
* Value: ff0f0e00
* Handle: 0x000f Type: Available Audio Contexts (0x2bcd)
*/
#define DISC_CTX(_caps...) \
DISC_SRC_PAC(_caps), \
IOV_DATA(0x0a, 0x0f, 0x00), \
IOV_DATA(0x0b, 0xff, 0x0f, 0x0e, 0x00)
#define DISC_CTX_LC3 \
DISC_CTX(0x06, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x01, \
0xff, 0x00, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x05, 0x04, \
0x1e, 0x00, 0xf0, 0x00, 0x00)
/* ATT: Read Request (0x0a) len 2
* Handle: 0x0012 Type: Supported Audio Contexts (0x2bce)
* ATT: Read Response (0x0b) len 4
* Value: ff0f0e00
* Handle: 0x0012 Type: Supported Audio Contexts (0x2bce)
*/
#define DISC_SUP_CTX(_caps...) \
DISC_CTX(_caps), \
IOV_DATA(0x0a, 0x12, 0x00), \
IOV_DATA(0x0b, 0xff, 0x0f, 0x0e, 0x00)
#define DISC_SUP_CTX_LC3 \
DISC_SUP_CTX(0x06, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x01, \
0xff, 0x00, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x05, 0x04, \
0x1e, 0x00, 0xf0, 0x00, 0x00)
/* ATT: Read Request (0x0a) len 2
* Handle: 0x0016 Type: Sink ASE (0x2bc4)
* ATT: Read Response (0x0b) len 4
* Value: 0100
* Handle: 0x0016 Type: Sink ASE (0x2bc4)
* ATT: Write Request (0x12) len 4
* Handle: 0x0017 Type: Client Characteristic Configuration (0x2902)
* Data: 0100
* Notification (0x01)
* ATT: Write Response (0x13) len 0
* ATT: Read Request (0x0a) len 2
* Handle: 0x0019 Type: Sink ASE (0x2bc4)
* ATT: Read Response (0x0b) len 4
* Value: 0200
* Handle: 0x0019 Type: Sink ASE (0x2bc4)
* ATT: Write Request (0x12) len 4
* Handle: 0x001a Type: Client Characteristic Configuration (0x2902)
* Data: 0100
* Notification (0x01)
* ATT: Write Response (0x13) len 0
*/
#define DISC_SNK_ASE(_caps...) \
DISC_SUP_CTX(_caps), \
IOV_DATA(0x0a, 0x16, 0x00), \
IOV_DATA(0x0b, 0x01, 0x00), \
IOV_DATA(0x12, 0x17, 0x00, 0x01, 0x00), \
IOV_DATA(0x13), \
IOV_DATA(0x0a, 0x19, 0x00), \
IOV_DATA(0x0b, 0x02, 0x00), \
IOV_DATA(0x12, 0x1a, 0x00, 0x01, 0x00), \
IOV_DATA(0x13)
#define DISC_SNK_ASE_LC3 \
DISC_SNK_ASE(0x06, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x01, \
0xff, 0x00, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x05, 0x04, \
0x1e, 0x00, 0xf0, 0x00, 0x00)
/* ATT: Read Request (0x0a) len 2
* Handle: 0x001c Type: Source ASE (0x2bc5)
* ATT: Read Response (0x0b) len 4
* Value: 0300
* Handle: 0x001c Type: Source ASE (0x2bc5)
* ATT: Write Request (0x12) len 4
* Handle: 0x001d Type: Client Characteristic Configuration (0x2902)
* Data: 0100
* Notification (0x01)
* ATT: Write Response (0x13) len 0
* ATT: Read Request (0x0a) len 2
* Handle: 0x001f Type: Source ASE (0x2bc5)
* ATT: Read Response (0x0b) len 4
* Value: 0400
* Handle: 0x001f Type: Source ASE (0x2bc5)
* ATT: Write Request (0x12) len 4
* Handle: 0x0020 Type: Client Characteristic Configuration (0x2902)
* Data: 0100
* Notification (0x01)
* ATT: Write Response (0x13) len 0
* ATT: Write Request (0x12) len 4
* Handle: 0x0023 Type: Client Characteristic Configuration (0x2902)
* Data: 0100
* Notification (0x01)
* ATT: Write Response (0x13) len 0
*/
#define DISC_SRC_ASE(_cfg...) \
DISC_SNK_ASE(_cfg), \
IOV_DATA(0x0a, 0x1c, 0x00), \
IOV_DATA(0x0b, 0x03, 0x00), \
IOV_DATA(0x12, 0x1d, 0x00, 0x01, 0x00), \
IOV_DATA(0x13), \
IOV_DATA(0x0a, 0x1f, 0x00), \
IOV_DATA(0x0b, 0x04, 0x00), \
IOV_DATA(0x12, 0x20, 0x00, 0x01, 0x00), \
IOV_DATA(0x13), \
IOV_DATA(0x12, 0x23, 0x00, 0x01, 0x00), \
IOV_DATA(0x13)
#define DISC_SRC_ASE_LC3 \
DISC_SRC_ASE(0x06, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x01, \
0xff, 0x00, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x05, 0x04, \
0x1e, 0x00, 0xf0, 0x00, 0x00)
static void test_disc(void)
{
/* The IUT discovers the characteristics specified in the PAC
* Characteristic and Location Characteristic columns in Table 4.4.
* The IUT reads the values of the characteristics specified in the PAC
* Characteristic and Location Characteristic columns.
*/
define_test("BAP/UCL/DISC/BV-01-C", test_setup, test_client, NULL,
DISC_SNK_LC3);
define_test("BAP/UCL/DISC/BV-02-C", test_setup, test_client, NULL,
DISC_SRC_LC3);
/* BAP/UCL/DISC/BV-06-C [Discover Available Audio Contexts]
*
* The IUT successfully reads the value of the Available Audio Contexts
* characteristic on the LowerTester.
*/
define_test("BAP/UCL/DISC/BV-06-C", test_setup, test_client, NULL,
DISC_CTX_LC3);
/* BAP/UCL/DISC/BV-05-C [Discover Supported Audio Contexts]
*
* The IUT successfully reads the value of the Supported Audio Contexts
* characteristic on the Lower Tester.
*/
define_test("BAP/UCL/DISC/BV-05-C", test_setup, test_client, NULL,
DISC_SUP_CTX_LC3);
/* BAP/UCL/DISC/BV-03-C [Discover Sink ASE_ID]
* BAP/UCL/DISC/BV-04-C [Discover Source ASE_ID]
*
* The IUT successfully reads the ASE_ID values of each discovered ASE
* characteristic on the LowerTester.
*/
define_test("BAP/UCL/DISC/BV-03-C", test_setup, test_client, NULL,
DISC_SNK_ASE_LC3);
define_test("BAP/UCL/DISC/BV-04-C", test_setup, test_client, NULL,
DISC_SRC_ASE_LC3);
}
/* ATT: Write Command (0x52) len 23
* Handle: 0x0022
* Data: 0101010202_cfg
* ATT: Handle Value Notification (0x1b) len 7
* Handle: 0x0022
* Data: 0101010000
* ATT: Handle Value Notification (0x1b) len 37
* Handle: 0x0016
* Data: 01010102010a00204e00409c00204e00409c00_cfg
*/
#define SCC_SNK(_cfg...) \
IOV_DATA(0x52, 0x22, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, _cfg), \
IOV_DATA(0x1b, 0x22, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00), \
IOV_NULL, \
IOV_DATA(0x1b, 0x16, 0x00, 0x01, 0x01, 0x01, 0x02, 0x01, 0x0a, 0x00, \
0x20, 0x4e, 0x00, 0x40, 0x9c, 0x00, 0x20, 0x4e, 0x00, \
0x40, 0x9c, 0x00, _cfg)
#define SCC_SNK_LC3(_cc...) \
DISC_SRC_ASE_LC3, \
SCC_SNK(0x06, 0x00, 0x00, 0x00, 0x00, _cc)
#define QOS_BALANCED_2M \
{ \
.target_latency = BT_BAP_CONFIG_LATENCY_BALANCED, \
.io_qos.phy = BT_BAP_CONFIG_PHY_2M, \
}
#define QOS_UCAST \
{\
.ucast = QOS_BALANCED_2M, \
}
static struct test_config cfg_snk_8_1 = {
.cc = LC3_CONFIG_8_1,
.qos = QOS_UCAST,
.snk = true,
};
#define SCC_SNK_8_1 \
SCC_SNK_LC3(0x0a, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x03, 0x04, \
0x1a, 0x00)
static struct test_config cfg_snk_8_2 = {
.cc = LC3_CONFIG_8_2,
.qos = QOS_UCAST,
.snk = true,
};
#define SCC_SNK_8_2 \
SCC_SNK_LC3(0x0a, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x03, 0x04, \
0x1e, 0x00)
static struct test_config cfg_snk_16_1 = {
.cc = LC3_CONFIG_16_1,
.qos = QOS_UCAST,
.snk = true,
};
#define SCC_SNK_16_1 \
SCC_SNK_LC3(0x0a, 0x02, 0x01, 0x03, 0x02, 0x02, 0x00, 0x03, 0x04, \
0x1e, 0x00)
static struct test_config cfg_snk_16_2 = {
.cc = LC3_CONFIG_16_2,
.qos = QOS_UCAST,
.snk = true,
};
#define SCC_SNK_16_2 \
SCC_SNK_LC3(0x0a, 0x02, 0x01, 0x03, 0x02, 0x02, 0x01, 0x03, 0x04, \
0x28, 0x00)
static struct test_config cfg_snk_24_1 = {
.cc = LC3_CONFIG_24_1,
.qos = QOS_UCAST,
.snk = true,
};
#define SCC_SNK_24_1 \
SCC_SNK_LC3(0x0a, 0x02, 0x01, 0x05, 0x02, 0x02, 0x00, 0x03, 0x04, \
0x2d, 0x00)
static struct test_config cfg_snk_24_2 = {
.cc = LC3_CONFIG_24_2,
.qos = QOS_UCAST,
.snk = true,
};
#define SCC_SNK_24_2 \
SCC_SNK_LC3(0x0a, 0x02, 0x01, 0x05, 0x02, 0x02, 0x01, 0x03, 0x04, \
0x3c, 0x00)
static struct test_config cfg_snk_32_1 = {
.cc = LC3_CONFIG_32_1,
.qos = QOS_UCAST,
.snk = true,
};
#define SCC_SNK_32_1 \
SCC_SNK_LC3(0x0a, 0x02, 0x01, 0x06, 0x02, 0x02, 0x00, 0x03, 0x04, \
0x3c, 0x00)
static struct test_config cfg_snk_32_2 = {
.cc = LC3_CONFIG_32_2,
.qos = QOS_UCAST,
.snk = true,
};
#define SCC_SNK_32_2 \
SCC_SNK_LC3(0x0a, 0x02, 0x01, 0x06, 0x02, 0x02, 0x01, 0x03, 0x04, \
0x50, 0x00)
static struct test_config cfg_snk_44_1 = {
.cc = LC3_CONFIG_44_1,
.qos = QOS_UCAST,
.snk = true,
};
#define SCC_SNK_44_1 \
SCC_SNK_LC3(0x0a, 0x02, 0x01, 0x07, 0x02, 0x02, 0x00, 0x03, 0x04, \
0x62, 0x00)
static struct test_config cfg_snk_44_2 = {
.cc = LC3_CONFIG_44_2,
.qos = QOS_UCAST,
.snk = true,
};
#define SCC_SNK_44_2 \
SCC_SNK_LC3(0x0a, 0x02, 0x01, 0x07, 0x02, 0x02, 0x01, 0x03, 0x04, \
0x82, 0x00)
static struct test_config cfg_snk_48_1 = {
.cc = LC3_CONFIG_48_1,
.qos = QOS_UCAST,
.snk = true,
};
#define SCC_SNK_48_1 \
SCC_SNK_LC3(0x0a, 0x02, 0x01, 0x08, 0x02, 0x02, 0x00, 0x03, 0x04, \
0x4b, 0x00)
static struct test_config cfg_snk_48_2 = {
.cc = LC3_CONFIG_48_2,
.qos = QOS_UCAST,
.snk = true,
};
#define SCC_SNK_48_2 \
SCC_SNK_LC3(0x0a, 0x02, 0x01, 0x08, 0x02, 0x02, 0x01, 0x03, 0x04, \
0x64, 0x00)
static struct test_config cfg_snk_48_3 = {
.cc = LC3_CONFIG_48_3,
.qos = QOS_UCAST,
.snk = true,
};
#define SCC_SNK_48_3 \
SCC_SNK_LC3(0x0a, 0x02, 0x01, 0x08, 0x02, 0x02, 0x00, 0x03, 0x04, \
0x5a, 0x00)
static struct test_config cfg_snk_48_4 = {
.cc = LC3_CONFIG_48_4,
.qos = QOS_UCAST,
.snk = true,
};
#define SCC_SNK_48_4 \
SCC_SNK_LC3(0x0a, 0x02, 0x01, 0x08, 0x02, 0x02, 0x01, 0x03, 0x04, \
0x78, 0x00)
static struct test_config cfg_snk_48_5 = {
.cc = LC3_CONFIG_48_5,
.qos = QOS_UCAST,
.snk = true,
};
#define SCC_SNK_48_5 \
SCC_SNK_LC3(0x0a, 0x02, 0x01, 0x08, 0x02, 0x02, 0x00, 0x03, 0x04, \
0x75, 0x00)
static struct test_config cfg_snk_48_6 = {
.cc = LC3_CONFIG_48_6,
.qos = QOS_UCAST,
.snk = true,
};
#define SCC_SNK_48_6 \
SCC_SNK_LC3(0x0a, 0x02, 0x01, 0x08, 0x02, 0x02, 0x01, 0x03, 0x04, \
0x9b, 0x00)
/* ATT: Write Command (0x52) len 23
* Handle: 0x0022
* Data: 0101030202_cfg
* ATT: Handle Value Notification (0x1b) len 7
* Handle: 0x0022
* Data: 0101030000
* ATT: Handle Value Notification (0x1b) len 37
* Handle: 0x001c
* Data: 03010102010a00204e00409c00204e00409c00_cfg
*/
#define SCC_SRC(_cfg...) \
IOV_DATA(0x52, 0x22, 0x00, 0x01, 0x01, 0x03, 0x02, 0x02, _cfg), \
IOV_DATA(0x1b, 0x22, 0x00, 0x01, 0x01, 0x03, 0x00, 0x00), \
IOV_NULL, \
IOV_DATA(0x1b, 0x1c, 0x00, 0x03, 0x01, 0x01, 0x02, 0x01, 0x0a, 0x00, \
0x20, 0x4e, 0x00, 0x40, 0x9c, 0x00, 0x20, 0x4e, 0x00, \
0x40, 0x9c, 0x00, _cfg)
#define SCC_SRC_LC3(_cc...) \
DISC_SRC_ASE_LC3, \
SCC_SRC(0x06, 0x00, 0x00, 0x00, 0x00, _cc)
static struct test_config cfg_src_8_1 = {
.cc = LC3_CONFIG_8_1,
.qos = QOS_UCAST,
.src = true,
};
#define SCC_SRC_8_1 \
SCC_SRC_LC3(0x0a, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x03, 0x04, \
0x1a, 0x00)
static struct test_config cfg_src_8_2 = {
.cc = LC3_CONFIG_8_2,
.qos = QOS_UCAST,
.src = true,
};
#define SCC_SRC_8_2 \
SCC_SRC_LC3(0x0a, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x03, 0x04, \
0x1e, 0x00)
static struct test_config cfg_src_16_1 = {
.cc = LC3_CONFIG_16_1,
.qos = QOS_UCAST,
.src = true,
};
#define SCC_SRC_16_1 \
SCC_SRC_LC3(0x0a, 0x02, 0x01, 0x03, 0x02, 0x02, 0x00, 0x03, 0x04, \
0x1e, 0x00)
static struct test_config cfg_src_16_2 = {
.cc = LC3_CONFIG_16_2,
.qos = QOS_UCAST,
.src = true,
};
#define SCC_SRC_16_2 \
SCC_SRC_LC3(0x0a, 0x02, 0x01, 0x03, 0x02, 0x02, 0x01, 0x03, 0x04, \
0x28, 0x00)
static struct test_config cfg_src_24_1 = {
.cc = LC3_CONFIG_24_1,
.qos = QOS_UCAST,
.src = true,
};
#define SCC_SRC_24_1 \
SCC_SRC_LC3(0x0a, 0x02, 0x01, 0x05, 0x02, 0x02, 0x00, 0x03, 0x04, \
0x2d, 0x00)
static struct test_config cfg_src_24_2 = {
.cc = LC3_CONFIG_24_2,
.qos = QOS_UCAST,
.src = true,
};
#define SCC_SRC_24_2 \
SCC_SRC_LC3(0x0a, 0x02, 0x01, 0x05, 0x02, 0x02, 0x01, 0x03, 0x04, \
0x3c, 0x00)
static struct test_config cfg_src_32_1 = {
.cc = LC3_CONFIG_32_1,
.qos = QOS_UCAST,
.src = true,
};
#define SCC_SRC_32_1 \
SCC_SRC_LC3(0x0a, 0x02, 0x01, 0x06, 0x02, 0x02, 0x00, 0x03, 0x04, \
0x3c, 0x00)
static struct test_config cfg_src_32_2 = {
.cc = LC3_CONFIG_32_2,
.qos = QOS_UCAST,
.src = true,
};
#define SCC_SRC_32_2 \
SCC_SRC_LC3(0x0a, 0x02, 0x01, 0x06, 0x02, 0x02, 0x01, 0x03, 0x04, \
0x50, 0x00)
static struct test_config cfg_src_44_1 = {
.cc = LC3_CONFIG_44_1,
.qos = QOS_UCAST,
.src = true,
};
#define SCC_SRC_44_1 \
SCC_SRC_LC3(0x0a, 0x02, 0x01, 0x07, 0x02, 0x02, 0x00, 0x03, 0x04, \
0x62, 0x00)
static struct test_config cfg_src_44_2 = {
.cc = LC3_CONFIG_44_2,
.qos = QOS_UCAST,
.src = true,
};
#define SCC_SRC_44_2 \
SCC_SRC_LC3(0x0a, 0x02, 0x01, 0x07, 0x02, 0x02, 0x01, 0x03, 0x04, \
0x82, 0x00)
static struct test_config cfg_src_48_1 = {
.cc = LC3_CONFIG_48_1,
.qos = QOS_UCAST,
.src = true,
};
#define SCC_SRC_48_1 \
SCC_SRC_LC3(0x0a, 0x02, 0x01, 0x08, 0x02, 0x02, 0x00, 0x03, 0x04, \
0x4b, 0x00)
static struct test_config cfg_src_48_2 = {
.cc = LC3_CONFIG_48_2,
.qos = QOS_UCAST,
.src = true,
};
#define SCC_SRC_48_2 \
SCC_SRC_LC3(0x0a, 0x02, 0x01, 0x08, 0x02, 0x02, 0x01, 0x03, 0x04, \
0x64, 0x00)
static struct test_config cfg_src_48_3 = {
.cc = LC3_CONFIG_48_3,
.qos = QOS_UCAST,
.src = true,
};
#define SCC_SRC_48_3 \
SCC_SRC_LC3(0x0a, 0x02, 0x01, 0x08, 0x02, 0x02, 0x00, 0x03, 0x04, \
0x5a, 0x00)
static struct test_config cfg_src_48_4 = {
.cc = LC3_CONFIG_48_4,
.qos = QOS_UCAST,
.src = true,
};
#define SCC_SRC_48_4 \
SCC_SRC_LC3(0x0a, 0x02, 0x01, 0x08, 0x02, 0x02, 0x01, 0x03, 0x04, \
0x78, 0x00)
static struct test_config cfg_src_48_5 = {
.cc = LC3_CONFIG_48_5,
.qos = QOS_UCAST,
.src = true,
};
#define SCC_SRC_48_5 \
SCC_SRC_LC3(0x0a, 0x02, 0x01, 0x08, 0x02, 0x02, 0x00, 0x03, 0x04, \
0x75, 0x00)
static struct test_config cfg_src_48_6 = {
.cc = LC3_CONFIG_48_6,
.qos = QOS_UCAST,
.src = true,
};
#define SCC_SRC_48_6 \
SCC_SRC_LC3(0x0a, 0x02, 0x01, 0x08, 0x02, 0x02, 0x01, 0x03, 0x04, \
0x9b, 0x00)
/* Test Purpose:
* Verify that a Unicast Client IUT can initiate a Config Codec
* operation for an LC3 codec.
*
* Pass verdict:
* The IUT successfully writes to the ASE Control point with the opcode
* set to 0x01 (Config Codec) and correctly formatted parameter values
* from Table 4.9. The Codec_ID field is a 5-octet field with octet 0
* set to the LC3 Coding_Format value defined in Bluetooth Assigned
* Numbers, octets 1–4 set to 0x0000. Each parameter (if present)
* included in the data sent in Codec_Specific_Configuration is
* formatted in an LTV structure with the length, type, and value
* specified in Table 4.10.
*/
static void test_scc_cc_lc3(void)
{
define_test("BAP/UCL/SCC/BV-001-C [UCL SRC Config Codec, LC3 8_1]",
test_setup, test_client, &cfg_snk_8_1, SCC_SNK_8_1);
define_test("BAP/UCL/SCC/BV-002-C [UCL SRC Config Codec, LC3 8_2]",
test_setup, test_client, &cfg_snk_8_2, SCC_SNK_8_2);
define_test("BAP/UCL/SCC/BV-003-C [UCL SRC Config Codec, LC3 16_1]",
test_setup, test_client, &cfg_snk_16_1, SCC_SNK_16_1);
define_test("BAP/UCL/SCC/BV-004-C [UCL SRC Config Codec, LC3 16_2]",
test_setup, test_client, &cfg_snk_16_2, SCC_SNK_16_2);
define_test("BAP/UCL/SCC/BV-005-C [UCL SRC Config Codec, LC3 24_1]",
test_setup, test_client, &cfg_snk_24_1, SCC_SNK_24_1);
define_test("BAP/UCL/SCC/BV-006-C [UCL SRC Config Codec, LC3 24_2]",
test_setup, test_client, &cfg_snk_24_2, SCC_SNK_24_2);
define_test("BAP/UCL/SCC/BV-007-C [UCL SRC Config Codec, LC3 32_1]",
test_setup, test_client, &cfg_snk_32_1, SCC_SNK_32_1);
define_test("BAP/UCL/SCC/BV-008-C [UCL SRC Config Codec, LC3 32_2]",
test_setup, test_client, &cfg_snk_32_2, SCC_SNK_32_2);
define_test("BAP/UCL/SCC/BV-009-C [UCL SRC Config Codec, LC3 44.1_1]",
test_setup, test_client, &cfg_snk_44_1, SCC_SNK_44_1);
define_test("BAP/UCL/SCC/BV-010-C [UCL SRC Config Codec, LC3 44.1_2]",
test_setup, test_client, &cfg_snk_44_2, SCC_SNK_44_2);
define_test("BAP/UCL/SCC/BV-011-C [UCL SRC Config Codec, LC3 48_1]",
test_setup, test_client, &cfg_snk_48_1, SCC_SNK_48_1);
define_test("BAP/UCL/SCC/BV-012-C [UCL SRC Config Codec, LC3 48_2]",
test_setup, test_client, &cfg_snk_48_2, SCC_SNK_48_2);
define_test("BAP/UCL/SCC/BV-013-C [UCL SRC Config Codec, LC3 48_3]",
test_setup, test_client, &cfg_snk_48_3, SCC_SNK_48_3);
define_test("BAP/UCL/SCC/BV-014-C [UCL SRC Config Codec, LC3 48_4]",
test_setup, test_client, &cfg_snk_48_4, SCC_SNK_48_4);
define_test("BAP/UCL/SCC/BV-015-C [UCL SRC Config Codec, LC3 48_5]",
test_setup, test_client, &cfg_snk_48_5, SCC_SNK_48_5);
define_test("BAP/UCL/SCC/BV-016-C [UCL SRC Config Codec, LC3 48_6]",
test_setup, test_client, &cfg_snk_48_6, SCC_SNK_48_6);
define_test("BAP/UCL/SCC/BV-017-C [UCL SNK Config Codec, LC3 8_1]",
test_setup, test_client, &cfg_src_8_1, SCC_SRC_8_1);
define_test("BAP/UCL/SCC/BV-018-C [UCL SNK Config Codec, LC3 8_2]",
test_setup, test_client, &cfg_src_8_2, SCC_SRC_8_2);
define_test("BAP/UCL/SCC/BV-019-C [UCL SNK Config Codec, LC3 16_1]",
test_setup, test_client, &cfg_src_16_1, SCC_SRC_16_1);
define_test("BAP/UCL/SCC/BV-020-C [UCL SNK Config Codec, LC3 16_2]",
test_setup, test_client, &cfg_src_16_2, SCC_SRC_16_2);
define_test("BAP/UCL/SCC/BV-021-C [UCL SNK Config Codec, LC3 24_1]",
test_setup, test_client, &cfg_src_24_1, SCC_SRC_24_1);
define_test("BAP/UCL/SCC/BV-022-C [UCL SNK Config Codec, LC3 24_2]",
test_setup, test_client, &cfg_src_24_2, SCC_SRC_24_2);
define_test("BAP/UCL/SCC/BV-023-C [UCL SNK Config Codec, LC3 32_1]",
test_setup, test_client, &cfg_src_32_1, SCC_SRC_32_1);
define_test("BAP/UCL/SCC/BV-024-C [UCL SNK Config Codec, LC3 32_2]",
test_setup, test_client, &cfg_src_32_2, SCC_SRC_32_2);
define_test("BAP/UCL/SCC/BV-025-C [UCL SNK Config Codec, LC3 44.1_1]",
test_setup, test_client, &cfg_src_44_1, SCC_SRC_44_1);
define_test("BAP/UCL/SCC/BV-026-C [UCL SNK Config Codec, LC3 44.1_2]",
test_setup, test_client, &cfg_src_44_2, SCC_SRC_44_2);
define_test("BAP/UCL/SCC/BV-027-C [UCL SNK Config Codec, LC3 48_1]",
test_setup, test_client, &cfg_src_48_1, SCC_SRC_48_1);
define_test("BAP/UCL/SCC/BV-028-C [UCL SNK Config Codec, LC3 48_2]",
test_setup, test_client, &cfg_src_48_2, SCC_SRC_48_2);
define_test("BAP/UCL/SCC/BV-029-C [UCL SNK Config Codec, LC3 48_3]",
test_setup, test_client, &cfg_src_48_3, SCC_SRC_48_3);
define_test("BAP/UCL/SCC/BV-030-C [UCL SNK Config Codec, LC3 48_4]",
test_setup, test_client, &cfg_src_48_4, SCC_SRC_48_4);
define_test("BAP/UCL/SCC/BV-031-C [UCL SNK Config Codec, LC3 48_5]",
test_setup, test_client, &cfg_src_48_5, SCC_SRC_48_5);
define_test("BAP/UCL/SCC/BV-032-C [UCL SNK Config Codec, LC3 48_6]",
test_setup, test_client, &cfg_src_48_6, SCC_SRC_48_6);
}
static struct test_config cfg_snk_vs = {
.cc = IOV_NULL,
.qos = QOS_UCAST,
.snk = true,
.vs = true,
};
#define DISC_SRC_ASE_VS \
DISC_SRC_ASE(0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00)
#define SCC_SNK_VS \
DISC_SRC_ASE_VS, \
SCC_SNK(0xff, 0x01, 0x00, 0x01, 0x00, 0x00)
static struct test_config cfg_src_vs = {
.cc = IOV_NULL,
.qos = QOS_UCAST,
.src = true,
.vs = true,
};
#define SCC_SRC_VS \
DISC_SRC_ASE_VS, \
SCC_SRC(0xff, 0x01, 0x00, 0x01, 0x00, 0x00)
/* Test Purpose:
* Verify that a Unicast Client IUT can initiate a Config Codec operation for a
* vendor-specific codec.
*
* Pass verdict:
* The IUT successfully writes to the ASE Control Point characteristic with the
* opcode set to 0x01 (Config Codec) and the specified parameters. The Codec_ID
* parameter is formatted with octet 0 set to 0xFF, octets 1–2 set to
* TSPX_VS_Company_ID, and octets 3–4 set to TSPX_VS_Codec_ID.
*/
static void test_scc_cc_vs(void)
{
define_test("BAP/UCL/SCC/BV-033-C [UCL SRC Config Codec, VS]",
test_setup, test_client, &cfg_snk_vs, SCC_SNK_VS);
define_test("BAP/UCL/SCC/BV-034-C [UCL SNK Config Codec, VS]",
test_setup, test_client, &cfg_src_vs, SCC_SRC_VS);
}
static struct test_config cfg_snk_8_1_1 = {
.cc = LC3_CONFIG_8_1,
.qos = LC3_QOS_8_1_1,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_8_2_1 = {
.cc = LC3_CONFIG_8_2,
.qos = LC3_QOS_8_2_1,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_16_1_1 = {
.cc = LC3_CONFIG_16_1,
.qos = LC3_QOS_16_1_1,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_16_2_1 = {
.cc = LC3_CONFIG_16_2,
.qos = LC3_QOS_16_2_1,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_24_1_1 = {
.cc = LC3_CONFIG_24_1,
.qos = LC3_QOS_24_1_1,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_24_2_1 = {
.cc = LC3_CONFIG_24_2,
.qos = LC3_QOS_24_2_1,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_32_1_1 = {
.cc = LC3_CONFIG_32_1,
.qos = LC3_QOS_32_1_1,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_32_2_1 = {
.cc = LC3_CONFIG_32_2,
.qos = LC3_QOS_32_2_1,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_44_1_1 = {
.cc = LC3_CONFIG_44_1,
.qos = LC3_QOS_44_1_1,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_44_2_1 = {
.cc = LC3_CONFIG_44_2,
.qos = LC3_QOS_44_2_1,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_48_1_1 = {
.cc = LC3_CONFIG_48_1,
.qos = LC3_QOS_48_1_1,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_48_2_1 = {
.cc = LC3_CONFIG_48_2,
.qos = LC3_QOS_48_2_1,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_48_3_1 = {
.cc = LC3_CONFIG_48_3,
.qos = LC3_QOS_48_3_1,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_48_4_1 = {
.cc = LC3_CONFIG_48_4,
.qos = LC3_QOS_48_4_1,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_48_5_1 = {
.cc = LC3_CONFIG_48_5,
.qos = LC3_QOS_48_5_1,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_48_6_1 = {
.cc = LC3_CONFIG_48_6,
.qos = LC3_QOS_48_6_1,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
/* ATT: Write Command (0x52) len 23
* Handle: 0x0022
* Data: 02010000_qos
* ATT: Handle Value Notification (0x1b) len 7
* Handle: 0x0022
* Data: 0201010000
* ATT: Handle Value Notification (0x1b) len 37
* Handle: 0x0016
* Data: 01010102010a00204e00409c00204e00409c00_qos
*/
#define QOS_SNK(_qos...) \
IOV_DATA(0x52, 0x22, 0x00, 0x02, 0x01, 0x01, 0x00, 0x00, _qos), \
IOV_DATA(0x1b, 0x22, 0x00, 0x02, 0x01, 0x01, 0x00, 0x00), \
IOV_NULL, \
IOV_DATA(0x1b, 0x16, 0x00, 0x01, 0x02, 0x00, 0x00, _qos)
#define SCC_SNK_8_1_1 \
SCC_SNK_8_1, \
QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x1a, 0x00, 0x02, 0x08, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_8_2_1 \
SCC_SNK_8_2, \
QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x1e, 0x00, 0x02, 0x0a, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_16_1_1 \
SCC_SNK_16_1, \
QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x1e, 0x00, 0x02, 0x08, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_16_2_1 \
SCC_SNK_16_2, \
QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x28, 0x00, 0x02, 0x0a, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_24_1_1 \
SCC_SNK_24_1, \
QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x2d, 0x00, 0x02, 0x08, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_24_2_1 \
SCC_SNK_24_2, \
QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x3c, 0x00, 0x02, 0x0a, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_32_1_1 \
SCC_SNK_32_1, \
QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x3c, 0x00, 0x02, 0x08, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_32_2_1 \
SCC_SNK_32_2, \
QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x50, 0x00, 0x02, 0x0a, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_44_1_1 \
SCC_SNK_44_1, \
QOS_SNK(0xe3, 0x1f, 0x00, 0x01, 0x02, 0x62, 0x00, 0x05, 0x18, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_44_2_1 \
SCC_SNK_44_2, \
QOS_SNK(0x84, 0x2a, 0x00, 0x01, 0x02, 0x82, 0x00, 0x05, 0x1f, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_48_1_1 \
SCC_SNK_48_1, \
QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x4b, 0x00, 0x05, 0x0f, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_48_2_1 \
SCC_SNK_48_2, \
QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x64, 0x00, 0x05, 0x14, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_48_3_1 \
SCC_SNK_48_3, \
QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x5a, 0x00, 0x05, 0x0f, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_48_4_1 \
SCC_SNK_48_4, \
QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x78, 0x00, 0x05, 0x14, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_48_5_1 \
SCC_SNK_48_5, \
QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x75, 0x00, 0x05, 0x0f, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_48_6_1 \
SCC_SNK_48_6, \
QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x9b, 0x00, 0x05, 0x14, 0x00, \
0x40, 0x9c, 0x00)
static struct test_config cfg_src_8_1_1 = {
.cc = LC3_CONFIG_8_1,
.qos = LC3_QOS_8_1_1,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_8_2_1 = {
.cc = LC3_CONFIG_8_2,
.qos = LC3_QOS_8_2_1,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_16_1_1 = {
.cc = LC3_CONFIG_16_1,
.qos = LC3_QOS_16_1_1,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_16_2_1 = {
.cc = LC3_CONFIG_16_2,
.qos = LC3_QOS_16_2_1,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_24_1_1 = {
.cc = LC3_CONFIG_24_1,
.qos = LC3_QOS_24_1_1,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_24_2_1 = {
.cc = LC3_CONFIG_24_2,
.qos = LC3_QOS_24_2_1,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_32_1_1 = {
.cc = LC3_CONFIG_32_1,
.qos = LC3_QOS_32_1_1,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_32_2_1 = {
.cc = LC3_CONFIG_32_2,
.qos = LC3_QOS_32_2_1,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_44_1_1 = {
.cc = LC3_CONFIG_44_1,
.qos = LC3_QOS_44_1_1,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_44_2_1 = {
.cc = LC3_CONFIG_44_2,
.qos = LC3_QOS_44_2_1,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_48_1_1 = {
.cc = LC3_CONFIG_48_1,
.qos = LC3_QOS_48_1_1,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_48_2_1 = {
.cc = LC3_CONFIG_48_2,
.qos = LC3_QOS_48_2_1,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_48_3_1 = {
.cc = LC3_CONFIG_48_3,
.qos = LC3_QOS_48_3_1,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_48_4_1 = {
.cc = LC3_CONFIG_48_4,
.qos = LC3_QOS_48_4_1,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_48_5_1 = {
.cc = LC3_CONFIG_48_5,
.qos = LC3_QOS_48_5_1,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_48_6_1 = {
.cc = LC3_CONFIG_48_6,
.qos = LC3_QOS_48_6_1,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
/* ATT: Write Command (0x52) len 23
* Handle: 0x0022
* Data: 02030000_qos
* ATT: Handle Value Notification (0x1b) len 7
* Handle: 0x0022
* Data: 0201030000
* ATT: Handle Value Notification (0x1b) len 37
* Handle: 0x001c
* Data: 03010102010a00204e00409c00204e00409c00_qos
*/
#define QOS_SRC(_qos...) \
IOV_DATA(0x52, 0x22, 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, _qos), \
IOV_DATA(0x1b, 0x22, 0x00, 0x02, 0x01, 0x01, 0x00, 0x00), \
IOV_NULL, \
IOV_DATA(0x1b, 0x1c, 0x00, 0x03, 0x02, 0x00, 0x00, _qos)
#define SCC_SRC_8_1_1 \
SCC_SRC_8_1, \
QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x1a, 0x00, 0x02, 0x08, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_8_2_1 \
SCC_SRC_8_2, \
QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x1e, 0x00, 0x02, 0x0a, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_16_1_1 \
SCC_SRC_16_1, \
QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x1e, 0x00, 0x02, 0x08, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_16_2_1 \
SCC_SRC_16_2, \
QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x28, 0x00, 0x02, 0x0a, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_24_1_1 \
SCC_SRC_24_1, \
QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x2d, 0x00, 0x02, 0x08, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_24_2_1 \
SCC_SRC_24_2, \
QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x3c, 0x00, 0x02, 0x0a, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_32_1_1 \
SCC_SRC_32_1, \
QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x3c, 0x00, 0x02, 0x08, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_32_2_1 \
SCC_SRC_32_2, \
QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x50, 0x00, 0x02, 0x0a, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_44_1_1 \
SCC_SRC_44_1, \
QOS_SRC(0xe3, 0x1f, 0x00, 0x01, 0x02, 0x62, 0x00, 0x05, 0x18, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_44_2_1 \
SCC_SRC_44_2, \
QOS_SRC(0x84, 0x2a, 0x00, 0x01, 0x02, 0x82, 0x00, 0x05, 0x1f, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_48_1_1 \
SCC_SRC_48_1, \
QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x4b, 0x00, 0x05, 0x0f, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_48_2_1 \
SCC_SRC_48_2, \
QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x64, 0x00, 0x05, 0x14, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_48_3_1 \
SCC_SRC_48_3, \
QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x5a, 0x00, 0x05, 0x0f, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_48_4_1 \
SCC_SRC_48_4, \
QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x78, 0x00, 0x05, 0x14, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_48_5_1 \
SCC_SRC_48_5, \
QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x75, 0x00, 0x05, 0x0f, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_48_6_1 \
SCC_SRC_48_6, \
QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x9b, 0x00, 0x05, 0x14, 0x00, \
0x40, 0x9c, 0x00)
static struct test_config cfg_snk_8_1_2 = {
.cc = LC3_CONFIG_8_1,
.qos = LC3_QOS_8_1_2,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_8_2_2 = {
.cc = LC3_CONFIG_8_2,
.qos = LC3_QOS_8_2_2,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_16_1_2 = {
.cc = LC3_CONFIG_16_1,
.qos = LC3_QOS_16_1_2,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_16_2_2 = {
.cc = LC3_CONFIG_16_2,
.qos = LC3_QOS_16_2_2,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_24_1_2 = {
.cc = LC3_CONFIG_24_1,
.qos = LC3_QOS_24_1_2,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_24_2_2 = {
.cc = LC3_CONFIG_24_2,
.qos = LC3_QOS_24_2_2,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_32_1_2 = {
.cc = LC3_CONFIG_32_1,
.qos = LC3_QOS_32_1_2,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_32_2_2 = {
.cc = LC3_CONFIG_32_2,
.qos = LC3_QOS_32_2_2,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_44_1_2 = {
.cc = LC3_CONFIG_44_1,
.qos = LC3_QOS_44_1_2,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_44_2_2 = {
.cc = LC3_CONFIG_44_2,
.qos = LC3_QOS_44_2_2,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_48_1_2 = {
.cc = LC3_CONFIG_48_1,
.qos = LC3_QOS_48_1_2,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_48_2_2 = {
.cc = LC3_CONFIG_48_2,
.qos = LC3_QOS_48_2_2,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_48_3_2 = {
.cc = LC3_CONFIG_48_3,
.qos = LC3_QOS_48_3_2,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_48_4_2 = {
.cc = LC3_CONFIG_48_4,
.qos = LC3_QOS_48_4_2,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_48_5_2 = {
.cc = LC3_CONFIG_48_5,
.qos = LC3_QOS_48_5_2,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_snk_48_6_2 = {
.cc = LC3_CONFIG_48_6,
.qos = LC3_QOS_48_6_2,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
#define SCC_SNK_8_1_2 \
SCC_SNK_8_1, \
QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x1a, 0x00, 0x0d, 0x4b, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_8_2_2 \
SCC_SNK_8_2, \
QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x1e, 0x00, 0x0d, 0x5f, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_16_1_2 \
SCC_SNK_16_1, \
QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x1e, 0x00, 0x0d, 0x4b, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_16_2_2 \
SCC_SNK_16_2, \
QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x28, 0x00, 0x0d, 0x5f, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_24_1_2 \
SCC_SNK_24_1, \
QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x2d, 0x00, 0x0d, 0x4b, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_24_2_2 \
SCC_SNK_24_2, \
QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x3c, 0x00, 0x0d, 0x5f, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_32_1_2 \
SCC_SNK_32_1, \
QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x3c, 0x00, 0x0d, 0x4b, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_32_2_2 \
SCC_SNK_32_2, \
QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x50, 0x00, 0x0d, 0x5f, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_44_1_2 \
SCC_SNK_44_1, \
QOS_SNK(0xe3, 0x1f, 0x00, 0x01, 0x02, 0x62, 0x00, 0x0d, 0x50, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_44_2_2 \
SCC_SNK_44_2, \
QOS_SNK(0x84, 0x2a, 0x00, 0x01, 0x02, 0x82, 0x00, 0x0d, 0x55, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_48_1_2 \
SCC_SNK_48_1, \
QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x4b, 0x00, 0x0d, 0x4b, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_48_2_2 \
SCC_SNK_48_2, \
QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x64, 0x00, 0x0d, 0x5f, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_48_3_2 \
SCC_SNK_48_3, \
QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x5a, 0x00, 0x0d, 0x4b, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_48_4_2 \
SCC_SNK_48_4, \
QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x78, 0x00, 0x0d, 0x64, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_48_5_2 \
SCC_SNK_48_5, \
QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x75, 0x00, 0x0d, 0x4b, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SNK_48_6_2 \
SCC_SNK_48_6, \
QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x9b, 0x00, 0x0d, 0x64, 0x00, \
0x40, 0x9c, 0x00)
static struct test_config cfg_src_8_1_2 = {
.cc = LC3_CONFIG_8_1,
.qos = LC3_QOS_8_1_2,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_8_2_2 = {
.cc = LC3_CONFIG_8_2,
.qos = LC3_QOS_8_2_2,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_16_1_2 = {
.cc = LC3_CONFIG_16_1,
.qos = LC3_QOS_16_1_2,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_16_2_2 = {
.cc = LC3_CONFIG_16_2,
.qos = LC3_QOS_16_2_2,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_24_1_2 = {
.cc = LC3_CONFIG_24_1,
.qos = LC3_QOS_24_1_2,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_24_2_2 = {
.cc = LC3_CONFIG_24_2,
.qos = LC3_QOS_24_2_2,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_32_1_2 = {
.cc = LC3_CONFIG_32_1,
.qos = LC3_QOS_32_1_2,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_32_2_2 = {
.cc = LC3_CONFIG_32_2,
.qos = LC3_QOS_32_2_2,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_44_1_2 = {
.cc = LC3_CONFIG_44_1,
.qos = LC3_QOS_44_1_2,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_44_2_2 = {
.cc = LC3_CONFIG_44_2,
.qos = LC3_QOS_44_2_2,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_48_1_2 = {
.cc = LC3_CONFIG_48_1,
.qos = LC3_QOS_48_1_2,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_48_2_2 = {
.cc = LC3_CONFIG_48_2,
.qos = LC3_QOS_48_2_2,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_48_3_2 = {
.cc = LC3_CONFIG_48_3,
.qos = LC3_QOS_48_3_2,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_48_4_2 = {
.cc = LC3_CONFIG_48_4,
.qos = LC3_QOS_48_4_2,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_48_5_2 = {
.cc = LC3_CONFIG_48_5,
.qos = LC3_QOS_48_5_2,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
static struct test_config cfg_src_48_6_2 = {
.cc = LC3_CONFIG_48_6,
.qos = LC3_QOS_48_6_2,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
};
#define SCC_SRC_8_1_2 \
SCC_SRC_8_1, \
QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x1a, 0x00, 0x0d, 0x4b, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_8_2_2 \
SCC_SRC_8_2, \
QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x1e, 0x00, 0x0d, 0x5f, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_16_1_2 \
SCC_SRC_16_1, \
QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x1e, 0x00, 0x0d, 0x4b, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_16_2_2 \
SCC_SRC_16_2, \
QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x28, 0x00, 0x0d, 0x5f, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_24_1_2 \
SCC_SRC_24_1, \
QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x2d, 0x00, 0x0d, 0x4b, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_24_2_2 \
SCC_SRC_24_2, \
QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x3c, 0x00, 0x0d, 0x5f, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_32_1_2 \
SCC_SRC_32_1, \
QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x3c, 0x00, 0x0d, 0x4b, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_32_2_2 \
SCC_SRC_32_2, \
QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x50, 0x00, 0x0d, 0x5f, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_44_1_2 \
SCC_SRC_44_1, \
QOS_SRC(0xe3, 0x1f, 0x00, 0x01, 0x02, 0x62, 0x00, 0x0d, 0x50, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_44_2_2 \
SCC_SRC_44_2, \
QOS_SRC(0x84, 0x2a, 0x00, 0x01, 0x02, 0x82, 0x00, 0x0d, 0x55, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_48_1_2 \
SCC_SRC_48_1, \
QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x4b, 0x00, 0x0d, 0x4b, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_48_2_2 \
SCC_SRC_48_2, \
QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x64, 0x00, 0x0d, 0x5f, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_48_3_2 \
SCC_SRC_48_3, \
QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x5a, 0x00, 0x0d, 0x4b, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_48_4_2 \
SCC_SRC_48_4, \
QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x78, 0x00, 0x0d, 0x64, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_48_5_2 \
SCC_SRC_48_5, \
QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x75, 0x00, 0x0d, 0x4b, 0x00, \
0x40, 0x9c, 0x00)
#define SCC_SRC_48_6_2 \
SCC_SRC_48_6, \
QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x9b, 0x00, 0x0d, 0x64, 0x00, \
0x40, 0x9c, 0x00)
/* Test Purpose:
* Verify that a Unicast Client IUT can initiate a Config QoS operation for the
* LC3 codec.
*
* Pass verdict:
* The IUT successfully writes to the ASE Control Point characteristic with the
* opcode set to 0x02 (Config QoS) and the specified parameters.
*/
static void test_scc_qos_lc3(void)
{
define_test("BAP/UCL/SCC/BV-035-C [UCL SRC Config QoS, LC3 8_1_1]",
test_setup, test_client, &cfg_snk_8_1_1,
SCC_SNK_8_1_1);
define_test("BAP/UCL/SCC/BV-036-C [UCL SRC Config QoS, LC3 8_2_1]",
test_setup, test_client, &cfg_snk_8_2_1,
SCC_SNK_8_2_1);
define_test("BAP/UCL/SCC/BV-037-C [UCL SRC Config QoS, LC3 16_1_1]",
test_setup, test_client, &cfg_snk_16_1_1,
SCC_SNK_16_1_1);
define_test("BAP/UCL/SCC/BV-038-C [UCL SRC Config QoS, LC3 16_2_1]",
test_setup, test_client, &cfg_snk_16_2_1,
SCC_SNK_16_2_1);
define_test("BAP/UCL/SCC/BV-039-C [UCL SRC Config QoS, LC3 24_1_1]",
test_setup, test_client, &cfg_snk_24_1_1,
SCC_SNK_24_1_1);
define_test("BAP/UCL/SCC/BV-040-C [UCL SRC Config QoS, LC3 24_2_1]",
test_setup, test_client, &cfg_snk_24_2_1,
SCC_SNK_24_2_1);
define_test("BAP/UCL/SCC/BV-041-C [UCL SRC Config QoS, LC3 32_1_1]",
test_setup, test_client, &cfg_snk_32_1_1,
SCC_SNK_32_1_1);
define_test("BAP/UCL/SCC/BV-042-C [UCL SRC Config QoS, LC3 32_2_1]",
test_setup, test_client, &cfg_snk_32_2_1,
SCC_SNK_32_2_1);
define_test("BAP/UCL/SCC/BV-043-C [UCL SRC Config QoS, LC3 44.1_1_1]",
test_setup, test_client, &cfg_snk_44_1_1,
SCC_SNK_44_1_1);
define_test("BAP/UCL/SCC/BV-044-C [UCL SRC Config QoS, LC3 44.1_2_1]",
test_setup, test_client, &cfg_snk_44_2_1,
SCC_SNK_44_2_1);
define_test("BAP/UCL/SCC/BV-045-C [UCL SRC Config QoS, LC3 48_1_1]",
test_setup, test_client, &cfg_snk_48_1_1,
SCC_SNK_48_1_1);
define_test("BAP/UCL/SCC/BV-046-C [UCL SRC Config QoS, LC3 48_2_1]",
test_setup, test_client, &cfg_snk_48_2_1,
SCC_SNK_48_2_1);
define_test("BAP/UCL/SCC/BV-047-C [UCL SRC Config QoS, LC3 48_3_1]",
test_setup, test_client, &cfg_snk_48_3_1,
SCC_SNK_48_3_1);
define_test("BAP/UCL/SCC/BV-048-C [UCL SRC Config QoS, LC3 48_4_1]",
test_setup, test_client, &cfg_snk_48_4_1,
SCC_SNK_48_4_1);
define_test("BAP/UCL/SCC/BV-049-C [UCL SRC Config QoS, LC3 48_5_1]",
test_setup, test_client, &cfg_snk_48_5_1,
SCC_SNK_48_5_1);
define_test("BAP/UCL/SCC/BV-050-C [UCL SRC Config QoS, LC3 48_6_1]",
test_setup, test_client, &cfg_snk_48_6_1,
SCC_SNK_48_6_1);
define_test("BAP/UCL/SCC/BV-051-C [UCL SNK Config QoS, LC3 8_1_1]",
test_setup, test_client, &cfg_src_8_1_1,
SCC_SRC_8_1_1);
define_test("BAP/UCL/SCC/BV-052-C [UCL SNK Config QoS, LC3 8_2_1]",
test_setup, test_client, &cfg_src_8_2_1,
SCC_SRC_8_2_1);
define_test("BAP/UCL/SCC/BV-053-C [UCL SNK Config QoS, LC3 16_1_1]",
test_setup, test_client, &cfg_src_16_1_1,
SCC_SRC_16_1_1);
define_test("BAP/UCL/SCC/BV-054-C [UCL SNK Config QoS, LC3 16_2_1]",
test_setup, test_client, &cfg_src_16_2_1,
SCC_SRC_16_2_1);
define_test("BAP/UCL/SCC/BV-055-C [UCL SNK Config QoS, LC3 24_1_1]",
test_setup, test_client, &cfg_src_24_1_1,
SCC_SRC_24_1_1);
define_test("BAP/UCL/SCC/BV-056-C [UCL SNK Config QoS, LC3 24_2_1]",
test_setup, test_client, &cfg_src_24_2_1,
SCC_SRC_24_2_1);
define_test("BAP/UCL/SCC/BV-057-C [UCL SNK Config QoS, LC3 32_1_1]",
test_setup, test_client, &cfg_src_32_1_1,
SCC_SRC_32_1_1);
define_test("BAP/UCL/SCC/BV-058-C [UCL SNK Config QoS, LC3 32_2_1]",
test_setup, test_client, &cfg_src_32_2_1,
SCC_SRC_32_2_1);
define_test("BAP/UCL/SCC/BV-059-C [UCL SNK Config QoS, LC3 44.1_1_1]",
test_setup, test_client, &cfg_src_44_1_1,
SCC_SRC_44_1_1);
define_test("BAP/UCL/SCC/BV-060-C [UCL SNK Config QoS, LC3 44.1_2_1]",
test_setup, test_client, &cfg_src_44_2_1,
SCC_SRC_44_2_1);
define_test("BAP/UCL/SCC/BV-061-C [UCL SNK Config QoS, LC3 48_1_1]",
test_setup, test_client, &cfg_src_48_1_1,
SCC_SRC_48_1_1);
define_test("BAP/UCL/SCC/BV-062-C [UCL SNK Config QoS, LC3 48_2_1]",
test_setup, test_client, &cfg_src_48_2_1,
SCC_SRC_48_2_1);
define_test("BAP/UCL/SCC/BV-063-C [UCL SNK Config QoS, LC3 48_3_1]",
test_setup, test_client, &cfg_src_48_3_1,
SCC_SRC_48_3_1);
define_test("BAP/UCL/SCC/BV-064-C [UCL SNK Config QoS, LC3 48_4_1]",
test_setup, test_client, &cfg_src_48_4_1,
SCC_SRC_48_4_1);
define_test("BAP/UCL/SCC/BV-065-C [UCL SNK Config QoS, LC3 48_5_1]",
test_setup, test_client, &cfg_src_48_5_1,
SCC_SRC_48_5_1);
define_test("BAP/UCL/SCC/BV-066-C [UCL SNK Config QoS, LC3 48_6_1]",
test_setup, test_client, &cfg_src_48_6_1,
SCC_SRC_48_6_1);
define_test("BAP/UCL/SCC/BV-067-C [UCL SRC Config QoS, LC3 8_1_2]",
test_setup, test_client, &cfg_snk_8_1_2,
SCC_SNK_8_1_2);
define_test("BAP/UCL/SCC/BV-068-C [UCL SRC Config QoS, LC3 8_2_2]",
test_setup, test_client, &cfg_snk_8_2_2,
SCC_SNK_8_2_2);
define_test("BAP/UCL/SCC/BV-069-C [UCL SRC Config QoS, LC3 16_1_2]",
test_setup, test_client, &cfg_snk_16_1_2,
SCC_SNK_16_1_2);
define_test("BAP/UCL/SCC/BV-070-C [UCL SRC Config QoS, LC3 16_2_2]",
test_setup, test_client, &cfg_snk_16_2_2,
SCC_SNK_16_2_2);
define_test("BAP/UCL/SCC/BV-071-C [UCL SRC Config QoS, LC3 24_1_2]",
test_setup, test_client, &cfg_snk_24_1_2,
SCC_SNK_24_1_2);
define_test("BAP/UCL/SCC/BV-072-C [UCL SRC Config QoS, LC3 24_2_2]",
test_setup, test_client, &cfg_snk_24_2_2,
SCC_SNK_24_2_2);
define_test("BAP/UCL/SCC/BV-073-C [UCL SRC Config QoS, LC3 32_1_2]",
test_setup, test_client, &cfg_snk_32_1_2,
SCC_SNK_32_1_2);
define_test("BAP/UCL/SCC/BV-074-C [UCL SRC Config QoS, LC3 32_2_2]",
test_setup, test_client, &cfg_snk_32_2_2,
SCC_SNK_32_2_2);
define_test("BAP/UCL/SCC/BV-075-C [UCL SRC Config QoS, LC3 44.1_1_2]",
test_setup, test_client, &cfg_snk_44_1_2,
SCC_SNK_44_1_2);
define_test("BAP/UCL/SCC/BV-076-C [UCL SRC Config QoS, LC3 44.1_2_2]",
test_setup, test_client, &cfg_snk_44_2_2,
SCC_SNK_44_2_2);
define_test("BAP/UCL/SCC/BV-077-C [UCL SRC Config QoS, LC3 48_1_2]",
test_setup, test_client, &cfg_snk_48_1_2,
SCC_SNK_48_1_2);
define_test("BAP/UCL/SCC/BV-078-C [UCL SRC Config QoS, LC3 48_2_2]",
test_setup, test_client, &cfg_snk_48_2_2,
SCC_SNK_48_2_2);
define_test("BAP/UCL/SCC/BV-079-C [UCL SRC Config QoS, LC3 48_3_2]",
test_setup, test_client, &cfg_snk_48_3_2,
SCC_SNK_48_3_2);
define_test("BAP/UCL/SCC/BV-080-C [UCL SRC Config QoS, LC3 48_4_2]",
test_setup, test_client, &cfg_snk_48_4_2,
SCC_SNK_48_4_2);
define_test("BAP/UCL/SCC/BV-081-C [UCL SRC Config QoS, LC3 48_5_2]",
test_setup, test_client, &cfg_snk_48_5_2,
SCC_SNK_48_5_2);
define_test("BAP/UCL/SCC/BV-082-C [UCL SRC Config QoS, LC3 48_6_2]",
test_setup, test_client, &cfg_snk_48_6_2,
SCC_SNK_48_6_2);
define_test("BAP/UCL/SCC/BV-083-C [UCL SNK Config QoS, LC3 8_1_2]",
test_setup, test_client, &cfg_src_8_1_2,
SCC_SRC_8_1_2);
define_test("BAP/UCL/SCC/BV-084-C [UCL SNK Config QoS, LC3 8_2_2]",
test_setup, test_client, &cfg_src_8_2_2,
SCC_SRC_8_2_2);
define_test("BAP/UCL/SCC/BV-085-C [UCL SNK Config QoS, LC3 16_1_2]",
test_setup, test_client, &cfg_src_16_1_2,
SCC_SRC_16_1_2);
define_test("BAP/UCL/SCC/BV-086-C [UCL SNK Config QoS, LC3 16_2_2]",
test_setup, test_client, &cfg_src_16_2_2,
SCC_SRC_16_2_2);
define_test("BAP/UCL/SCC/BV-087-C [UCL SNK Config QoS, LC3 24_1_2]",
test_setup, test_client, &cfg_src_24_1_2,
SCC_SRC_24_1_2);
define_test("BAP/UCL/SCC/BV-088-C [UCL SNK Config QoS, LC3 24_2_2]",
test_setup, test_client, &cfg_src_24_2_2,
SCC_SRC_24_2_2);
define_test("BAP/UCL/SCC/BV-089-C [UCL SNK Config QoS, LC3 32_1_2]",
test_setup, test_client, &cfg_src_32_1_2,
SCC_SRC_32_1_2);
define_test("BAP/UCL/SCC/BV-090-C [UCL SNK Config QoS, LC3 32_2_2]",
test_setup, test_client, &cfg_src_32_2_2,
SCC_SRC_32_2_2);
define_test("BAP/UCL/SCC/BV-091-C [UCL SNK Config QoS, LC3 44.1_1_2]",
test_setup, test_client, &cfg_src_44_1_2,
SCC_SRC_44_1_2);
define_test("BAP/UCL/SCC/BV-092-C [UCL SNK Config QoS, LC3 44.1_2_2]",
test_setup, test_client, &cfg_src_44_2_2,
SCC_SRC_44_2_2);
define_test("BAP/UCL/SCC/BV-093-C [UCL SNK Config QoS, LC3 48_1_2]",
test_setup, test_client, &cfg_src_48_1_2,
SCC_SRC_48_1_2);
define_test("BAP/UCL/SCC/BV-094-C [UCL SNK Config QoS, LC3 48_2_2]",
test_setup, test_client, &cfg_src_48_2_2,
SCC_SRC_48_2_2);
define_test("BAP/UCL/SCC/BV-095-C [UCL SNK Config QoS, LC3 48_3_2]",
test_setup, test_client, &cfg_src_48_3_2,
SCC_SRC_48_3_2);
define_test("BAP/UCL/SCC/BV-096-C [UCL SNK Config QoS, LC3 48_4_2]",
test_setup, test_client, &cfg_src_48_4_2,
SCC_SRC_48_4_2);
define_test("BAP/UCL/SCC/BV-097-C [UCL SNK Config QoS, LC3 48_5_2]",
test_setup, test_client, &cfg_src_48_5_2,
SCC_SRC_48_5_2);
define_test("BAP/UCL/SCC/BV-098-C [UCL SNK Config QoS, LC3 48_6_2]",
test_setup, test_client, &cfg_src_48_6_2,
SCC_SRC_48_6_2);
}
static struct test_config cfg_snk_qos_vs = {
.cc = IOV_NULL,
.qos = QOS_UCAST,
.snk = true,
.vs = true,
.state = BT_BAP_STREAM_STATE_QOS
};
#define SCC_SNK_QOS_VS \
SCC_SNK_VS, \
QOS_SNK(0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00)
static struct test_config cfg_src_qos_vs = {
.cc = IOV_NULL,
.qos = QOS_UCAST,
.src = true,
.vs = true,
.state = BT_BAP_STREAM_STATE_QOS
};
#define SCC_SRC_QOS_VS \
SCC_SRC_VS, \
QOS_SRC(0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00)
/* Test Purpose:
* Verify that a Unicast Client IUT can initiate a Config QoS operation for a
* vendor-specific codec.
*
* Pass verdict:
* The IUT successfully writes to the ASE Control Point characteristic with the
* opcode set to 0x02 (Config QoS) and the specified parameters.
*/
static void test_scc_qos_vs(void)
{
define_test("BAP/UCL/SCC/BV-099-C [UCL SNK Config QoS, VS]",
test_setup, test_client, &cfg_src_qos_vs,
SCC_SRC_QOS_VS);
define_test("BAP/UCL/SCC/BV-100-C [UCL SRC QoS Codec, VS]",
test_setup, test_client, &cfg_snk_qos_vs,
SCC_SNK_QOS_VS);
}
static struct test_config cfg_snk_enable = {
.cc = LC3_CONFIG_16_2,
.qos = LC3_QOS_16_2_1,
.snk = true,
.state = BT_BAP_STREAM_STATE_ENABLING
};
/* ATT: Write Command (0x52) len 23
* Handle: 0x0022
* Data: 03010104030201
* ATT: Handle Value Notification (0x1b) len 7
* Handle: 0x0022
* Data: 0301010000
* ATT: Handle Value Notification (0x1b) len 37
* Handle: 0x0016
* Data: 0101010300403020100
*/
#define SCC_SNK_ENABLE \
SCC_SNK_16_2_1, \
IOV_DATA(0x52, 0x22, 0x00, 0x03, 0x01, 0x01, 0x04, 0x03, 0x02, 0x01, \
00), \
IOV_DATA(0x1b, 0x22, 0x00, 0x03, 0x01, 0x01, 0x00, 0x00), \
IOV_NULL, \
IOV_DATA(0x1b, 0x16, 0x00, 0x01, 0x03, 0x00, 0x00, 0x04, 0x03, 0x02, \
0x01, 0x00)
static struct test_config cfg_src_enable = {
.cc = LC3_CONFIG_16_2,
.qos = LC3_QOS_16_2_1,
.src = true,
.state = BT_BAP_STREAM_STATE_ENABLING
};
/* ATT: Write Command (0x52) len 23
* Handle: 0x0022
* Data: 0301030403020100
* ATT: Handle Value Notification (0x1b) len 7
* Handle: 0x0022
* Data: 0301030000
* ATT: Handle Value Notification (0x1b) len 37
* Handle: 0x001c
* Data: 030300000403020100
*/
#define SRC_ENABLE \
IOV_DATA(0x52, 0x22, 0x00, 0x03, 0x01, 0x03, 0x04, 0x03, 0x02, 0x01, \
00), \
IOV_DATA(0x1b, 0x22, 0x00, 0x03, 0x01, 0x01, 0x00, 0x00), \
IOV_NULL, \
IOV_DATA(0x1b, 0x1c, 0x00, 0x03, 0x03, 0x00, 0x00, 0x04, 0x03, 0x02, \
0x01, 0x00)
#define SCC_SRC_ENABLE \
SCC_SRC_16_2_1, \
SRC_ENABLE
/* Test Purpose:
* Verify that a Unicast Client IUT can initiate an Enable operation for an ASE
* with a Unicast Server that is either in the Audio Sink role or the Audio
* Source role.
*
* Pass verdict:
* The IUT successfully writes to the ASE Control Point characteristic with the
* opcode set to 0x03 (Enable) and the specified parameters.
*/
static void test_scc_enable(void)
{
define_test("BAP/UCL/SCC/BV-101-C [UCL SRC Enable]",
test_setup, test_client, &cfg_snk_enable,
SCC_SNK_ENABLE);
define_test("BAP/UCL/SCC/BV-102-C [UCL SNK Enable]",
test_setup, test_client, &cfg_src_enable,
SCC_SRC_ENABLE);
}
static struct test_config cfg_snk_disable = {
.cc = LC3_CONFIG_16_2,
.qos = LC3_QOS_16_2_1,
.snk = true,
.state = BT_BAP_STREAM_STATE_DISABLING
};
/* ATT: Write Command (0x52) len 23
* Handle: 0x0022
* Data: 050101
* ATT: Handle Value Notification (0x1b) len 7
* Handle: 0x0022
* Data: 0501010000
* ATT: Handle Value Notification (0x1b) len 37
* Handle: 0x0016
* Data: 01010102010a00204e00409c00204e00409c00_qos
*/
#define ASE_SNK_DISABLE \
IOV_DATA(0x52, 0x22, 0x00, 0x05, 0x01, 0x01), \
IOV_DATA(0x1b, 0x22, 0x00, 0x05, 0x01, 0x01, 0x00, 0x00), \
IOV_NULL, \
IOV_DATA(0x1b, 0x16, 0x00, 0x01, 0x02, 0x00, 0x00, 0x4c, 0x1d, 0x00, \
0x00, 0x02, 0x1a, 0x00, 0x02, 0x08, 0x00, 0x40, 0x9c, \
0x00)
#define SCC_SNK_DISABLE \
SCC_SNK_ENABLE, \
ASE_SNK_DISABLE
static struct test_config cfg_src_disable = {
.cc = LC3_CONFIG_16_2,
.qos = LC3_QOS_16_2_1,
.src = true,
.state = BT_BAP_STREAM_STATE_DISABLING
};
/* ATT: Write Command (0x52) len 23
* Handle: 0x0022
* Data: 050103
* ATT: Handle Value Notification (0x1b) len 7
* Handle: 0x0022
* Data: 0301030000
* ATT: Handle Value Notification (0x1b) len 37
* Handle: 0x001c
* Data: 030300000403020100
*/
#define ASE_SRC_DISABLE \
IOV_DATA(0x52, 0x22, 0x00, 0x05, 0x01, 0x03), \
IOV_DATA(0x1b, 0x22, 0x00, 0x05, 0x01, 0x03, 0x00, 0x00), \
IOV_NULL, \
IOV_DATA(0x1b, 0x1c, 0x00, 0x03, 0x05, 0x00, 0x00, 0x4c, 0x1d, 0x00, \
0x00, 0x02, 0x1a, 0x00, 0x04, 0x08, 0x00, 0x40, 0x9c, \
0x00)
#define SCC_SRC_DISABLE \
SCC_SRC_ENABLE, \
ASE_SRC_DISABLE
static void state_start_disable(struct bt_bap_stream *stream,
uint8_t old_state, uint8_t new_state,
void *user_data)
{
struct test_data *data = user_data;
uint8_t id;
switch (new_state) {
case BT_BAP_STREAM_STATE_STREAMING:
id = bt_bap_stream_disable(stream, true, bap_disable,
data);
g_assert(id);
break;
}
}
static struct test_config cfg_src_disable_streaming = {
.cc = LC3_CONFIG_16_2,
.qos = LC3_QOS_16_2_1,
.src = true,
.state = BT_BAP_STREAM_STATE_STREAMING,
.state_func = state_start_disable
};
/* ATT: Write Command (0x52) len 23
* Handle: 0x0022
* Data: 040101
* ATT: Handle Value Notification (0x1b) len 7
* Handle: 0x0022
* Data: 0401010000
* ATT: Handle Value Notification (0x1b) len 37
* Handle: 0x0016
* Data: 0101010400403020100
*/
#define SRC_START \
IOV_DATA(0x52, 0x22, 0x00, 0x04, 0x01, 0x03), \
IOV_DATA(0x1b, 0x22, 0x00, 0x04, 0x01, 0x03, 0x00, 0x00), \
IOV_NULL, \
IOV_DATA(0x1b, 0x1c, 0x00, 0x03, 0x04, 0x00, 0x00, 0x04, 0x03, 0x02, \
0x01, 0x00)
#define SCC_SRC_DISABLE_STREAMING \
SCC_SRC_ENABLE, \
SRC_START, \
ASE_SRC_DISABLE
/* Test Purpose:
* Verify that a Unicast Client IUT can initiate a Disable operation for an ASE
* in the Enabling or Streaming state.
*
* Pass verdict:
* The IUT successfully writes to the ASE Control Point characteristic with the
* opcode set to 0x05 (Disable) and the specified parameters.
*/
static void test_scc_disable(void)
{
define_test("BAP/UCL/SCC/BV-103-C [UCL SNK Disable in Enabling State]",
test_setup, test_client, &cfg_src_disable,
SCC_SRC_DISABLE);
define_test("BAP/UCL/SCC/BV-104-C [UCL SRC Disable in Enabling or "
"Streaming state]",
test_setup, test_client, &cfg_snk_disable,
SCC_SNK_DISABLE);
define_test("BAP/UCL/SCC/BV-105-C [UCL SNK Disable in Streaming State]",
test_setup, test_client, &cfg_src_disable_streaming,
SCC_SRC_DISABLE_STREAMING);
}
static void bap_release(struct bt_bap_stream *stream,
uint8_t code, uint8_t reason,
void *user_data)
{
if (code)
tester_test_failed();
}
static void state_cc_release(struct bt_bap_stream *stream,
uint8_t old_state, uint8_t new_state,
void *user_data)
{
struct test_data *data = user_data;
uint8_t id;
switch (new_state) {
case BT_BAP_STREAM_STATE_CONFIG:
id = bt_bap_stream_release(stream, bap_release, data);
g_assert(id);
break;
}
}
static struct test_config cfg_src_cc_release = {
.cc = LC3_CONFIG_16_2,
.qos = QOS_UCAST,
.src = true,
.state_func = state_cc_release,
};
/* ATT: Write Command (0x52) len 23
* Handle: 0x0022
* Data: 080103
* ATT: Handle Value Notification (0x1b) len 7
* Handle: 0x0022
* Data: 0801030000
* ATT: Handle Value Notification (0x1b) len 37
* Handle: 0x001c
* Data: 0300
*/
#define ASE_SRC_RELEASE \
IOV_DATA(0x52, 0x22, 0x00, 0x08, 0x01, 0x03), \
IOV_DATA(0x1b, 0x22, 0x00, 0x08, 0x01, 0x03, 0x00, 0x00), \
IOV_NULL, \
IOV_DATA(0x1b, 0x1c, 0x00, 0x03, 0x00)
#define SCC_SRC_CC_RELEASE \
SCC_SRC_16_2, \
ASE_SRC_RELEASE
static struct test_config cfg_snk_cc_release = {
.cc = LC3_CONFIG_16_2,
.qos = QOS_UCAST,
.snk = true,
.state_func = state_cc_release,
};
/* ATT: Write Command (0x52) len 23
* Handle: 0x0022
* Data: 080101
* ATT: Handle Value Notification (0x1b) len 7
* Handle: 0x0022
* Data: 0801010000
* ATT: Handle Value Notification (0x1b) len 37
* Handle: 0x0016
* Data: 0300
*/
#define ASE_SNK_RELEASE \
IOV_DATA(0x52, 0x22, 0x00, 0x08, 0x01, 0x01), \
IOV_DATA(0x1b, 0x22, 0x00, 0x08, 0x01, 0x01, 0x00, 0x00), \
IOV_NULL, \
IOV_DATA(0x1b, 0x16, 0x00, 0x03, 0x00)
#define SCC_SNK_CC_RELEASE \
SCC_SNK_16_2, \
ASE_SNK_RELEASE
static void state_qos_release(struct bt_bap_stream *stream,
uint8_t old_state, uint8_t new_state,
void *user_data)
{
struct test_data *data = user_data;
uint8_t id;
switch (new_state) {
case BT_BAP_STREAM_STATE_QOS:
id = bt_bap_stream_release(stream, bap_release, data);
g_assert(id);
break;
}
}
static struct test_config cfg_src_qos_release = {
.cc = LC3_CONFIG_16_2,
.qos = LC3_QOS_16_2_1,
.src = true,
.state = BT_BAP_STREAM_STATE_QOS,
.state_func = state_qos_release,
};
#define SCC_SRC_QOS_RELEASE \
SCC_SRC_16_2_1, \
ASE_SRC_RELEASE
static struct test_config cfg_snk_qos_release = {
.cc = LC3_CONFIG_16_2,
.qos = LC3_QOS_16_2_1,
.snk = true,
.state = BT_BAP_STREAM_STATE_QOS,
.state_func = state_qos_release,
};
#define SCC_SNK_QOS_RELEASE \
SCC_SNK_16_2_1, \
ASE_SNK_RELEASE
static void state_enable_release(struct bt_bap_stream *stream,
uint8_t old_state, uint8_t new_state,
void *user_data)
{
struct test_data *data = user_data;
uint8_t id;
switch (new_state) {
case BT_BAP_STREAM_STATE_ENABLING:
id = bt_bap_stream_release(stream, bap_release, data);
g_assert(id);
break;
}
}
static struct test_config cfg_src_enable_release = {
.cc = LC3_CONFIG_16_2,
.qos = LC3_QOS_16_2_1,
.src = true,
.state = BT_BAP_STREAM_STATE_ENABLING,
.state_func = state_enable_release,
};
#define SCC_SRC_ENABLE_RELEASE \
SCC_SRC_ENABLE, \
ASE_SRC_RELEASE
static struct test_config cfg_snk_enable_release = {
.cc = LC3_CONFIG_16_2,
.qos = LC3_QOS_16_2_1,
.snk = true,
.state = BT_BAP_STREAM_STATE_ENABLING,
.state_func = state_enable_release,
};
#define SCC_SNK_ENABLE_RELEASE \
SCC_SNK_ENABLE, \
ASE_SNK_RELEASE
static void state_start_release(struct bt_bap_stream *stream,
uint8_t old_state, uint8_t new_state,
void *user_data)
{
struct test_data *data = user_data;
uint8_t id;
switch (new_state) {
case BT_BAP_STREAM_STATE_STREAMING:
id = bt_bap_stream_release(stream, bap_release, data);
g_assert(id);
break;
}
}
static struct test_config cfg_src_start_release = {
.cc = LC3_CONFIG_16_2,
.qos = LC3_QOS_16_2_1,
.src = true,
.state = BT_BAP_STREAM_STATE_STREAMING,
.state_func = state_start_release,
};
#define SCC_SRC_START_RELEASE \
SCC_SRC_ENABLE, \
SRC_START, \
ASE_SRC_RELEASE
static void state_disable_release(struct bt_bap_stream *stream,
uint8_t old_state, uint8_t new_state,
void *user_data)
{
struct test_data *data = user_data;
uint8_t id;
switch (new_state) {
case BT_BAP_STREAM_STATE_DISABLING:
id = bt_bap_stream_release(stream, bap_release, data);
g_assert(id);
break;
}
}
static struct test_config cfg_src_disable_release = {
.cc = LC3_CONFIG_16_2,
.qos = LC3_QOS_16_2_1,
.src = true,
.state = BT_BAP_STREAM_STATE_DISABLING,
.state_func = state_disable_release,
};
#define SCC_SRC_DISABLE_RELEASE \
SCC_SRC_DISABLE, \
ASE_SRC_RELEASE
/* Test Purpose:
* Verify that a Unicast Client IUT can release an ASE by initiating a Release
* operation.
*
* Pass verdict:
* The IUT successfully writes to the ASE Control Point characteristic with the
* opcode set to 0x08 (Release) and the specified parameters.
*/
static void test_scc_release(void)
{
define_test("BAP/UCL/SCC/BV-106-C [UCL SNK Release in Codec Configured"
" state]",
test_setup, test_client, &cfg_src_cc_release,
SCC_SRC_CC_RELEASE);
define_test("BAP/UCL/SCC/BV-107-C [UCL SRC Release in Codec Configured"
" state]",
test_setup, test_client, &cfg_snk_cc_release,
SCC_SNK_CC_RELEASE);
define_test("BAP/UCL/SCC/BV-108-C [UCL SNK Release in QoS Configured"
" state]",
test_setup, test_client, &cfg_src_qos_release,
SCC_SRC_QOS_RELEASE);
define_test("BAP/UCL/SCC/BV-109-C [UCL SRC Release in QoS Configured"
" state]",
test_setup, test_client, &cfg_snk_qos_release,
SCC_SNK_QOS_RELEASE);
define_test("BAP/UCL/SCC/BV-110-C [UCL SNK Release in Enabling state]",
test_setup, test_client, &cfg_src_enable_release,
SCC_SRC_ENABLE_RELEASE);
define_test("BAP/UCL/SCC/BV-111-C [UCL SRC Release in Enabling or"
" Streaming state]",
test_setup, test_client, &cfg_snk_enable_release,
SCC_SNK_ENABLE_RELEASE);
define_test("BAP/UCL/SCC/BV-112-C [UCL SNK Release in Streaming state]",
test_setup, test_client, &cfg_src_start_release,
SCC_SRC_START_RELEASE);
define_test("BAP/UCL/SCC/BV-113-C [UCL SNK Release in Disabling state]",
test_setup, test_client, &cfg_src_disable_release,
SCC_SRC_DISABLE_RELEASE);
}
static void bap_metadata(struct bt_bap_stream *stream,
uint8_t code, uint8_t reason,
void *user_data)
{
if (code)
tester_test_failed();
}
static void state_enable_metadata(struct bt_bap_stream *stream,
uint8_t old_state, uint8_t new_state,
void *user_data)
{
struct test_data *data = user_data;
struct iovec iov = {};
uint8_t id;
switch (new_state) {
case BT_BAP_STREAM_STATE_ENABLING:
id = bt_bap_stream_metadata(stream, &iov, bap_metadata,
data);
g_assert(id);
break;
}
}
static struct test_config cfg_snk_metadata = {
.cc = LC3_CONFIG_16_2,
.qos = LC3_QOS_16_2_1,
.snk = true,