edtt: Extend Zephyr EDTT test app with IXIT request/response command

This command is used to obtain 'Implementation eXtra Information for Test'
(IXIT) values that are required to proceed with BT qualification tests.

Signed-off-by: Tim Sørensen <tims@demant.com>
This commit is contained in:
Tim Sørensen 2021-07-19 16:33:16 +02:00 committed by Carles Cufí
commit 9312b79b1c
3 changed files with 124 additions and 0 deletions

View file

@ -751,6 +751,14 @@ config BT_CTLR_CONN_ISO_HCI_DATAPATH_SKIP_INVALID_DATA
This allows for applications to decide whether to This allows for applications to decide whether to
forward invalid SDUs through HCI upwards. forward invalid SDUs through HCI upwards.
config BT_CTLR_CONN_ISO_STREAMS_MAX_NSE
int "LE Connected Isochronous Streams max number of subevents"
depends on BT_CTLR_CONN_ISO
range 1 31
default 31
help
Maximum number of CIS subevents.
config BT_CTLR_ISO config BT_CTLR_ISO
bool bool
default BT_CTLR_BROADCAST_ISO || BT_CTLR_CONN_ISO default BT_CTLR_BROADCAST_ISO || BT_CTLR_CONN_ISO

View file

@ -244,6 +244,43 @@ enum commands_t {
CMD_LE_ISO_DATA_WRITE_RSP, CMD_LE_ISO_DATA_WRITE_RSP,
CMD_LE_ISO_DATA_READ_REQ, CMD_LE_ISO_DATA_READ_REQ,
CMD_LE_ISO_DATA_READ_RSP, CMD_LE_ISO_DATA_READ_RSP,
CMD_LE_SET_CIG_PARAMETERS_REQ,
CMD_LE_SET_CIG_PARAMETERS_RSP,
CMD_LE_SET_CIG_PARAMETERS_TEST_REQ,
CMD_LE_SET_CIG_PARAMETERS_TEST_RSP,
CMD_LE_CREATE_CIS_REQ,
CMD_LE_CREATE_CIS_RSP,
CMD_LE_REMOVE_CIG_REQ,
CMD_LE_REMOVE_CIG_RSP,
CMD_LE_ACCEPT_CIS_REQUEST_REQ,
CMD_LE_ACCEPT_CIS_REQUEST_RSP,
CMD_LE_REJECT_CIS_REQUEST_REQ,
CMD_LE_REJECT_CIS_REQUEST_RSP,
CMD_LE_SETUP_ISO_DATA_PATH_REQ,
CMD_LE_SETUP_ISO_DATA_PATH_RSP,
CMD_LE_REMOVE_ISO_DATA_PATH_REQ,
CMD_LE_REMOVE_ISO_DATA_PATH_RSP,
CMD_LE_SET_HOST_FEATURE_REQ,
CMD_LE_SET_HOST_FEATURE_RSP,
CMD_GET_IXIT_VALUE_REQ,
CMD_GET_IXIT_VALUE_RSP,
CMD_HCI_LE_ISO_TRANSMIT_TEST_REQ,
CMD_HCI_LE_ISO_TRANSMIT_TEST_RSP,
CMD_HCI_LE_ISO_RECEIVE_TEST_REQ,
CMD_HCI_LE_ISO_RECEIVE_TEST_RSP,
CMD_HCI_LE_ISO_READ_TEST_COUNTERS_REQ,
CMD_HCI_LE_ISO_READ_TEST_COUNTERS_RSP,
CMD_HCI_LE_ISO_TEST_END_REQ,
CMD_HCI_LE_ISO_TEST_END_RSP
};
enum profile_t {
PROFILE_ID_GAP,
PROFILE_ID_GATT,
PROFILE_ID_HCI,
PROFILE_ID_L2CAP,
PROFILE_ID_LL,
PROFILE_ID_SM,
}; };
#endif /* EDDT_APP_COMMANDS_H */ #endif /* EDDT_APP_COMMANDS_H */

View file

