mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-11-10 14:30:33 +00:00
nimble/ll/iso: Add HCI LE ISO Transmit Test command
This adds command implementation along with unit test. Fixes: LL/IST/BRD/BV-01-C
This commit is contained in:
committed by
Andrzej Kaczmarek
parent
47eeaea896
commit
8bb24379f7
@@ -27,10 +27,30 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct ble_ll_iso_data_path {
|
||||
uint8_t data_path_id;
|
||||
uint8_t enabled : 1;
|
||||
};
|
||||
struct ble_ll_iso_test_mode {
|
||||
struct {
|
||||
uint32_t rand;
|
||||
uint8_t payload_type;
|
||||
uint8_t enabled : 1;
|
||||
} transmit;
|
||||
};
|
||||
struct ble_ll_iso_conn {
|
||||
/* Connection handle */
|
||||
uint16_t handle;
|
||||
|
||||
/* Maximum SDU size */
|
||||
uint16_t max_sdu;
|
||||
|
||||
/* ISO Data Path */
|
||||
struct ble_ll_iso_data_path data_path;
|
||||
|
||||
/* ISO Test Mode */
|
||||
struct ble_ll_iso_test_mode test_mode;
|
||||
|
||||
/* ISOAL Multiplexer */
|
||||
struct ble_ll_isoal_mux mux;
|
||||
|
||||
@@ -48,7 +68,6 @@ int ble_ll_iso_read_tx_sync(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf,
|
||||
int ble_ll_iso_set_cig_param(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen);
|
||||
int ble_ll_iso_set_cig_param_test(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen);
|
||||
int ble_ll_iso_create_cis(const uint8_t *cmdbuf, uint8_t len);
|
||||
int ble_ll_iso_disconnect_cmd(const struct ble_hci_lc_disconnect_cp *cmd);
|
||||
int ble_ll_iso_remove_cig(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen);
|
||||
int ble_ll_iso_accept_cis_req(const uint8_t *cmdbuf, uint8_t len);
|
||||
int ble_ll_iso_reject_cis_req(const uint8_t *cmdbuf, uint8_t len);
|
||||
@@ -59,10 +78,10 @@ int ble_ll_iso_big_create_sync(const uint8_t *cmdbuf, uint8_t len);
|
||||
int ble_ll_iso_big_terminate_sync(const uint8_t *cmdbuf, uint8_t len);
|
||||
int ble_ll_iso_setup_iso_data_path(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen);
|
||||
int ble_ll_iso_remove_iso_data_path(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen);
|
||||
int ble_ll_iso_transmit_test(const uint8_t *cmdbuf, uint8_t len);
|
||||
int ble_ll_iso_transmit_test(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen);
|
||||
int ble_ll_iso_receive_test(const uint8_t *cmdbuf, uint8_t len);
|
||||
int ble_ll_iso_read_counters_test(const uint8_t *cmdbuf, uint8_t len);
|
||||
int ble_ll_iso_end_test(const uint8_t *cmdbuf, uint8_t len);
|
||||
int ble_ll_iso_end_test(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen);
|
||||
|
||||
void ble_ll_iso_init(void);
|
||||
void ble_ll_iso_reset(void);
|
||||
@@ -70,11 +89,20 @@ void ble_ll_iso_reset(void);
|
||||
/* ISO Data handler */
|
||||
int ble_ll_iso_data_in(struct os_mbuf *om);
|
||||
|
||||
int ble_ll_iso_pdu_get(struct ble_ll_iso_conn *conn, uint8_t idx, uint8_t *llid, void *dptr);
|
||||
int ble_ll_iso_pdu_get(struct ble_ll_iso_conn *conn, uint8_t idx, uint32_t pkt_counter, uint8_t *llid, void *dptr);
|
||||
|
||||
void ble_ll_iso_conn_init(struct ble_ll_iso_conn *conn, uint16_t conn_handle,
|
||||
uint8_t max_pdu, uint32_t iso_interval_us,
|
||||
uint32_t sdu_interval_us, uint8_t bn, uint8_t pte, uint8_t framing);
|
||||
struct ble_ll_iso_conn_init_param {
|
||||
uint32_t iso_interval_us;
|
||||
uint32_t sdu_interval_us;
|
||||
uint16_t conn_handle;
|
||||
uint16_t max_sdu;
|
||||
uint8_t max_pdu;
|
||||
uint8_t framing;
|
||||
uint8_t pte;
|
||||
uint8_t bn;
|
||||
};
|
||||
|
||||
void ble_ll_iso_conn_init(struct ble_ll_iso_conn *conn, struct ble_ll_iso_conn_init_param *param);
|
||||
void ble_ll_iso_conn_free(struct ble_ll_iso_conn *conn);
|
||||
|
||||
int ble_ll_iso_conn_event_start(struct ble_ll_iso_conn *conn, uint32_t timestamp);
|
||||
|
||||
@@ -1284,6 +1284,9 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf,
|
||||
case BLE_HCI_OCF_LE_TERMINATE_BIG:
|
||||
rc = ble_ll_iso_big_hci_terminate(cmdbuf, len);
|
||||
break;
|
||||
case BLE_HCI_OCF_LE_ISO_TRANSMIT_TEST:
|
||||
rc = ble_ll_iso_transmit_test(cmdbuf, len, rspbuf, rsplen);
|
||||
break;
|
||||
#endif /* BLE_LL_ISO_BROADCASTER */
|
||||
#if MYNEWT_VAL(BLE_LL_ISO)
|
||||
case BLE_HCI_OCF_LE_SETUP_ISO_DATA_PATH:
|
||||
@@ -1292,6 +1295,9 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf,
|
||||
case BLE_HCI_OCF_LE_REMOVE_ISO_DATA_PATH:
|
||||
rc = ble_ll_iso_remove_iso_data_path(cmdbuf, len, rspbuf, rsplen);
|
||||
break;
|
||||
case BLE_HCI_OCF_LE_ISO_TEST_END:
|
||||
rc = ble_ll_iso_end_test(cmdbuf, len, rspbuf, rsplen);
|
||||
break;
|
||||
case BLE_HCI_OCF_LE_READ_ISO_TX_SYNC:
|
||||
rc = ble_ll_iso_read_tx_sync(cmdbuf, len, rspbuf, rsplen);
|
||||
break;
|
||||
|
||||
@@ -288,9 +288,15 @@ static const uint8_t octet_43 = OCTET(
|
||||
BIT(3) /* HCI LE Setup ISO Data Path */
|
||||
BIT(4) /* HCI LE Remove ISO Data Path */
|
||||
#endif
|
||||
#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER)
|
||||
BIT(5) /* HCI LE ISO Transmit Test */
|
||||
#endif
|
||||
);
|
||||
|
||||
static const uint8_t octet_44 = OCTET(
|
||||
#if MYNEWT_VAL(BLE_LL_ISO)
|
||||
BIT(0) /* HCI LE ISO Test End */
|
||||
#endif
|
||||
#if BLE_LL_HOST_CONTROLLED_FEATURES
|
||||
BIT(1) /* HCI LE Set Host Feature */
|
||||
#endif
|
||||
|
||||
@@ -46,6 +46,14 @@ ble_ll_iso_setup_iso_data_path(const uint8_t *cmdbuf, uint8_t cmdlen,
|
||||
return BLE_ERR_UNK_CONN_ID;
|
||||
}
|
||||
|
||||
if (conn->mux.bn == 0) {
|
||||
return BLE_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (conn->data_path.enabled) {
|
||||
return BLE_ERR_CMD_DISALLOWED;
|
||||
}
|
||||
|
||||
/* Only input for now since we only support BIS */
|
||||
if (cmd->data_path_dir) {
|
||||
return BLE_ERR_CMD_DISALLOWED;
|
||||
@@ -56,6 +64,9 @@ ble_ll_iso_setup_iso_data_path(const uint8_t *cmdbuf, uint8_t cmdlen,
|
||||
return BLE_ERR_CMD_DISALLOWED;
|
||||
}
|
||||
|
||||
conn->data_path.enabled = 1;
|
||||
conn->data_path.data_path_id = cmd->data_path_id;
|
||||
|
||||
rsp->conn_handle = cmd->conn_handle;
|
||||
*rsplen = sizeof(*rsp);
|
||||
|
||||
@@ -68,8 +79,23 @@ ble_ll_iso_remove_iso_data_path(const uint8_t *cmdbuf, uint8_t cmdlen,
|
||||
{
|
||||
const struct ble_hci_le_remove_iso_data_path_cp *cmd = (const void *)cmdbuf;
|
||||
struct ble_hci_le_remove_iso_data_path_rp *rsp = (void *)rspbuf;
|
||||
struct ble_ll_iso_conn *conn;
|
||||
uint16_t conn_handle;
|
||||
|
||||
conn_handle = le16toh(cmd->conn_handle);
|
||||
|
||||
conn = ble_ll_iso_conn_find_by_handle(conn_handle);
|
||||
if (!conn) {
|
||||
return BLE_ERR_UNK_CONN_ID;
|
||||
}
|
||||
|
||||
/* Only input for now since we only support BIS */
|
||||
if (cmd->data_path_dir) {
|
||||
return BLE_ERR_CMD_DISALLOWED;
|
||||
}
|
||||
|
||||
conn->data_path.enabled = 0;
|
||||
|
||||
/* XXX accepts anything for now */
|
||||
rsp->conn_handle = cmd->conn_handle;
|
||||
*rsplen = sizeof(*rsp);
|
||||
|
||||
@@ -101,6 +127,76 @@ ble_ll_iso_read_tx_sync(const uint8_t *cmdbuf, uint8_t cmdlen,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ble_ll_iso_transmit_test(const uint8_t *cmdbuf, uint8_t cmdlen, uint8_t *rspbuf, uint8_t *rsplen)
|
||||
{
|
||||
const struct ble_hci_le_iso_transmit_test_cp *cmd = (const void *)cmdbuf;
|
||||
struct ble_hci_le_iso_transmit_test_rp *rsp = (void *)rspbuf;
|
||||
struct ble_ll_iso_conn *conn;
|
||||
uint16_t handle;
|
||||
|
||||
handle = le16toh(cmd->conn_handle);
|
||||
|
||||
conn = ble_ll_iso_conn_find_by_handle(handle);
|
||||
if (!conn) {
|
||||
return BLE_ERR_UNK_CONN_ID;
|
||||
}
|
||||
|
||||
if (conn->mux.bn == 0) {
|
||||
return BLE_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (conn->data_path.enabled) {
|
||||
return BLE_ERR_CMD_DISALLOWED;
|
||||
}
|
||||
|
||||
if (cmd->payload_type > BLE_HCI_PAYLOAD_TYPE_MAXIMUM_LENGTH) {
|
||||
return BLE_ERR_INV_LMP_LL_PARM;
|
||||
}
|
||||
|
||||
conn->data_path.enabled = 1;
|
||||
conn->data_path.data_path_id = BLE_HCI_ISO_DATA_PATH_ID_HCI;
|
||||
conn->test_mode.transmit.enabled = 1;
|
||||
conn->test_mode.transmit.payload_type = cmd->payload_type;
|
||||
|
||||
rsp->conn_handle = cmd->conn_handle;
|
||||
|
||||
*rsplen = sizeof(*rsp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ble_ll_iso_end_test(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen)
|
||||
{
|
||||
const struct ble_hci_le_iso_test_end_cp *cmd = (const void *)cmdbuf;
|
||||
struct ble_hci_le_iso_test_end_rp *rsp = (void *)rspbuf;
|
||||
struct ble_ll_iso_conn *iso_conn;
|
||||
uint16_t handle;
|
||||
|
||||
handle = le16toh(cmd->conn_handle);
|
||||
iso_conn = ble_ll_iso_conn_find_by_handle(handle);
|
||||
if (!iso_conn) {
|
||||
return BLE_ERR_UNK_CONN_ID;
|
||||
}
|
||||
|
||||
if (!iso_conn->test_mode.transmit.enabled) {
|
||||
return BLE_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
iso_conn->data_path.enabled = 0;
|
||||
iso_conn->test_mode.transmit.enabled = 0;
|
||||
|
||||
rsp->conn_handle = cmd->conn_handle;
|
||||
rsp->received_sdu_count = 0;
|
||||
rsp->missed_sdu_count = 0;
|
||||
rsp->failed_sdu_count = 0;
|
||||
|
||||
*rsplen = sizeof(*rsp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ble_ll_iso_conn *
|
||||
ble_ll_iso_conn_find_by_handle(uint16_t conn_handle)
|
||||
{
|
||||
@@ -213,26 +309,93 @@ ble_ll_iso_data_in(struct os_mbuf *om)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ble_ll_iso_pdu_get(struct ble_ll_iso_conn *conn, uint8_t idx, uint8_t *llid, void *dptr)
|
||||
static int
|
||||
ble_ll_iso_test_pdu_get(struct ble_ll_iso_conn *conn, uint8_t idx, uint32_t pkt_counter, uint8_t *llid, uint8_t *dptr)
|
||||
{
|
||||
uint32_t payload_len;
|
||||
uint16_t rem_len;
|
||||
uint8_t sdu_idx;
|
||||
uint8_t pdu_idx;
|
||||
int pdu_len;
|
||||
|
||||
BLE_LL_ASSERT(!conn->mux.framed);
|
||||
|
||||
sdu_idx = idx / conn->mux.pdu_per_sdu;
|
||||
pdu_idx = idx - sdu_idx * conn->mux.pdu_per_sdu;
|
||||
|
||||
switch (conn->test_mode.transmit.payload_type) {
|
||||
case BLE_HCI_PAYLOAD_TYPE_ZERO_LENGTH:
|
||||
*llid = 0b00;
|
||||
pdu_len = 0;
|
||||
break;
|
||||
case BLE_HCI_PAYLOAD_TYPE_VARIABLE_LENGTH:
|
||||
payload_len = max(conn->test_mode.transmit.rand + (sdu_idx * pdu_idx), 4);
|
||||
|
||||
rem_len = payload_len - pdu_idx * conn->mux.max_pdu;
|
||||
if (rem_len == 0) {
|
||||
*llid = 0b01;
|
||||
pdu_len = 0;
|
||||
} else {
|
||||
*llid = rem_len > conn->mux.max_pdu;
|
||||
pdu_len = min(conn->mux.max_pdu, rem_len);
|
||||
}
|
||||
|
||||
memset(dptr, 0, pdu_len);
|
||||
|
||||
if (payload_len == rem_len) {
|
||||
put_le32(dptr, pkt_counter);
|
||||
}
|
||||
|
||||
break;
|
||||
case BLE_HCI_PAYLOAD_TYPE_MAXIMUM_LENGTH:
|
||||
payload_len = conn->max_sdu;
|
||||
|
||||
rem_len = payload_len - pdu_idx * conn->mux.max_pdu;
|
||||
if (rem_len == 0) {
|
||||
*llid = 0b01;
|
||||
pdu_len = 0;
|
||||
} else {
|
||||
*llid = rem_len > conn->mux.max_pdu;
|
||||
pdu_len = min(conn->mux.max_pdu, rem_len);
|
||||
}
|
||||
|
||||
memset(dptr, 0, pdu_len);
|
||||
|
||||
if (payload_len == rem_len) {
|
||||
put_le32(dptr, pkt_counter);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
BLE_LL_ASSERT(0);
|
||||
}
|
||||
|
||||
return pdu_len;
|
||||
}
|
||||
|
||||
int
|
||||
ble_ll_iso_pdu_get(struct ble_ll_iso_conn *conn, uint8_t idx, uint32_t pkt_counter, uint8_t *llid, void *dptr)
|
||||
{
|
||||
if (conn->test_mode.transmit.enabled) {
|
||||
return ble_ll_iso_test_pdu_get(conn, idx, pkt_counter, llid, dptr);
|
||||
}
|
||||
|
||||
return ble_ll_isoal_mux_pdu_get(&conn->mux, idx, llid, dptr);
|
||||
}
|
||||
|
||||
void
|
||||
ble_ll_iso_conn_init(struct ble_ll_iso_conn *conn, uint16_t conn_handle,
|
||||
uint8_t max_pdu, uint32_t iso_interval_us,
|
||||
uint32_t sdu_interval_us, uint8_t bn, uint8_t pte,
|
||||
uint8_t framing)
|
||||
ble_ll_iso_conn_init(struct ble_ll_iso_conn *conn, struct ble_ll_iso_conn_init_param *param)
|
||||
{
|
||||
os_sr_t sr;
|
||||
|
||||
memset(conn, 0, sizeof(*conn));
|
||||
|
||||
conn->handle = conn_handle;
|
||||
ble_ll_isoal_mux_init(&conn->mux, max_pdu, iso_interval_us, sdu_interval_us,
|
||||
bn, pte, BLE_LL_ISOAL_MUX_IS_FRAMED(framing),
|
||||
framing == BLE_HCI_ISO_FRAMING_FRAMED_UNSEGMENTED);
|
||||
conn->handle = param->conn_handle;
|
||||
conn->max_sdu = param->max_sdu;
|
||||
|
||||
ble_ll_isoal_mux_init(&conn->mux, param->max_pdu, param->iso_interval_us, param->sdu_interval_us,
|
||||
param->bn, param->pte, BLE_LL_ISOAL_MUX_IS_FRAMED(param->framing),
|
||||
param->framing == BLE_HCI_ISO_FRAMING_FRAMED_UNSEGMENTED);
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
STAILQ_INSERT_TAIL(&ll_iso_conn_q, conn, iso_conn_q_next);
|
||||
@@ -254,6 +417,10 @@ ble_ll_iso_conn_free(struct ble_ll_iso_conn *conn)
|
||||
int
|
||||
ble_ll_iso_conn_event_start(struct ble_ll_iso_conn *conn, uint32_t timestamp)
|
||||
{
|
||||
if (conn->test_mode.transmit.enabled) {
|
||||
conn->test_mode.transmit.rand = ble_ll_rand() % conn->max_sdu;
|
||||
}
|
||||
|
||||
ble_ll_isoal_mux_event_start(&conn->mux, timestamp);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -683,7 +683,7 @@ ble_ll_iso_big_subevent_pdu_cb(uint8_t *dptr, void *arg, uint8_t *hdr_byte)
|
||||
}
|
||||
|
||||
#if 1
|
||||
pdu_len = ble_ll_iso_pdu_get(&bis->conn, idx, &llid, dptr);
|
||||
pdu_len = ble_ll_iso_pdu_get(&bis->conn, idx, big->bis_counter + idx, &llid, dptr);
|
||||
#else
|
||||
llid = 0;
|
||||
pdu_len = big->max_pdu;
|
||||
@@ -923,12 +923,18 @@ static int
|
||||
ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis,
|
||||
struct big_params *bp)
|
||||
{
|
||||
struct ble_ll_iso_conn_init_param conn_init_param = {
|
||||
.iso_interval_us = bp->iso_interval * 1250,
|
||||
.sdu_interval_us = bp->sdu_interval,
|
||||
.max_sdu = bp->max_sdu,
|
||||
.max_pdu = bp->max_pdu,
|
||||
.framing = bp->framing,
|
||||
.bn = bp->bn,
|
||||
};
|
||||
struct ble_ll_iso_big *big = NULL;
|
||||
struct ble_ll_iso_bis *bis;
|
||||
struct ble_ll_adv_sm *advsm;
|
||||
uint32_t seed_aa;
|
||||
uint16_t conn_handle;
|
||||
uint8_t pte;
|
||||
uint8_t gc;
|
||||
uint8_t idx;
|
||||
int rc;
|
||||
@@ -984,9 +990,9 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis,
|
||||
/* Core 5.3, Vol 6, Part B, 4.4.6.6 */
|
||||
gc = bp->nse / bp->bn;
|
||||
if (bp->irc == gc) {
|
||||
pte = 0;
|
||||
conn_init_param.pte = 0;
|
||||
} else {
|
||||
pte = bp->pto * (gc - bp->irc);
|
||||
conn_init_param.pte = bp->pto * (gc - bp->irc);
|
||||
}
|
||||
|
||||
/* Allocate BISes */
|
||||
@@ -1005,11 +1011,9 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis,
|
||||
bis->num = big->num_bis;
|
||||
bis->crc_init = (big->crc_init << 8) | (big->num_bis);
|
||||
|
||||
conn_handle = BLE_LL_CONN_HANDLE(BLE_LL_CONN_HANDLE_TYPE_BIS, idx);
|
||||
conn_init_param.conn_handle = BLE_LL_CONN_HANDLE(BLE_LL_CONN_HANDLE_TYPE_BIS, idx);
|
||||
|
||||
ble_ll_iso_conn_init(&bis->conn, conn_handle, bp->max_pdu,
|
||||
bp->iso_interval * 1250, bp->sdu_interval,
|
||||
bp->bn, pte, bp->framing);
|
||||
ble_ll_iso_conn_init(&bis->conn, &conn_init_param);
|
||||
}
|
||||
|
||||
bis_pool_free -= num_bis;
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <controller/ble_ll_iso.h>
|
||||
#include <os/os_mbuf.h>
|
||||
#include <nimble/ble.h>
|
||||
#include <nimble/hci_common.h>
|
||||
#include <testutil/testutil.h>
|
||||
|
||||
#ifndef min
|
||||
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef max
|
||||
#define max(a, b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#define TSPX_max_tx_nse 3
|
||||
#define TSPX_max_tx_payload 32
|
||||
|
||||
/* LL.TS.p24 4.11.2 Common Parameters */
|
||||
struct test_ll_common_params {
|
||||
uint8_t TxNumBIS;
|
||||
uint8_t RxNumBIS;
|
||||
uint8_t NumDataPDUs;
|
||||
uint8_t RTN;
|
||||
uint8_t NSE;
|
||||
uint8_t IRC;
|
||||
uint8_t PTO;
|
||||
uint8_t BN;
|
||||
uint8_t Transport_Latency;
|
||||
uint8_t SDU_Interval;
|
||||
uint8_t ISO_Interval;
|
||||
uint8_t BIG_Sync_Timeout;
|
||||
uint8_t Data_Size;
|
||||
uint8_t PHY;
|
||||
uint8_t Packing;
|
||||
uint8_t Framing;
|
||||
uint8_t Encryption;
|
||||
uint8_t PADV_Interval;
|
||||
uint8_t Sync_Timeout;
|
||||
};
|
||||
|
||||
const struct test_ll_common_params test_ll_common_params_bn_1 = {
|
||||
.TxNumBIS = 1,
|
||||
.RxNumBIS = 1,
|
||||
.NumDataPDUs = 20,
|
||||
.RTN = TSPX_max_tx_nse,
|
||||
.NSE = TSPX_max_tx_nse,
|
||||
.IRC = TSPX_max_tx_nse,
|
||||
.PTO = 0,
|
||||
.BN = 1,
|
||||
.Transport_Latency = 20,
|
||||
.SDU_Interval = 10,
|
||||
.ISO_Interval = 10,
|
||||
.BIG_Sync_Timeout = 100,
|
||||
.Data_Size = 0,
|
||||
.PHY = 0x01,
|
||||
.Packing = 0x00,
|
||||
.Framing = 0x00,
|
||||
.Encryption = 0x00,
|
||||
.PADV_Interval = 20,
|
||||
.Sync_Timeout = 100,
|
||||
};
|
||||
|
||||
TEST_CASE_SELF(test_ll_ist_brd_bv_01_c) {
|
||||
const uint8_t payload_types[] = {
|
||||
BLE_HCI_PAYLOAD_TYPE_ZERO_LENGTH,
|
||||
BLE_HCI_PAYLOAD_TYPE_VARIABLE_LENGTH,
|
||||
BLE_HCI_PAYLOAD_TYPE_MAXIMUM_LENGTH
|
||||
};
|
||||
const struct test_ll_common_params *params = &test_ll_common_params_bn_1;
|
||||
struct ble_hci_le_setup_iso_data_path_cp setup_iso_data_path_cp;
|
||||
struct ble_hci_le_setup_iso_data_path_rp setup_iso_data_path_rp;
|
||||
struct ble_hci_le_iso_transmit_test_cp iso_transmit_test_cp;
|
||||
struct ble_hci_le_iso_transmit_test_rp iso_transmit_test_rp;
|
||||
struct ble_hci_le_iso_test_end_cp iso_test_end_cp;
|
||||
struct ble_hci_le_iso_test_end_rp iso_test_end_rp;
|
||||
struct ble_ll_iso_conn_init_param conn_param = {
|
||||
.iso_interval_us = params->SDU_Interval * 1000,
|
||||
.sdu_interval_us = params->SDU_Interval * 1000,
|
||||
.conn_handle = 0x0001,
|
||||
.max_sdu = TSPX_max_tx_payload,
|
||||
.max_pdu = TSPX_max_tx_payload,
|
||||
.framing = params->Framing,
|
||||
.bn = params->BN
|
||||
};
|
||||
struct ble_ll_iso_conn conn;
|
||||
uint8_t payload_type;
|
||||
uint8_t pdu[100];
|
||||
uint8_t llid;
|
||||
uint8_t rsplen = 0;
|
||||
int rc;
|
||||
|
||||
ble_ll_iso_conn_init(&conn, &conn_param);
|
||||
|
||||
for (uint8_t i = 0; i < ARRAY_SIZE(payload_types); i++) {
|
||||
payload_type = payload_types[i];
|
||||
|
||||
/* 2. The Upper Tester sends the HCI_LE_ISO_Transmit_Test command with Payload_Type as
|
||||
* specified in Table 4.12-2 and receives a successful HCI_Command_Complete event from the IUT in response.
|
||||
*/
|
||||
rsplen = 0xFF;
|
||||
iso_transmit_test_cp.conn_handle = htole16(conn.handle);
|
||||
iso_transmit_test_cp.payload_type = payload_type;
|
||||
rc = ble_ll_iso_transmit_test((uint8_t *)&iso_transmit_test_cp, sizeof(iso_transmit_test_cp),
|
||||
(uint8_t *)&iso_transmit_test_rp, &rsplen);
|
||||
TEST_ASSERT(rc == 0);
|
||||
TEST_ASSERT(rsplen == sizeof(iso_transmit_test_rp));
|
||||
TEST_ASSERT(iso_transmit_test_rp.conn_handle == iso_transmit_test_cp.conn_handle);
|
||||
|
||||
/* 3. The IUT sends isochronous data PDUs with Payload as specified in Table 4.12-2. The SDU
|
||||
* Count value meets the requirements for unframed PDUs as specified in [14] Section 7.1.
|
||||
* 4. Repeat step 3 for a total of 5 payloads.
|
||||
*/
|
||||
for (uint8_t j = 0; j < 5; j++) {
|
||||
rc = ble_ll_iso_conn_event_start(&conn, 30000);
|
||||
TEST_ASSERT(rc == 0);
|
||||
|
||||
for (uint8_t k = 0; k < conn_param.bn; k++) {
|
||||
llid = 0xFF;
|
||||
rc = ble_ll_iso_pdu_get(&conn, k, k, &llid, pdu);
|
||||
if (payload_type == BLE_HCI_PAYLOAD_TYPE_ZERO_LENGTH) {
|
||||
TEST_ASSERT(rc == 0);
|
||||
TEST_ASSERT(llid == 0b00);
|
||||
} else if (payload_type == BLE_HCI_PAYLOAD_TYPE_VARIABLE_LENGTH) {
|
||||
TEST_ASSERT(rc >= 4);
|
||||
TEST_ASSERT(llid == 0b00);
|
||||
} else if (payload_type == BLE_HCI_PAYLOAD_TYPE_MAXIMUM_LENGTH) {
|
||||
TEST_ASSERT(rc == conn_param.max_pdu);
|
||||
TEST_ASSERT(llid == 0b00);
|
||||
}
|
||||
}
|
||||
|
||||
rc = ble_ll_iso_conn_event_done(&conn);
|
||||
TEST_ASSERT(rc == 0);
|
||||
}
|
||||
|
||||
/* 5. The Upper Tester sends an HCI_LE_Setup_ISO_Data_Path command to the IUT.
|
||||
* 6. The IUT sends an HCI_Command_Complete event to the Upper Tester with Status set to 0x0C.
|
||||
*/
|
||||
setup_iso_data_path_cp.conn_handle = htole16(conn.handle);
|
||||
setup_iso_data_path_cp.data_path_dir = 0x00;
|
||||
setup_iso_data_path_cp.data_path_id = 0x00;
|
||||
rc = ble_ll_iso_setup_iso_data_path((uint8_t *)&setup_iso_data_path_cp, sizeof(setup_iso_data_path_cp),
|
||||
(uint8_t *)&setup_iso_data_path_rp, &rsplen);
|
||||
TEST_ASSERT(rc == 0x0C);
|
||||
|
||||
/* 7. The Upper Tester sends the HCI_LE_ISO_Test_End command to the IUT and receives an
|
||||
* HCI_Command_Status event from the IUT with the Status field set to Success. The returned
|
||||
* Received_SDU_Count, Missed_SDU_Count, and Failed_SDU_Count are all zero.
|
||||
*/
|
||||
rsplen = 0xFF;
|
||||
iso_test_end_cp.conn_handle = htole16(conn.handle);
|
||||
rc = ble_ll_iso_end_test((uint8_t *)&iso_test_end_cp, sizeof(iso_test_end_cp),
|
||||
(uint8_t *)&iso_test_end_rp, &rsplen);
|
||||
TEST_ASSERT(rc == 0);
|
||||
TEST_ASSERT(rsplen == sizeof(iso_test_end_rp));
|
||||
TEST_ASSERT(iso_test_end_rp.conn_handle == iso_test_end_cp.conn_handle);
|
||||
TEST_ASSERT(iso_test_end_rp.received_sdu_count == 0);
|
||||
TEST_ASSERT(iso_test_end_rp.missed_sdu_count == 0);
|
||||
TEST_ASSERT(iso_test_end_rp.failed_sdu_count == 0);
|
||||
}
|
||||
|
||||
ble_ll_iso_conn_free(&conn);
|
||||
}
|
||||
|
||||
TEST_SUITE(ble_ll_iso_test_suite) {
|
||||
ble_ll_iso_init();
|
||||
|
||||
test_ll_ist_brd_bv_01_c();
|
||||
|
||||
ble_ll_iso_reset();
|
||||
}
|
||||
@@ -26,6 +26,7 @@ TEST_SUITE_DECL(ble_ll_aa_test_suite);
|
||||
TEST_SUITE_DECL(ble_ll_crypto_test_suite);
|
||||
TEST_SUITE_DECL(ble_ll_csa2_test_suite);
|
||||
TEST_SUITE_DECL(ble_ll_isoal_test_suite);
|
||||
TEST_SUITE_DECL(ble_ll_iso_test_suite);
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
@@ -34,6 +35,7 @@ main(int argc, char **argv)
|
||||
ble_ll_crypto_test_suite();
|
||||
ble_ll_csa2_test_suite();
|
||||
ble_ll_isoal_test_suite();
|
||||
ble_ll_iso_test_suite();
|
||||
|
||||
return tu_any_failed;
|
||||
}
|
||||
|
||||
@@ -1647,6 +1647,11 @@ struct ble_hci_vs_set_scan_cfg_cp {
|
||||
#define BLE_HCI_PRIVACY_NETWORK (0)
|
||||
#define BLE_HCI_PRIVACY_DEVICE (1)
|
||||
|
||||
/* --- LE iso transmit test payload type options (OCF 0x0070) */
|
||||
#define BLE_HCI_PAYLOAD_TYPE_ZERO_LENGTH (0x00)
|
||||
#define BLE_HCI_PAYLOAD_TYPE_VARIABLE_LENGTH (0x01)
|
||||
#define BLE_HCI_PAYLOAD_TYPE_MAXIMUM_LENGTH (0x02)
|
||||
|
||||
/* --- LE set advertising coded PHY options (OCF 0x007F) */
|
||||
#define BLE_HCI_ADVERTISING_PHY_OPT_NO_PREF 0x0
|
||||
#define BLE_HCI_ADVERTISING_PHY_OPT_S2_PREF 0x1
|
||||
|
||||
Reference in New Issue
Block a user