@ -39,6 +39,25 @@ static uint16_t waiting_opcode;
static enum commands_t waiting_response; static enum commands_t waiting_response;
static uint8_t m_events; static uint8_t m_events;
struct EdttIxit {
uint8_t refMajor;
uint8_t refMinor;
uint16_t len;
uint8_t *pVal;
};
/*! \brief Implementation eXtra Information for Test (IXIT) definitions */
#if defined(CONFIG_BT_CTLR_CONN_ISO_STREAMS_MAX_NSE)
const uint8_t TSPX_max_cis_nse = CONFIG_BT_CTLR_CONN_ISO_STREAMS_MAX_NSE;
#endif
/*! \brief Persistent LL IXIT values. */
static struct EdttIxit llIxits[] = {
#if defined(CONFIG_BT_CTLR_CONN_ISO_STREAMS_MAX_NSE)
{7, 14, 1, &TSPX_max_cis_nse},
#endif
};
/** /**
* @brief Clean out excess bytes from the input buffer * @brief Clean out excess bytes from the input buffer
*/ */
@ -672,6 +691,61 @@ static void le_iso_data_write(uint16_t size)
} }
#endif /* CONFIG_BT_ISO */ #endif /* CONFIG_BT_ISO */
/**
* @brief Read 'Implementation eXtra Information for Test' value
*/
static void le_ixit_value_read(uint16_t size)
{
uint8_t profileId;
uint8_t refMajor;
uint8_t refMinor;
struct EdttIxit *pIxitArray;
int ixitArraySize;
struct EdttIxit *pIxitElement = NULL;
/*
* CMD_GET_IXIT_VALUE_REQ payload layout
*
* ...
* [ 4] PROFILE_ID[0]
* [ 5] IXIT_Reference_Major
* [ 6] IXIT_Reference_Minor
*/
edtt_read((uint8_t *)&profileId, sizeof(profileId), EDTTT_BLOCK);
edtt_read((uint8_t *)&refMajor, sizeof(refMajor), EDTTT_BLOCK);
edtt_read((uint8_t *)&refMinor, sizeof(refMinor), EDTTT_BLOCK);
switch (profileId) {
case PROFILE_ID_LL:
pIxitArray = llIxits;
ixitArraySize = ARRAY_SIZE(llIxits);
break;
default:
pIxitArray = NULL;
ixitArraySize = 0;
}
for (int i = 0; i < ixitArraySize; i++) {
if (pIxitArray[i].refMajor == refMajor && pIxitArray[i].refMinor == refMinor) {
pIxitElement = &pIxitArray[i];
break;
}
}
struct ixit_value_get_resp {
uint16_t code;
uint16_t size;
uint8_t data[];
} __packed;
struct ixit_value_get_resp response = {
.code = sys_cpu_to_le16(CMD_GET_IXIT_VALUE_RSP),
.size = sys_cpu_to_le16(pIxitElement ? pIxitElement->len : 0),
};
edtt_write((uint8_t *)&response, sizeof(response), EDTTT_BLOCK);
if (pIxitElement) {
edtt_write(pIxitElement->pVal, pIxitElement->len, EDTTT_BLOCK);
}
}
static K_THREAD_STACK_DEFINE(service_events_stack, static K_THREAD_STACK_DEFINE(service_events_stack,
CONFIG_BT_HCI_TX_STACK_SIZE); CONFIG_BT_HCI_TX_STACK_SIZE);
static struct k_thread service_events_data; static struct k_thread service_events_data;
@ -775,6 +849,11 @@ void main(void)
le_iso_data_read(size); le_iso_data_read(size);
break; break;
#endif /* CONFIG_BT_ISO */ #endif /* CONFIG_BT_ISO */
case CMD_GET_IXIT_VALUE_REQ:
le_ixit_value_read(size);
break;
default: default:
if (size >= 2) { if (size >= 2) {
edtt_read((uint8_t *)&opcode, sizeof(opcode), edtt_read((uint8_t *)&opcode, sizeof(opcode),