bluetooth: controller: Implements Peripheral CIS Create Procedure
Implements PDU flow and unittest of CIS Create on Peripheral Hooks CIS Create into the controller and fixes a few minor things in ull to allow for running with NEW LLCP Also handles CONFIG based comilation of CIS Create Signed-off-by: Erik Brockhoff <erbr@oticon.com>
This commit is contained in:
parent
6cf357bd9d
commit
3fbfb6537e
23 changed files with 1640 additions and 12 deletions
|
@ -78,6 +78,12 @@ if(CONFIG_BT_LL_SW_SPLIT)
|
||||||
CONFIG_BT_CTLR_LE_ENC
|
CONFIG_BT_CTLR_LE_ENC
|
||||||
ll_sw/ull_llcp_enc.c
|
ll_sw/ull_llcp_enc.c
|
||||||
)
|
)
|
||||||
|
if (CONFIG_BT_CTLR_PERIPHERAL_ISO OR
|
||||||
|
CONFIG_BT_CTLR_CENTRAL_ISO)
|
||||||
|
zephyr_library_sources(
|
||||||
|
ll_sw/ull_llcp_cc.c
|
||||||
|
)
|
||||||
|
endif()
|
||||||
zephyr_library_sources(
|
zephyr_library_sources(
|
||||||
ll_sw/ull_tx_queue.c
|
ll_sw/ull_tx_queue.c
|
||||||
ll_sw/ull_llcp.c
|
ll_sw/ull_llcp.c
|
||||||
|
|
|
@ -27,6 +27,10 @@
|
||||||
#define ISO_INT_UNIT_US CONN_INT_UNIT_US
|
#define ISO_INT_UNIT_US CONN_INT_UNIT_US
|
||||||
#define PERIODIC_INT_UNIT_US 1250U
|
#define PERIODIC_INT_UNIT_US 1250U
|
||||||
|
|
||||||
|
/* Timeout for Host to accept/reject cis create request */
|
||||||
|
/* See BTCore5.3, 4.E.6.7 - Default value 0x1f40 * 625us */
|
||||||
|
#define DEFAULT_CONNECTION_ACCEPT_TIMEOUT_US (5 * USEC_PER_SEC)
|
||||||
|
|
||||||
/* Intervals after which connection or sync establishment is considered lost */
|
/* Intervals after which connection or sync establishment is considered lost */
|
||||||
#define CONN_ESTAB_COUNTDOWN 6U
|
#define CONN_ESTAB_COUNTDOWN 6U
|
||||||
|
|
||||||
|
|
|
@ -225,6 +225,7 @@ struct ll_conn_iso_stream *ll_conn_iso_stream_get_by_group(struct ll_conn_iso_gr
|
||||||
|
|
||||||
void ull_conn_iso_cis_established(struct ll_conn_iso_stream *cis)
|
void ull_conn_iso_cis_established(struct ll_conn_iso_stream *cis)
|
||||||
{
|
{
|
||||||
|
#if defined(CONFIG_BT_LL_SW_LLCP_LEGACY)
|
||||||
struct node_rx_conn_iso_estab *est;
|
struct node_rx_conn_iso_estab *est;
|
||||||
struct node_rx_pdu *node_rx;
|
struct node_rx_pdu *node_rx;
|
||||||
|
|
||||||
|
@ -245,6 +246,7 @@ void ull_conn_iso_cis_established(struct ll_conn_iso_stream *cis)
|
||||||
|
|
||||||
ll_rx_put(node_rx->hdr.link, node_rx);
|
ll_rx_put(node_rx->hdr.link, node_rx);
|
||||||
ll_rx_sched();
|
ll_rx_sched();
|
||||||
|
#endif /* defined(CONFIG_BT_LL_SW_LLCP_LEGACY) */
|
||||||
|
|
||||||
cis->established = 1;
|
cis->established = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -541,7 +541,7 @@ struct ll_conn {
|
||||||
uint16_t connect_expire;
|
uint16_t connect_expire;
|
||||||
uint16_t supervision_reload;
|
uint16_t supervision_reload;
|
||||||
uint16_t supervision_expire;
|
uint16_t supervision_expire;
|
||||||
|
uint32_t connect_accept_to;
|
||||||
|
|
||||||
#if defined(CONFIG_BT_CTLR_PHY)
|
#if defined(CONFIG_BT_CTLR_PHY)
|
||||||
uint8_t phy_pref_tx:3;
|
uint8_t phy_pref_tx:3;
|
||||||
|
|
|
@ -30,6 +30,10 @@
|
||||||
#include "lll_conn_iso.h"
|
#include "lll_conn_iso.h"
|
||||||
#include "lll_iso_tx.h"
|
#include "lll_iso_tx.h"
|
||||||
|
|
||||||
|
#if !defined(CONFIG_BT_LL_SW_LLCP_LEGACY)
|
||||||
|
#include "ull_tx_queue.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "isoal.h"
|
#include "isoal.h"
|
||||||
|
|
||||||
#include "ull_adv_types.h"
|
#include "ull_adv_types.h"
|
||||||
|
@ -44,6 +48,7 @@
|
||||||
#include "ull_sync_iso_internal.h"
|
#include "ull_sync_iso_internal.h"
|
||||||
#include "ull_conn_iso_internal.h"
|
#include "ull_conn_iso_internal.h"
|
||||||
#include "ull_conn_types.h"
|
#include "ull_conn_types.h"
|
||||||
|
#include "ull_llcp.h"
|
||||||
|
|
||||||
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
|
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
|
||||||
#define LOG_MODULE_NAME bt_ctlr_ull_iso
|
#define LOG_MODULE_NAME bt_ctlr_ull_iso
|
||||||
|
@ -248,9 +253,12 @@ uint8_t ll_setup_iso_path(uint16_t handle, uint8_t path_dir, uint8_t path_id,
|
||||||
* disallowed status.
|
* disallowed status.
|
||||||
*/
|
*/
|
||||||
#if defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
|
#if defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
|
||||||
|
#if defined(CONFIG_BT_LL_SW_LLCP_LEGACY)
|
||||||
const uint8_t cis_waiting = (conn->llcp_cis.state ==
|
const uint8_t cis_waiting = (conn->llcp_cis.state ==
|
||||||
LLCP_CIS_STATE_RSP_WAIT);
|
LLCP_CIS_STATE_RSP_WAIT);
|
||||||
|
#else
|
||||||
|
const uint8_t cis_waiting = ull_cp_cc_awaiting_reply(conn);
|
||||||
|
#endif
|
||||||
if (cis_waiting) {
|
if (cis_waiting) {
|
||||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -440,6 +440,11 @@ struct proc_ctx *llcp_create_remote_procedure(enum llcp_proc proc)
|
||||||
llcp_rp_comm_init_proc(ctx);
|
llcp_rp_comm_init_proc(ctx);
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_REQ */
|
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_REQ */
|
||||||
|
#if defined(CONFIG_BT_PERIPHERAL) && defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
|
||||||
|
case PROC_CIS_CREATE:
|
||||||
|
llcp_rp_cc_init_proc(ctx);
|
||||||
|
break;
|
||||||
|
#endif /* CONFIG_BT_PERIPHERAL && CONFIG_BT_CTLR_PERIPHERAL_ISO */
|
||||||
#if defined(CONFIG_BT_CTLR_CENTRAL_ISO) || defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
|
#if defined(CONFIG_BT_CTLR_CENTRAL_ISO) || defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
|
||||||
case PROC_CIS_TERMINATE:
|
case PROC_CIS_TERMINATE:
|
||||||
llcp_rp_comm_init_proc(ctx);
|
llcp_rp_comm_init_proc(ctx);
|
||||||
|
@ -1089,6 +1094,53 @@ void ull_cp_cte_req_set_disable(struct ll_conn *conn)
|
||||||
conn->llcp.cte_req.req_interval = 0U;
|
conn->llcp.cte_req.req_interval = 0U;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_REQ */
|
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_REQ */
|
||||||
|
#if defined(CONFIG_BT_PERIPHERAL) && defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
|
||||||
|
bool ull_cp_cc_awaiting_reply(struct ll_conn *conn)
|
||||||
|
{
|
||||||
|
struct proc_ctx *ctx;
|
||||||
|
|
||||||
|
ctx = llcp_rr_peek(conn);
|
||||||
|
if (ctx && ctx->proc == PROC_CIS_CREATE) {
|
||||||
|
return llcp_rp_cc_awaiting_reply(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t ull_cp_cc_ongoing_handle(struct ll_conn *conn)
|
||||||
|
{
|
||||||
|
struct proc_ctx *ctx;
|
||||||
|
|
||||||
|
ctx = llcp_rr_peek(conn);
|
||||||
|
if (ctx && ctx->proc == PROC_CIS_CREATE) {
|
||||||
|
return ctx->data.cis_create.cis_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ull_cp_cc_accept(struct ll_conn *conn)
|
||||||
|
{
|
||||||
|
struct proc_ctx *ctx;
|
||||||
|
|
||||||
|
ctx = llcp_rr_peek(conn);
|
||||||
|
if (ctx && ctx->proc == PROC_CIS_CREATE) {
|
||||||
|
llcp_rp_cc_accept(conn, ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ull_cp_cc_reject(struct ll_conn *conn, uint8_t error_code)
|
||||||
|
{
|
||||||
|
struct proc_ctx *ctx;
|
||||||
|
|
||||||
|
ctx = llcp_rr_peek(conn);
|
||||||
|
if (ctx && ctx->proc == PROC_CIS_CREATE) {
|
||||||
|
ctx->data.cis_create.error = error_code;
|
||||||
|
llcp_rp_cc_reject(conn, ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* defined(CONFIG_BT_PERIPHERAL) && defined(CONFIG_BT_CTLR_PERIPHERAL_ISO) */
|
||||||
|
|
||||||
static bool pdu_is_expected(struct pdu_data *pdu, struct proc_ctx *ctx)
|
static bool pdu_is_expected(struct pdu_data *pdu, struct proc_ctx *ctx)
|
||||||
{
|
{
|
||||||
|
|
|
@ -158,6 +158,27 @@ uint8_t ull_cp_terminate(struct ll_conn *conn, uint8_t error_code);
|
||||||
uint8_t ull_cp_cis_terminate(struct ll_conn *conn, struct ll_conn_iso_stream *cis,
|
uint8_t ull_cp_cis_terminate(struct ll_conn *conn, struct ll_conn_iso_stream *cis,
|
||||||
uint8_t error_code);
|
uint8_t error_code);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is ongoing create cis procedure expecting a reply?
|
||||||
|
*/
|
||||||
|
bool ull_cp_cc_awaiting_reply(struct ll_conn *conn);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get handle of ongoing create cis procedure.
|
||||||
|
* @return 0xFFFF if none
|
||||||
|
*/
|
||||||
|
uint16_t ull_cp_cc_ongoing_handle(struct ll_conn *conn);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Accept the remote device’s request to create cis.
|
||||||
|
*/
|
||||||
|
void ull_cp_cc_accept(struct ll_conn *conn);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Rejset the remote device’s request to create cis.
|
||||||
|
*/
|
||||||
|
void ull_cp_cc_reject(struct ll_conn *conn, uint8_t error_code);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initiate a Channel Map Update Procedure.
|
* @brief Initiate a Channel Map Update Procedure.
|
||||||
*/
|
*/
|
||||||
|
|
599
subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c
Normal file
599
subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c
Normal file
|
@ -0,0 +1,599 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 Demant
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr/types.h>
|
||||||
|
|
||||||
|
#include <bluetooth/hci.h>
|
||||||
|
#include <sys/byteorder.h>
|
||||||
|
#include <sys/slist.h>
|
||||||
|
#include <sys/util.h>
|
||||||
|
|
||||||
|
#include "hal/ecb.h"
|
||||||
|
#include "hal/ccm.h"
|
||||||
|
|
||||||
|
#include "util/util.h"
|
||||||
|
#include "util/mem.h"
|
||||||
|
#include "util/memq.h"
|
||||||
|
#include "util/dbuf.h"
|
||||||
|
|
||||||
|
#include "pdu.h"
|
||||||
|
#include "ll.h"
|
||||||
|
#include "ll_feat.h"
|
||||||
|
#include "ll_settings.h"
|
||||||
|
|
||||||
|
#include "lll.h"
|
||||||
|
#include "lll/lll_df_types.h"
|
||||||
|
#include "lll_conn.h"
|
||||||
|
#include "lll_conn_iso.h"
|
||||||
|
|
||||||
|
#include "ull_tx_queue.h"
|
||||||
|
|
||||||
|
#include "isoal.h"
|
||||||
|
#include "ull_iso_types.h"
|
||||||
|
#include "ull_conn_types.h"
|
||||||
|
#include "ull_conn_iso_types.h"
|
||||||
|
#include "ull_internal.h"
|
||||||
|
#include "ull_llcp.h"
|
||||||
|
#include "ull_llcp_internal.h"
|
||||||
|
#include "ull_llcp_features.h"
|
||||||
|
#include "ull_conn_internal.h"
|
||||||
|
|
||||||
|
#include "ull_iso_internal.h"
|
||||||
|
#include "ull_conn_iso_internal.h"
|
||||||
|
#include "ull_peripheral_iso_internal.h"
|
||||||
|
|
||||||
|
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
|
||||||
|
#define LOG_MODULE_NAME bt_ctlr_ull_llcp_cis
|
||||||
|
#include "common/log.h"
|
||||||
|
#include <soc.h>
|
||||||
|
#include "hal/debug.h"
|
||||||
|
|
||||||
|
static uint16_t cc_event_counter(struct ll_conn *conn)
|
||||||
|
{
|
||||||
|
struct lll_conn *lll;
|
||||||
|
uint16_t event_counter;
|
||||||
|
|
||||||
|
uint16_t lazy = conn->llcp.prep.lazy;
|
||||||
|
|
||||||
|
/**/
|
||||||
|
lll = &conn->lll;
|
||||||
|
|
||||||
|
/* Calculate current event counter */
|
||||||
|
event_counter = lll->event_counter + lll->latency_prepare + lazy;
|
||||||
|
|
||||||
|
return event_counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_PERIPHERAL)
|
||||||
|
/* LLCP Remote Procedure FSM states */
|
||||||
|
enum {
|
||||||
|
/* Establish Procedure */
|
||||||
|
RP_CC_STATE_IDLE,
|
||||||
|
RP_CC_STATE_WAIT_RX_CIS_REQ,
|
||||||
|
RP_CC_STATE_WAIT_NTF_CIS_CREATE,
|
||||||
|
RP_CC_STATE_WAIT_REPLY,
|
||||||
|
RP_CC_STATE_WAIT_TX_CIS_RSP,
|
||||||
|
RP_CC_STATE_WAIT_TX_REJECT_IND,
|
||||||
|
RP_CC_STATE_WAIT_RX_CIS_IND,
|
||||||
|
RP_CC_STATE_WAIT_INSTANT,
|
||||||
|
RP_CC_STATE_WAIT_CIS_ESTABLISHED,
|
||||||
|
RP_CC_STATE_WAIT_NTF,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* LLCP Remote Procedure FSM events */
|
||||||
|
enum {
|
||||||
|
/* Procedure prepared */
|
||||||
|
RP_CC_EVT_RUN,
|
||||||
|
|
||||||
|
/* Request received */
|
||||||
|
RP_CC_EVT_CIS_REQ,
|
||||||
|
|
||||||
|
/* Response received */
|
||||||
|
RP_CC_EVT_CIS_RSP,
|
||||||
|
|
||||||
|
/* Indication received */
|
||||||
|
RP_CC_EVT_CIS_IND,
|
||||||
|
|
||||||
|
/* Create request accept reply */
|
||||||
|
RP_CC_EVT_CIS_REQ_ACCEPT,
|
||||||
|
|
||||||
|
/* Create request decline reply */
|
||||||
|
RP_CC_EVT_CIS_REQ_REJECT,
|
||||||
|
|
||||||
|
/* Reject response received */
|
||||||
|
RP_CC_EVT_REJECT,
|
||||||
|
|
||||||
|
/* Unknown response received */
|
||||||
|
RP_CC_EVT_UNKNOWN,
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
* LLCP Remote Procedure FSM
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void llcp_rp_cc_tx_rsp(struct ll_conn *conn, struct proc_ctx *ctx)
|
||||||
|
{
|
||||||
|
struct node_tx *tx;
|
||||||
|
struct pdu_data *pdu;
|
||||||
|
|
||||||
|
/* Allocate tx node */
|
||||||
|
tx = llcp_tx_alloc(conn, ctx);
|
||||||
|
LL_ASSERT(tx);
|
||||||
|
|
||||||
|
pdu = (struct pdu_data *)tx->pdu;
|
||||||
|
|
||||||
|
llcp_pdu_encode_cis_rsp(ctx, pdu);
|
||||||
|
ctx->tx_opcode = pdu->llctrl.opcode;
|
||||||
|
|
||||||
|
/* Enqueue LL Control PDU towards LLL */
|
||||||
|
llcp_tx_enqueue(conn, tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void llcp_rp_cc_tx_reject(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t opcode)
|
||||||
|
{
|
||||||
|
struct node_tx *tx;
|
||||||
|
struct pdu_data *pdu;
|
||||||
|
|
||||||
|
/* Allocate tx node */
|
||||||
|
tx = llcp_tx_alloc(conn, ctx);
|
||||||
|
LL_ASSERT(tx);
|
||||||
|
|
||||||
|
pdu = (struct pdu_data *)tx->pdu;
|
||||||
|
|
||||||
|
/* Encode LL Control PDU */
|
||||||
|
llcp_pdu_encode_reject_ext_ind(pdu, opcode, ctx->data.cis_create.error);
|
||||||
|
ctx->tx_opcode = pdu->llctrl.opcode;
|
||||||
|
|
||||||
|
/* Enqueue LL Control PDU towards LLL */
|
||||||
|
llcp_tx_enqueue(conn, tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rp_cc_ntf_create(struct ll_conn *conn, struct proc_ctx *ctx)
|
||||||
|
{
|
||||||
|
struct node_rx_pdu *ntf;
|
||||||
|
struct node_rx_conn_iso_req *pdu;
|
||||||
|
|
||||||
|
/* Allocate ntf node */
|
||||||
|
ntf = llcp_ntf_alloc();
|
||||||
|
LL_ASSERT(ntf);
|
||||||
|
|
||||||
|
ntf->hdr.type = NODE_RX_TYPE_CIS_REQUEST;
|
||||||
|
ntf->hdr.handle = conn->lll.handle;
|
||||||
|
pdu = (struct node_rx_conn_iso_req *)ntf->pdu;
|
||||||
|
|
||||||
|
pdu->cig_id = ctx->data.cis_create.cig_id;
|
||||||
|
pdu->cis_id = ctx->data.cis_create.cis_id;
|
||||||
|
pdu->cis_handle = ctx->data.cis_create.cis_handle;
|
||||||
|
|
||||||
|
ctx->data.cis_create.host_request_to = 0U;
|
||||||
|
|
||||||
|
/* Enqueue notification towards LL */
|
||||||
|
ll_rx_put(ntf->hdr.link, ntf);
|
||||||
|
ll_rx_sched();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void rp_cc_ntf(struct ll_conn *conn, struct proc_ctx *ctx)
|
||||||
|
{
|
||||||
|
struct node_rx_pdu *ntf;
|
||||||
|
struct node_rx_conn_iso_estab *pdu;
|
||||||
|
|
||||||
|
/* Allocate ntf node */
|
||||||
|
ntf = llcp_ntf_alloc();
|
||||||
|
LL_ASSERT(ntf);
|
||||||
|
|
||||||
|
ntf->hdr.type = NODE_RX_TYPE_CIS_ESTABLISHED;
|
||||||
|
ntf->hdr.handle = conn->lll.handle;
|
||||||
|
ntf->hdr.rx_ftr.param = ll_conn_iso_stream_get(ctx->data.cis_create.cis_handle);
|
||||||
|
|
||||||
|
pdu = (struct node_rx_conn_iso_estab *)ntf->pdu;
|
||||||
|
|
||||||
|
pdu->cis_handle = ctx->data.cis_create.cis_handle;
|
||||||
|
pdu->status = ctx->data.cis_create.error;
|
||||||
|
|
||||||
|
/* Enqueue notification towards LL */
|
||||||
|
ll_rx_put(ntf->hdr.link, ntf);
|
||||||
|
ll_rx_sched();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rp_cc_complete(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param)
|
||||||
|
{
|
||||||
|
if (!llcp_ntf_alloc_is_available()) {
|
||||||
|
ctx->state = RP_CC_STATE_WAIT_NTF;
|
||||||
|
} else {
|
||||||
|
rp_cc_ntf(conn, ctx);
|
||||||
|
llcp_rr_complete(conn);
|
||||||
|
ctx->state = RP_CC_STATE_IDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rp_cc_send_cis_rsp(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
|
||||||
|
void *param)
|
||||||
|
{
|
||||||
|
if (llcp_rr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) {
|
||||||
|
ctx->state = RP_CC_STATE_WAIT_TX_CIS_RSP;
|
||||||
|
} else {
|
||||||
|
llcp_rp_cc_tx_rsp(conn, ctx);
|
||||||
|
|
||||||
|
/* Wait for the LL_CIS_IND */
|
||||||
|
ctx->rx_opcode = PDU_DATA_LLCTRL_TYPE_CIS_IND;
|
||||||
|
ctx->state = RP_CC_STATE_WAIT_RX_CIS_IND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rp_cc_send_create_ntf(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
|
||||||
|
void *param)
|
||||||
|
{
|
||||||
|
if (!llcp_ntf_alloc_is_available()) {
|
||||||
|
ctx->state = RP_CC_STATE_WAIT_NTF_CIS_CREATE;
|
||||||
|
} else {
|
||||||
|
rp_cc_ntf_create(conn, ctx);
|
||||||
|
ctx->state = RP_CC_STATE_WAIT_REPLY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rp_cc_send_reject_ind(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
|
||||||
|
void *param)
|
||||||
|
{
|
||||||
|
if (llcp_rr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) {
|
||||||
|
ctx->state = RP_CC_STATE_WAIT_TX_REJECT_IND;
|
||||||
|
} else {
|
||||||
|
llcp_rp_cc_tx_reject(conn, ctx, PDU_DATA_LLCTRL_TYPE_CIS_REQ);
|
||||||
|
|
||||||
|
if (ctx->data.cis_create.error == BT_HCI_ERR_CONN_ACCEPT_TIMEOUT) {
|
||||||
|
/* We reject due to an accept timeout, so we should generate NTF */
|
||||||
|
rp_cc_complete(conn, ctx, evt, param);
|
||||||
|
} else {
|
||||||
|
/* Otherwise we quietly complete the procedure */
|
||||||
|
llcp_rr_complete(conn);
|
||||||
|
ctx->state = RP_CC_STATE_IDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rp_cc_state_idle(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
|
||||||
|
void *param)
|
||||||
|
{
|
||||||
|
switch (evt) {
|
||||||
|
case RP_CC_EVT_RUN:
|
||||||
|
ctx->state = RP_CC_STATE_WAIT_RX_CIS_REQ;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Ignore other evts */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool phy_valid(uint8_t phy)
|
||||||
|
{
|
||||||
|
/* This is equivalent to:
|
||||||
|
* exactly one bit set, and no bit set is rfu's
|
||||||
|
*/
|
||||||
|
return (phy == PHY_1M || phy == PHY_2M || phy == PHY_CODED);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t rp_cc_check_phy(struct ll_conn *conn, struct proc_ctx *ctx,
|
||||||
|
struct pdu_data *pdu)
|
||||||
|
{
|
||||||
|
if (!phy_valid(pdu->llctrl.cis_req.c_phy) ||
|
||||||
|
!phy_valid(pdu->llctrl.cis_req.p_phy)) {
|
||||||
|
/* zero, more than one or any rfu bit selected in either phy */
|
||||||
|
return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_CTLR_PHY)
|
||||||
|
const uint8_t phys = pdu->llctrl.cis_req.p_phy | pdu->llctrl.cis_req.c_phy;
|
||||||
|
|
||||||
|
if (((phys & PHY_2M) && !feature_phy_2m(conn)) ||
|
||||||
|
((phys & PHY_CODED) && !feature_phy_coded(conn))) {
|
||||||
|
/* Unsupported phy selected */
|
||||||
|
return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return BT_HCI_ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool rp_cc_check_cis_established_lll(struct proc_ctx *ctx)
|
||||||
|
{
|
||||||
|
const struct ll_conn_iso_stream *cis =
|
||||||
|
ll_conn_iso_stream_get(ctx->data.cis_create.cis_handle);
|
||||||
|
|
||||||
|
return cis->established;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rp_cc_state_wait_rx_cis_req(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
|
||||||
|
void *param)
|
||||||
|
{
|
||||||
|
struct pdu_data *pdu = (struct pdu_data *)param;
|
||||||
|
|
||||||
|
switch (evt) {
|
||||||
|
case RP_CC_EVT_CIS_REQ:
|
||||||
|
/* Handle CIS request */
|
||||||
|
llcp_pdu_decode_cis_req(ctx, pdu);
|
||||||
|
|
||||||
|
/* Check PHY */
|
||||||
|
ctx->data.cis_create.error = rp_cc_check_phy(conn, ctx, pdu);
|
||||||
|
|
||||||
|
if (ctx->data.cis_create.error == BT_HCI_ERR_SUCCESS) {
|
||||||
|
ctx->data.cis_create.error =
|
||||||
|
ull_peripheral_iso_acquire(conn, &pdu->llctrl.cis_req,
|
||||||
|
&ctx->data.cis_create.cis_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx->data.cis_create.error == BT_HCI_ERR_SUCCESS) {
|
||||||
|
/* Now controller accepts, so go ask the host to accept or decline */
|
||||||
|
rp_cc_send_create_ntf(conn, ctx, evt, param);
|
||||||
|
} else {
|
||||||
|
/* Now controller rejects, right out */
|
||||||
|
rp_cc_send_reject_ind(conn, ctx, evt, param);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Ignore other evts */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rp_cc_state_wait_tx_cis_rsp(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
|
||||||
|
void *param)
|
||||||
|
{
|
||||||
|
switch (evt) {
|
||||||
|
case RP_CC_EVT_RUN:
|
||||||
|
rp_cc_send_cis_rsp(conn, ctx, evt, param);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Ignore other evts */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rp_cc_state_wait_tx_reject_ind(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
|
||||||
|
void *param)
|
||||||
|
{
|
||||||
|
switch (evt) {
|
||||||
|
case RP_CC_EVT_RUN:
|
||||||
|
rp_cc_send_reject_ind(conn, ctx, evt, param);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Ignore other evts */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rp_cc_state_wait_rx_cis_ind(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
|
||||||
|
void *param)
|
||||||
|
{
|
||||||
|
struct pdu_data *pdu = (struct pdu_data *)param;
|
||||||
|
|
||||||
|
switch (evt) {
|
||||||
|
case RP_CC_EVT_CIS_IND:
|
||||||
|
if (!ull_peripheral_iso_setup(&pdu->llctrl.cis_ind, ctx->data.cis_create.cig_id,
|
||||||
|
ctx->data.cis_create.cis_handle)) {
|
||||||
|
|
||||||
|
/* CIS has been setup, go wait for 'instant' before starting */
|
||||||
|
ctx->state = RP_CC_STATE_WAIT_INSTANT;
|
||||||
|
|
||||||
|
/* Fixme - Implement CIS Supervision timeout
|
||||||
|
* Spec:
|
||||||
|
* When establishing a CIS, the Peripheral shall start the CIS supervision
|
||||||
|
* timer at the start of the next CIS event after receiving the LL_CIS_IND.
|
||||||
|
* If the CIS supervision timer reaches 6 * ISO_Interval before the CIS is
|
||||||
|
* established, the CIS shall be considered lost.
|
||||||
|
*/
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* If we get to here the CIG_ID referred in req/acquire has become void/invalid */
|
||||||
|
/* This cannot happen unless the universe has started to deflate */
|
||||||
|
LL_ASSERT(0);
|
||||||
|
case RP_CC_EVT_REJECT:
|
||||||
|
/* Handle CIS creation rejection */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* Ignore other evts */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rp_cc_state_wait_ntf_cis_create(struct ll_conn *conn, struct proc_ctx *ctx,
|
||||||
|
uint8_t evt, void *param)
|
||||||
|
{
|
||||||
|
switch (evt) {
|
||||||
|
case RP_CC_EVT_RUN:
|
||||||
|
rp_cc_send_create_ntf(conn, ctx, evt, param);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Ignore other evts */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void rp_cc_state_wait_ntf(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
|
||||||
|
void *param)
|
||||||
|
{
|
||||||
|
switch (evt) {
|
||||||
|
case RP_CC_EVT_RUN:
|
||||||
|
rp_cc_complete(conn, ctx, evt, param);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Ignore other evts */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rp_cc_check_instant(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
|
||||||
|
void *param)
|
||||||
|
{
|
||||||
|
uint16_t start_event_count;
|
||||||
|
|
||||||
|
start_event_count = ctx->data.cis_create.conn_event_count;
|
||||||
|
|
||||||
|
if (is_instant_reached_or_passed(start_event_count,
|
||||||
|
cc_event_counter(conn))) {
|
||||||
|
/* Start CIS */
|
||||||
|
ull_peripheral_iso_start(conn, conn->llcp.prep.ticks_at_expire,
|
||||||
|
ctx->data.cis_create.cis_handle);
|
||||||
|
|
||||||
|
/* Now we can wait for CIS to become established */
|
||||||
|
ctx->state = RP_CC_STATE_WAIT_CIS_ESTABLISHED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rp_cc_state_wait_reply(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
|
||||||
|
void *param)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (evt) {
|
||||||
|
case RP_CC_EVT_CIS_REQ_ACCEPT:
|
||||||
|
/* Continue procedure in next prepare run */
|
||||||
|
ctx->state = RP_CC_STATE_WAIT_TX_CIS_RSP;
|
||||||
|
break;
|
||||||
|
case RP_CC_EVT_RUN:
|
||||||
|
/* Update 'time' and check for timeout on the Reply */
|
||||||
|
ctx->data.cis_create.host_request_to += (conn->lll.interval * CONN_INT_UNIT_US);
|
||||||
|
if (ctx->data.cis_create.host_request_to < conn->connect_accept_to) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Reject 'reason/error' */
|
||||||
|
ctx->data.cis_create.error = BT_HCI_ERR_CONN_ACCEPT_TIMEOUT;
|
||||||
|
/* If timeout is hit, fall through and reject */
|
||||||
|
case RP_CC_EVT_CIS_REQ_REJECT:
|
||||||
|
/* Continue procedure in next prepare run */
|
||||||
|
ctx->state = RP_CC_STATE_WAIT_TX_REJECT_IND;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Ignore other evts */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void rp_cc_state_wait_instant(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
|
||||||
|
void *param)
|
||||||
|
{
|
||||||
|
switch (evt) {
|
||||||
|
case RP_CC_EVT_RUN:
|
||||||
|
rp_cc_check_instant(conn, ctx, evt, param);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Ignore other evts */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void rp_cc_state_wait_cis_established(struct ll_conn *conn, struct proc_ctx *ctx,
|
||||||
|
uint8_t evt, void *param)
|
||||||
|
{
|
||||||
|
switch (evt) {
|
||||||
|
case RP_CC_EVT_RUN:
|
||||||
|
/* Check for CIS state */
|
||||||
|
if (rp_cc_check_cis_established_lll(ctx)) {
|
||||||
|
/* CIS was established, so let's got ahead and complete procedure */
|
||||||
|
rp_cc_complete(conn, ctx, evt, param);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Ignore other evts */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void rp_cc_execute_fsm(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param)
|
||||||
|
{
|
||||||
|
switch (ctx->state) {
|
||||||
|
/* Create Procedure */
|
||||||
|
case RP_CC_STATE_IDLE:
|
||||||
|
rp_cc_state_idle(conn, ctx, evt, param);
|
||||||
|
break;
|
||||||
|
case RP_CC_STATE_WAIT_RX_CIS_REQ:
|
||||||
|
rp_cc_state_wait_rx_cis_req(conn, ctx, evt, param);
|
||||||
|
break;
|
||||||
|
case RP_CC_STATE_WAIT_NTF_CIS_CREATE:
|
||||||
|
rp_cc_state_wait_ntf_cis_create(conn, ctx, evt, param);
|
||||||
|
break;
|
||||||
|
case RP_CC_STATE_WAIT_TX_REJECT_IND:
|
||||||
|
rp_cc_state_wait_tx_reject_ind(conn, ctx, evt, param);
|
||||||
|
break;
|
||||||
|
case RP_CC_STATE_WAIT_TX_CIS_RSP:
|
||||||
|
rp_cc_state_wait_tx_cis_rsp(conn, ctx, evt, param);
|
||||||
|
break;
|
||||||
|
case RP_CC_STATE_WAIT_REPLY:
|
||||||
|
rp_cc_state_wait_reply(conn, ctx, evt, param);
|
||||||
|
break;
|
||||||
|
case RP_CC_STATE_WAIT_RX_CIS_IND:
|
||||||
|
rp_cc_state_wait_rx_cis_ind(conn, ctx, evt, param);
|
||||||
|
break;
|
||||||
|
case RP_CC_STATE_WAIT_INSTANT:
|
||||||
|
rp_cc_state_wait_instant(conn, ctx, evt, param);
|
||||||
|
break;
|
||||||
|
case RP_CC_STATE_WAIT_CIS_ESTABLISHED:
|
||||||
|
rp_cc_state_wait_cis_established(conn, ctx, evt, param);
|
||||||
|
break;
|
||||||
|
case RP_CC_STATE_WAIT_NTF:
|
||||||
|
rp_cc_state_wait_ntf(conn, ctx, evt, param);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Unknown state */
|
||||||
|
LL_ASSERT(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void llcp_rp_cc_rx(struct ll_conn *conn, struct proc_ctx *ctx, struct node_rx_pdu *rx)
|
||||||
|
{
|
||||||
|
struct pdu_data *pdu = (struct pdu_data *)rx->pdu;
|
||||||
|
|
||||||
|
switch (pdu->llctrl.opcode) {
|
||||||
|
case PDU_DATA_LLCTRL_TYPE_CIS_REQ:
|
||||||
|
rp_cc_execute_fsm(conn, ctx, RP_CC_EVT_CIS_REQ, pdu);
|
||||||
|
break;
|
||||||
|
case PDU_DATA_LLCTRL_TYPE_CIS_IND:
|
||||||
|
rp_cc_execute_fsm(conn, ctx, RP_CC_EVT_CIS_IND, pdu);
|
||||||
|
break;
|
||||||
|
case PDU_DATA_LLCTRL_TYPE_REJECT_IND:
|
||||||
|
case PDU_DATA_LLCTRL_TYPE_REJECT_EXT_IND:
|
||||||
|
rp_cc_execute_fsm(conn, ctx, RP_CC_EVT_REJECT, pdu);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Unknown opcode */
|
||||||
|
LL_ASSERT(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void llcp_rp_cc_init_proc(struct proc_ctx *ctx)
|
||||||
|
{
|
||||||
|
switch (ctx->proc) {
|
||||||
|
case PROC_CIS_CREATE:
|
||||||
|
ctx->state = RP_CC_STATE_IDLE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LL_ASSERT(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool llcp_rp_cc_awaiting_reply(struct proc_ctx *ctx)
|
||||||
|
{
|
||||||
|
return (ctx->state == RP_CC_STATE_WAIT_REPLY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void llcp_rp_cc_accept(struct ll_conn *conn, struct proc_ctx *ctx)
|
||||||
|
{
|
||||||
|
rp_cc_execute_fsm(conn, ctx, RP_CC_EVT_CIS_REQ_ACCEPT, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void llcp_rp_cc_reject(struct ll_conn *conn, struct proc_ctx *ctx)
|
||||||
|
{
|
||||||
|
rp_cc_execute_fsm(conn, ctx, RP_CC_EVT_CIS_REQ_REJECT, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void llcp_rp_cc_run(struct ll_conn *conn, struct proc_ctx *ctx, void *param)
|
||||||
|
{
|
||||||
|
rp_cc_execute_fsm(conn, ctx, RP_CC_EVT_RUN, param);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BT_PERIPHERAL */
|
|
@ -885,7 +885,6 @@ static void rp_comm_terminate(struct ll_conn *conn, struct proc_ctx *ctx)
|
||||||
#if defined(CONFIG_BT_CTLR_CENTRAL_ISO) || defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
|
#if defined(CONFIG_BT_CTLR_CENTRAL_ISO) || defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
|
||||||
static void rp_comm_stop_cis(struct proc_ctx *ctx)
|
static void rp_comm_stop_cis(struct proc_ctx *ctx)
|
||||||
{
|
{
|
||||||
|
|
||||||
llcp_cis_stop_by_id(ctx->data.cis_term.cig_id, ctx->data.cis_term.cis_id,
|
llcp_cis_stop_by_id(ctx->data.cis_term.cig_id, ctx->data.cis_term.cis_id,
|
||||||
ctx->data.cis_term.error_code);
|
ctx->data.cis_term.error_code);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ enum llcp_proc {
|
||||||
PROC_CHAN_MAP_UPDATE,
|
PROC_CHAN_MAP_UPDATE,
|
||||||
PROC_DATA_LENGTH_UPDATE,
|
PROC_DATA_LENGTH_UPDATE,
|
||||||
PROC_CTE_REQ,
|
PROC_CTE_REQ,
|
||||||
|
PROC_CIS_CREATE,
|
||||||
PROC_CIS_TERMINATE,
|
PROC_CIS_TERMINATE,
|
||||||
/* A helper enum entry, to use in pause procedure context */
|
/* A helper enum entry, to use in pause procedure context */
|
||||||
PROC_NONE = 0x0,
|
PROC_NONE = 0x0,
|
||||||
|
@ -249,6 +250,40 @@ struct proc_ctx {
|
||||||
uint8_t min_cte_len;
|
uint8_t min_cte_len;
|
||||||
} cte_remote_req;
|
} cte_remote_req;
|
||||||
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
|
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
|
||||||
|
struct {
|
||||||
|
uint8_t error;
|
||||||
|
uint16_t cis_handle;
|
||||||
|
uint8_t cig_id;
|
||||||
|
uint8_t cis_id;
|
||||||
|
uint16_t conn_event_count;
|
||||||
|
uint32_t cis_offset_min;
|
||||||
|
uint32_t cis_offset_max;
|
||||||
|
#if defined(CONFIG_BT_PERIPHERAL)
|
||||||
|
uint32_t host_request_to;
|
||||||
|
#endif /* defined(CONFIG_BT_PERIPHERAL) */
|
||||||
|
#if defined(CONFIG_BT_CENTRAL)
|
||||||
|
/* In case of a cis_req data decoded by ull_peripheral_iso_acquire, so
|
||||||
|
* only need to store info in local create (ie central enabled device)
|
||||||
|
*/
|
||||||
|
uint8_t c_phy;
|
||||||
|
uint8_t p_phy;
|
||||||
|
uint16_t c_max_sdu;
|
||||||
|
uint16_t p_max_sdu;
|
||||||
|
uint8_t framed;
|
||||||
|
uint32_t c_sdu_interval;
|
||||||
|
uint32_t p_sdu_interval;
|
||||||
|
uint8_t nse;
|
||||||
|
uint16_t c_max_pdu;
|
||||||
|
uint16_t p_max_pdu;
|
||||||
|
uint32_t sub_interval;
|
||||||
|
uint8_t p_bn;
|
||||||
|
uint8_t c_bn;
|
||||||
|
uint8_t c_ft;
|
||||||
|
uint8_t p_ft;
|
||||||
|
uint16_t iso_interval;
|
||||||
|
#endif /* defined(CONFIG_BT_CENTRAL) */
|
||||||
|
} cis_create;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint8_t cig_id;
|
uint8_t cig_id;
|
||||||
uint8_t cis_id;
|
uint8_t cis_id;
|
||||||
|
@ -642,6 +677,19 @@ void llcp_pdu_decode_cte_req(struct proc_ctx *ctx, struct pdu_data *pdu);
|
||||||
void llcp_pdu_encode_cte_rsp(const struct proc_ctx *ctx, struct pdu_data *pdu);
|
void llcp_pdu_encode_cte_rsp(const struct proc_ctx *ctx, struct pdu_data *pdu);
|
||||||
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
|
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
|
||||||
|
|
||||||
|
void llcp_lp_cc_init_proc(struct proc_ctx *ctx);
|
||||||
|
void llcp_lp_cc_rx(struct ll_conn *conn, struct proc_ctx *ctx, struct node_rx_pdu *rx);
|
||||||
|
void llcp_lp_cc_run(struct ll_conn *conn, struct proc_ctx *ctx, void *param);
|
||||||
|
|
||||||
|
void llcp_rp_cc_init_proc(struct proc_ctx *ctx);
|
||||||
|
void llcp_rp_cc_rx(struct ll_conn *conn, struct proc_ctx *ctx, struct node_rx_pdu *rx);
|
||||||
|
void llcp_rp_cc_run(struct ll_conn *conn, struct proc_ctx *ctx, void *param);
|
||||||
|
bool llcp_rp_cc_awaiting_reply(struct proc_ctx *ctx);
|
||||||
|
void llcp_rp_cc_accept(struct ll_conn *conn, struct proc_ctx *ctx);
|
||||||
|
void llcp_rp_cc_reject(struct ll_conn *conn, struct proc_ctx *ctx);
|
||||||
|
|
||||||
|
void llcp_pdu_decode_cis_req(struct proc_ctx *ctx, struct pdu_data *pdu);
|
||||||
|
void llcp_pdu_encode_cis_rsp(struct proc_ctx *ctx, struct pdu_data *pdu);
|
||||||
void llcp_pdu_encode_cis_terminate_ind(struct proc_ctx *ctx, struct pdu_data *pdu);
|
void llcp_pdu_encode_cis_terminate_ind(struct proc_ctx *ctx, struct pdu_data *pdu);
|
||||||
void llcp_pdu_decode_cis_terminate_ind(struct proc_ctx *ctx, struct pdu_data *pdu);
|
void llcp_pdu_decode_cis_terminate_ind(struct proc_ctx *ctx, struct pdu_data *pdu);
|
||||||
|
|
||||||
|
|
|
@ -835,6 +835,51 @@ void llcp_pdu_encode_cte_rsp(const struct proc_ctx *ctx, struct pdu_data *pdu)
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
|
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
|
||||||
|
void llcp_pdu_decode_cis_req(struct proc_ctx *ctx, struct pdu_data *pdu)
|
||||||
|
{
|
||||||
|
ctx->data.cis_create.cig_id = pdu->llctrl.cis_req.cig_id;
|
||||||
|
ctx->data.cis_create.cis_id = pdu->llctrl.cis_req.cis_id;
|
||||||
|
ctx->data.cis_create.cis_offset_min = sys_get_le24(pdu->llctrl.cis_req.cis_offset_min);
|
||||||
|
ctx->data.cis_create.cis_offset_max = sys_get_le24(pdu->llctrl.cis_req.cis_offset_max);
|
||||||
|
ctx->data.cis_create.conn_event_count =
|
||||||
|
sys_le16_to_cpu(pdu->llctrl.cis_req.conn_event_count);
|
||||||
|
/* The remainder of the req is decoded by ull_peripheral_iso_acquire, so
|
||||||
|
* no need to do it here too
|
||||||
|
ctx->data.cis_create.c_phy = pdu->llctrl.cis_req.c_phy;
|
||||||
|
ctx->data.cis_create.p_phy = pdu->llctrl.cis_req.p_phy;
|
||||||
|
ctx->data.cis_create.c_max_sdu = pdu->llctrl.cis_req.c_max_sdu;
|
||||||
|
ctx->data.cis_create.p_max_sdu = pdu->llctrl.cis_req.p_max_sdu;
|
||||||
|
ctx->data.cis_create.framed = pdu->llctrl.cis_req.framed;
|
||||||
|
ctx->data.cis_create.c_sdu_interval = sys_get_le24(pdu->llctrl.cis_req.c_sdu_interval);
|
||||||
|
ctx->data.cis_create.p_sdu_interval = sys_get_le24(pdu->llctrl.cis_req.p_sdu_interval);
|
||||||
|
ctx->data.cis_create.nse = pdu->llctrl.cis_req.nse;
|
||||||
|
ctx->data.cis_create.c_max_pdu = sys_le16_to_cpu(pdu->llctrl.cis_req.c_max_pdu);
|
||||||
|
ctx->data.cis_create.p_max_pdu = sys_le16_to_cpu(pdu->llctrl.cis_req.p_max_pdu);
|
||||||
|
ctx->data.cis_create.sub_interval = sys_get_le24(pdu->llctrl.cis_req.sub_interval);
|
||||||
|
ctx->data.cis_create.p_bn = pdu->llctrl.cis_req.p_bn;
|
||||||
|
ctx->data.cis_create.c_bn = pdu->llctrl.cis_req.c_bn;
|
||||||
|
ctx->data.cis_create.c_ft = pdu->llctrl.cis_req.c_ft;
|
||||||
|
ctx->data.cis_create.p_ft = pdu->llctrl.cis_req.p_ft;
|
||||||
|
ctx->data.cis_create.iso_interval = sys_le16_to_cpu(pdu->llctrl.cis_req.iso_interval);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void llcp_pdu_encode_cis_rsp(struct proc_ctx *ctx, struct pdu_data *pdu)
|
||||||
|
{
|
||||||
|
struct pdu_data_llctrl_cis_rsp *p;
|
||||||
|
|
||||||
|
pdu->ll_id = PDU_DATA_LLID_CTRL;
|
||||||
|
pdu->len =
|
||||||
|
offsetof(struct pdu_data_llctrl, cis_rsp) + sizeof(struct pdu_data_llctrl_cis_rsp);
|
||||||
|
pdu->llctrl.opcode = PDU_DATA_LLCTRL_TYPE_CIS_RSP;
|
||||||
|
|
||||||
|
p = &pdu->llctrl.cis_rsp;
|
||||||
|
sys_put_le24(ctx->data.cis_create.cis_offset_max, p->cis_offset_max);
|
||||||
|
sys_put_le24(ctx->data.cis_create.cis_offset_min, p->cis_offset_min);
|
||||||
|
p->conn_event_count = sys_cpu_to_le16(ctx->data.cis_create.conn_event_count);
|
||||||
|
}
|
||||||
|
#endif /* defined(CONFIG_BT_CTLR_PERIPHERAL_ISO) */
|
||||||
#if defined(CONFIG_BT_CTLR_CENTRAL_ISO) || defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
|
#if defined(CONFIG_BT_CTLR_CENTRAL_ISO) || defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
|
||||||
void llcp_pdu_encode_cis_terminate_ind(struct proc_ctx *ctx, struct pdu_data *pdu)
|
void llcp_pdu_encode_cis_terminate_ind(struct proc_ctx *ctx, struct pdu_data *pdu)
|
||||||
{
|
{
|
||||||
|
|
|
@ -93,6 +93,7 @@ static bool proc_with_instant(struct proc_ctx *ctx)
|
||||||
case PROC_DATA_LENGTH_UPDATE:
|
case PROC_DATA_LENGTH_UPDATE:
|
||||||
case PROC_CTE_REQ:
|
case PROC_CTE_REQ:
|
||||||
case PROC_CIS_TERMINATE:
|
case PROC_CIS_TERMINATE:
|
||||||
|
case PROC_CIS_CREATE:
|
||||||
return 0U;
|
return 0U;
|
||||||
case PROC_PHY_UPDATE:
|
case PROC_PHY_UPDATE:
|
||||||
case PROC_CONN_UPDATE:
|
case PROC_CONN_UPDATE:
|
||||||
|
@ -267,6 +268,11 @@ void llcp_rr_rx(struct ll_conn *conn, struct proc_ctx *ctx, struct node_rx_pdu *
|
||||||
llcp_rp_comm_rx(conn, ctx, rx);
|
llcp_rp_comm_rx(conn, ctx, rx);
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
|
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
|
||||||
|
#if defined(CONFIG_BT_PERIPHERAL) && defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
|
||||||
|
case PROC_CIS_CREATE:
|
||||||
|
llcp_rp_cc_rx(conn, ctx, rx);
|
||||||
|
break;
|
||||||
|
#endif /* CONFIG_BT_PERIPHERAL && CONFIG_BT_CTLR_PERIPHERAL_ISO */
|
||||||
#if defined(CONFIG_BT_CTLR_CENTRAL_ISO) || defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
|
#if defined(CONFIG_BT_CTLR_CENTRAL_ISO) || defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
|
||||||
case PROC_CIS_TERMINATE:
|
case PROC_CIS_TERMINATE:
|
||||||
llcp_rp_comm_rx(conn, ctx, rx);
|
llcp_rp_comm_rx(conn, ctx, rx);
|
||||||
|
@ -362,6 +368,11 @@ static void rr_act_run(struct ll_conn *conn)
|
||||||
llcp_rp_comm_run(conn, ctx, NULL);
|
llcp_rp_comm_run(conn, ctx, NULL);
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
|
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
|
||||||
|
#if defined(CONFIG_BT_PERIPHERAL) && defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
|
||||||
|
case PROC_CIS_CREATE:
|
||||||
|
llcp_rp_cc_run(conn, ctx, NULL);
|
||||||
|
break;
|
||||||
|
#endif /* CONFIG_BT_PERIPHERAL && CONFIG_BT_CTLR_PERIPHERAL_ISO */
|
||||||
#if defined(CONFIG_BT_CTLR_CENTRAL_ISO) || defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
|
#if defined(CONFIG_BT_CTLR_CENTRAL_ISO) || defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
|
||||||
case PROC_CIS_TERMINATE:
|
case PROC_CIS_TERMINATE:
|
||||||
llcp_rp_comm_run(conn, ctx, NULL);
|
llcp_rp_comm_run(conn, ctx, NULL);
|
||||||
|
@ -796,6 +807,9 @@ static const struct proc_role new_proc_lut[] = {
|
||||||
#if defined(CONFIG_BT_CTLR_CENTRAL_ISO) || defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
|
#if defined(CONFIG_BT_CTLR_CENTRAL_ISO) || defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
|
||||||
[PDU_DATA_LLCTRL_TYPE_CIS_TERMINATE_IND] = { PROC_CIS_TERMINATE, ACCEPT_ROLE_BOTH },
|
[PDU_DATA_LLCTRL_TYPE_CIS_TERMINATE_IND] = { PROC_CIS_TERMINATE, ACCEPT_ROLE_BOTH },
|
||||||
#endif /* CONFIG_BT_CTLR_CENTRAL_ISO || CONFIG_BT_CTLR_PERIPHERAL_ISO */
|
#endif /* CONFIG_BT_CTLR_CENTRAL_ISO || CONFIG_BT_CTLR_PERIPHERAL_ISO */
|
||||||
|
#if defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
|
||||||
|
[PDU_DATA_LLCTRL_TYPE_CIS_REQ] = { PROC_CIS_CREATE, ACCEPT_ROLE_PERIPHERAL },
|
||||||
|
#endif /* CONFIG_BT_CTLR_CENTRAL_ISO */
|
||||||
};
|
};
|
||||||
|
|
||||||
void llcp_rr_new(struct ll_conn *conn, struct node_rx_pdu *rx, bool valid_pdu)
|
void llcp_rr_new(struct ll_conn *conn, struct node_rx_pdu *rx, bool valid_pdu)
|
||||||
|
|
|
@ -218,6 +218,9 @@ void ull_periph_setup(struct node_rx_hdr *rx, struct node_rx_ftr *ftr,
|
||||||
ull_cp_prt_reload_set(conn, conn_interval_us);
|
ull_cp_prt_reload_set(conn, conn_interval_us);
|
||||||
#endif /* CONFIG_BT_LL_SW_LLCP_LEGACY */
|
#endif /* CONFIG_BT_LL_SW_LLCP_LEGACY */
|
||||||
|
|
||||||
|
#if (!defined(CONFIG_BT_LL_SW_LLCP_LEGACY))
|
||||||
|
conn->connect_accept_to = DEFAULT_CONNECTION_ACCEPT_TIMEOUT_US;
|
||||||
|
#endif /* !defined(CONFIG_BT_LL_SW_LLCP_LEGACY) */
|
||||||
#if defined(CONFIG_BT_CTLR_LE_PING)
|
#if defined(CONFIG_BT_CTLR_LE_PING)
|
||||||
/* APTO in no. of connection events */
|
/* APTO in no. of connection events */
|
||||||
conn->apto_reload = RADIO_CONN_EVENTS((30 * 1000 * 1000),
|
conn->apto_reload = RADIO_CONN_EVENTS((30 * 1000 * 1000),
|
||||||
|
|
|
@ -26,9 +26,15 @@
|
||||||
#include "isoal.h"
|
#include "isoal.h"
|
||||||
#include "ull_iso_types.h"
|
#include "ull_iso_types.h"
|
||||||
|
|
||||||
|
#if !defined(CONFIG_BT_LL_SW_LLCP_LEGACY)
|
||||||
|
#include "ull_tx_queue.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "ull_conn_types.h"
|
#include "ull_conn_types.h"
|
||||||
#include "ull_conn_iso_types.h"
|
#include "ull_conn_iso_types.h"
|
||||||
#include "ull_internal.h"
|
#include "ull_internal.h"
|
||||||
|
#include "ull_llcp.h"
|
||||||
|
#include "ull_llcp_internal.h"
|
||||||
|
|
||||||
#include "ull_conn_internal.h"
|
#include "ull_conn_internal.h"
|
||||||
#include "ull_conn_iso_internal.h"
|
#include "ull_conn_iso_internal.h"
|
||||||
|
@ -39,14 +45,19 @@
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
#include "hal/debug.h"
|
#include "hal/debug.h"
|
||||||
|
|
||||||
uint8_t ll_cis_accept(uint16_t handle)
|
static struct ll_conn *ll_cis_get_acl_awaiting_reply(uint16_t handle, uint8_t *error)
|
||||||
{
|
{
|
||||||
struct ll_conn *acl_conn = NULL;
|
struct ll_conn *acl_conn = NULL;
|
||||||
|
|
||||||
for (int h = 0; h < CONFIG_BT_MAX_CONN; h++) {
|
for (int h = 0; h < CONFIG_BT_MAX_CONN; h++) {
|
||||||
struct ll_conn *conn = ll_conn_get(h);
|
struct ll_conn *conn = ll_conn_get(h);
|
||||||
|
#if defined(CONFIG_BT_LL_SW_LLCP_LEGACY)
|
||||||
|
uint16_t cis_handle = conn->llcp_cis.cis_handle;
|
||||||
|
#else
|
||||||
|
uint16_t cis_handle = ull_cp_cc_ongoing_handle(conn);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (handle == conn->llcp_cis.cis_handle) {
|
if (handle == cis_handle) {
|
||||||
/* ACL connection found */
|
/* ACL connection found */
|
||||||
acl_conn = conn;
|
acl_conn = conn;
|
||||||
break;
|
break;
|
||||||
|
@ -55,25 +66,62 @@ uint8_t ll_cis_accept(uint16_t handle)
|
||||||
|
|
||||||
if (!acl_conn) {
|
if (!acl_conn) {
|
||||||
BT_ERR("No connection found for handle %u", handle);
|
BT_ERR("No connection found for handle %u", handle);
|
||||||
return BT_HCI_ERR_UNKNOWN_CONN_ID;
|
*error = BT_HCI_ERR_UNKNOWN_CONN_ID;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (acl_conn->lll.role == BT_CONN_ROLE_CENTRAL) {
|
if (acl_conn->lll.role == BT_CONN_ROLE_CENTRAL) {
|
||||||
BT_ERR("Not allowed for central");
|
BT_ERR("Not allowed for central");
|
||||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
*error = BT_HCI_ERR_CMD_DISALLOWED;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
acl_conn->llcp_cis.req++;
|
#if defined(CONFIG_BT_LL_SW_LLCP_LEGACY)
|
||||||
|
if (acl_conn->llcp_cis.state != LLCP_CIS_STATE_RSP_WAIT) {
|
||||||
|
#else
|
||||||
|
if (!ull_cp_cc_awaiting_reply(acl_conn)) {
|
||||||
|
#endif
|
||||||
|
BT_ERR("Not allowed in current procedure state");
|
||||||
|
*error = BT_HCI_ERR_CMD_DISALLOWED;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return acl_conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ll_cis_accept(uint16_t handle)
|
||||||
|
{
|
||||||
|
uint8_t status = BT_HCI_ERR_SUCCESS;
|
||||||
|
struct ll_conn *acl_conn = ll_cis_get_acl_awaiting_reply(handle, &status);
|
||||||
|
|
||||||
|
if (acl_conn) {
|
||||||
|
/* Accept request */
|
||||||
|
#if defined(CONFIG_BT_LL_SW_LLCP_LEGACY)
|
||||||
|
acl_conn->llcp_cis.req++;
|
||||||
|
#else
|
||||||
|
ull_cp_cc_accept(acl_conn);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t ll_cis_reject(uint16_t handle, uint8_t reason)
|
uint8_t ll_cis_reject(uint16_t handle, uint8_t reason)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(handle);
|
uint8_t status = BT_HCI_ERR_SUCCESS;
|
||||||
ARG_UNUSED(reason);
|
|
||||||
|
|
||||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
#if defined(CONFIG_BT_LL_SW_LLCP_LEGACY)
|
||||||
|
status = BT_HCI_ERR_CMD_DISALLOWED;
|
||||||
|
#else
|
||||||
|
struct ll_conn *acl_conn = ll_cis_reply_ok(handle, &status);
|
||||||
|
|
||||||
|
if (acl_conn) {
|
||||||
|
/* Accept request */
|
||||||
|
ull_cp_cc_reject(acl_conn, reason);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ull_peripheral_iso_init(void)
|
int ull_peripheral_iso_init(void)
|
||||||
|
|
|
@ -29,6 +29,7 @@ FILE(GLOB ll_sw_sources
|
||||||
${ZEPHYR_BASE}/subsys/bluetooth/controller/ll_sw/ull_llcp_enc.c
|
${ZEPHYR_BASE}/subsys/bluetooth/controller/ll_sw/ull_llcp_enc.c
|
||||||
${ZEPHYR_BASE}/subsys/bluetooth/controller/ll_sw/ull_llcp_conn_upd.c
|
${ZEPHYR_BASE}/subsys/bluetooth/controller/ll_sw/ull_llcp_conn_upd.c
|
||||||
${ZEPHYR_BASE}/subsys/bluetooth/controller/ll_sw/ull_llcp_chmu.c
|
${ZEPHYR_BASE}/subsys/bluetooth/controller/ll_sw/ull_llcp_chmu.c
|
||||||
|
${ZEPHYR_BASE}/subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c
|
||||||
${ZEPHYR_BASE}/subsys/bluetooth/controller/ll_sw/ull_llcp.c
|
${ZEPHYR_BASE}/subsys/bluetooth/controller/ll_sw/ull_llcp.c
|
||||||
${ZEPHYR_BASE}/subsys/bluetooth/controller/ll_sw/ull_conn.c
|
${ZEPHYR_BASE}/subsys/bluetooth/controller/ll_sw/ull_conn.c
|
||||||
${ZEPHYR_BASE}/subsys/bluetooth/controller/ll_sw/ll_addr.c
|
${ZEPHYR_BASE}/subsys/bluetooth/controller/ll_sw/ll_addr.c
|
||||||
|
@ -46,6 +47,7 @@ FILE(GLOB mock_sources
|
||||||
${ZEPHYR_BASE}/tests/bluetooth/controller/mock_ctrl/src/ull.c
|
${ZEPHYR_BASE}/tests/bluetooth/controller/mock_ctrl/src/ull.c
|
||||||
${ZEPHYR_BASE}/tests/bluetooth/controller/mock_ctrl/src/ull_conn_iso.c
|
${ZEPHYR_BASE}/tests/bluetooth/controller/mock_ctrl/src/ull_conn_iso.c
|
||||||
${ZEPHYR_BASE}/tests/bluetooth/controller/mock_ctrl/src/ull_peripheral.c
|
${ZEPHYR_BASE}/tests/bluetooth/controller/mock_ctrl/src/ull_peripheral.c
|
||||||
|
${ZEPHYR_BASE}/tests/bluetooth/controller/mock_ctrl/src/ull_peripheral_iso.c
|
||||||
${ZEPHYR_BASE}/tests/bluetooth/controller/mock_ctrl/src/ull_central.c
|
${ZEPHYR_BASE}/tests/bluetooth/controller/mock_ctrl/src/ull_central.c
|
||||||
${ZEPHYR_BASE}/tests/bluetooth/controller/mock_ctrl/src/ull_scan.c
|
${ZEPHYR_BASE}/tests/bluetooth/controller/mock_ctrl/src/ull_scan.c
|
||||||
${ZEPHYR_BASE}/tests/bluetooth/controller/mock_ctrl/src/lll_clock.c
|
${ZEPHYR_BASE}/tests/bluetooth/controller/mock_ctrl/src/lll_clock.c
|
||||||
|
|
|
@ -53,6 +53,10 @@ void helper_pdu_encode_cte_rsp(struct pdu_data *pdu, void *param);
|
||||||
void helper_node_encode_cte_rsp(struct node_rx_pdu *rx, void *param);
|
void helper_node_encode_cte_rsp(struct node_rx_pdu *rx, void *param);
|
||||||
|
|
||||||
void helper_pdu_encode_zero(struct pdu_data *pdu, void *param);
|
void helper_pdu_encode_zero(struct pdu_data *pdu, void *param);
|
||||||
|
|
||||||
|
void helper_pdu_encode_cis_req(struct pdu_data *pdu, void *param);
|
||||||
|
void helper_pdu_encode_cis_rsp(struct pdu_data *pdu, void *param);
|
||||||
|
void helper_pdu_encode_cis_ind(struct pdu_data *pdu, void *param);
|
||||||
void helper_pdu_encode_cis_terminate_ind(struct pdu_data *pdu, void *param);
|
void helper_pdu_encode_cis_terminate_ind(struct pdu_data *pdu, void *param);
|
||||||
|
|
||||||
void helper_pdu_verify_ping_req(const char *file, uint32_t line, struct pdu_data *pdu, void *param);
|
void helper_pdu_verify_ping_req(const char *file, uint32_t line, struct pdu_data *pdu, void *param);
|
||||||
|
@ -135,6 +139,13 @@ void helper_node_verify_cte_rsp(const char *file, uint32_t line, struct node_rx_
|
||||||
void helper_pdu_ntf_verify_cte_rsp(const char *file, uint32_t line, struct pdu_data *pdu,
|
void helper_pdu_ntf_verify_cte_rsp(const char *file, uint32_t line, struct pdu_data *pdu,
|
||||||
void *param);
|
void *param);
|
||||||
|
|
||||||
|
void helper_node_verify_cis_request(const char *file, uint32_t line, struct node_rx_pdu *rx,
|
||||||
|
void *param);
|
||||||
|
void helper_node_verify_cis_established(const char *file, uint32_t line, struct node_rx_pdu *rx,
|
||||||
|
void *param);
|
||||||
|
void helper_pdu_verify_cis_req(const char *file, uint32_t line, struct pdu_data *pdu, void *param);
|
||||||
|
void helper_pdu_verify_cis_rsp(const char *file, uint32_t line, struct pdu_data *pdu, void *param);
|
||||||
|
void helper_pdu_verify_cis_ind(const char *file, uint32_t line, struct pdu_data *pdu, void *param);
|
||||||
void helper_pdu_verify_cis_terminate_ind(const char *file, uint32_t line, struct pdu_data *pdu,
|
void helper_pdu_verify_cis_terminate_ind(const char *file, uint32_t line, struct pdu_data *pdu,
|
||||||
void *param);
|
void *param);
|
||||||
|
|
||||||
|
@ -167,6 +178,9 @@ enum helper_pdu_opcode {
|
||||||
LL_LENGTH_RSP,
|
LL_LENGTH_RSP,
|
||||||
LL_CTE_REQ,
|
LL_CTE_REQ,
|
||||||
LL_CTE_RSP,
|
LL_CTE_RSP,
|
||||||
|
LL_CIS_REQ,
|
||||||
|
LL_CIS_RSP,
|
||||||
|
LL_CIS_IND,
|
||||||
LL_CIS_TERMINATE_IND,
|
LL_CIS_TERMINATE_IND,
|
||||||
LL_ZERO,
|
LL_ZERO,
|
||||||
};
|
};
|
||||||
|
@ -176,6 +190,9 @@ enum helper_node_opcode {
|
||||||
NODE_CONN_UPDATE,
|
NODE_CONN_UPDATE,
|
||||||
NODE_ENC_REFRESH,
|
NODE_ENC_REFRESH,
|
||||||
NODE_CTE_RSP,
|
NODE_CTE_RSP,
|
||||||
|
NODE_CIS_REQUEST,
|
||||||
|
NODE_CIS_ESTABLISHED,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void(helper_pdu_encode_func_t)(struct pdu_data *data, void *param);
|
typedef void(helper_pdu_encode_func_t)(struct pdu_data *data, void *param);
|
||||||
|
|
|
@ -407,6 +407,66 @@ void helper_node_encode_cte_rsp(struct node_rx_pdu *rx, void *param)
|
||||||
rx->hdr.rx_ftr.iq_report = (struct cte_conn_iq_report *)param;
|
rx->hdr.rx_ftr.iq_report = (struct cte_conn_iq_report *)param;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void helper_pdu_encode_cis_req(struct pdu_data *pdu, void *param)
|
||||||
|
{
|
||||||
|
struct pdu_data_llctrl_cis_req *p = param;
|
||||||
|
|
||||||
|
pdu->ll_id = PDU_DATA_LLID_CTRL;
|
||||||
|
pdu->len = offsetof(struct pdu_data_llctrl, cis_req) +
|
||||||
|
sizeof(struct pdu_data_llctrl_cis_req);
|
||||||
|
pdu->llctrl.opcode = PDU_DATA_LLCTRL_TYPE_CIS_REQ;
|
||||||
|
|
||||||
|
pdu->llctrl.cis_req.cig_id = p->cig_id;
|
||||||
|
pdu->llctrl.cis_req.cis_id = p->cis_id;
|
||||||
|
pdu->llctrl.cis_req.c_phy = p->c_phy;
|
||||||
|
pdu->llctrl.cis_req.p_phy = p->p_phy;
|
||||||
|
pdu->llctrl.cis_req.c_max_pdu = p->c_max_pdu;
|
||||||
|
pdu->llctrl.cis_req.p_max_pdu = p->p_max_pdu;
|
||||||
|
pdu->llctrl.cis_req.nse = p->nse;
|
||||||
|
pdu->llctrl.cis_req.p_bn = p->p_bn;
|
||||||
|
pdu->llctrl.cis_req.c_bn = p->c_bn;
|
||||||
|
pdu->llctrl.cis_req.c_ft = p->c_ft;
|
||||||
|
pdu->llctrl.cis_req.p_ft = p->p_ft;
|
||||||
|
pdu->llctrl.cis_req.iso_interval = p->iso_interval;
|
||||||
|
pdu->llctrl.cis_req.conn_event_count = p->conn_event_count;
|
||||||
|
memcpy(pdu->llctrl.cis_req.c_max_sdu_packed, p->c_max_sdu_packed,
|
||||||
|
sizeof(p->c_max_sdu_packed));
|
||||||
|
memcpy(pdu->llctrl.cis_req.p_max_sdu, p->p_max_sdu, sizeof(p->p_max_sdu));
|
||||||
|
memcpy(pdu->llctrl.cis_req.c_sdu_interval, p->c_sdu_interval, sizeof(p->c_sdu_interval));
|
||||||
|
memcpy(pdu->llctrl.cis_req.p_sdu_interval, p->p_sdu_interval, sizeof(p->p_sdu_interval));
|
||||||
|
memcpy(pdu->llctrl.cis_req.sub_interval, p->sub_interval, sizeof(p->sub_interval));
|
||||||
|
memcpy(pdu->llctrl.cis_req.cis_offset_min, p->cis_offset_min, sizeof(p->cis_offset_min));
|
||||||
|
memcpy(pdu->llctrl.cis_req.cis_offset_max, p->cis_offset_max, sizeof(p->cis_offset_max));
|
||||||
|
}
|
||||||
|
|
||||||
|
void helper_pdu_encode_cis_rsp(struct pdu_data *pdu, void *param)
|
||||||
|
{
|
||||||
|
struct pdu_data_llctrl_cis_rsp *p = param;
|
||||||
|
|
||||||
|
pdu->ll_id = PDU_DATA_LLID_CTRL;
|
||||||
|
pdu->len = offsetof(struct pdu_data_llctrl, cis_rsp) +
|
||||||
|
sizeof(struct pdu_data_llctrl_cis_rsp);
|
||||||
|
pdu->llctrl.opcode = PDU_DATA_LLCTRL_TYPE_CIS_RSP;
|
||||||
|
memcpy(pdu->llctrl.cis_rsp.cis_offset_min, p->cis_offset_min, sizeof(p->cis_offset_min));
|
||||||
|
memcpy(pdu->llctrl.cis_rsp.cis_offset_max, p->cis_offset_max, sizeof(p->cis_offset_max));
|
||||||
|
pdu->llctrl.cis_rsp.conn_event_count = p->conn_event_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void helper_pdu_encode_cis_ind(struct pdu_data *pdu, void *param)
|
||||||
|
{
|
||||||
|
struct pdu_data_llctrl_cis_ind *p = param;
|
||||||
|
|
||||||
|
pdu->ll_id = PDU_DATA_LLID_CTRL;
|
||||||
|
pdu->len = offsetof(struct pdu_data_llctrl, cis_ind) +
|
||||||
|
sizeof(struct pdu_data_llctrl_cis_ind);
|
||||||
|
pdu->llctrl.opcode = PDU_DATA_LLCTRL_TYPE_CIS_IND;
|
||||||
|
memcpy(pdu->llctrl.cis_ind.aa, p->aa, sizeof(p->aa));
|
||||||
|
memcpy(pdu->llctrl.cis_ind.cis_offset, p->cis_offset, sizeof(p->cis_offset));
|
||||||
|
memcpy(pdu->llctrl.cis_ind.cig_sync_delay, p->cig_sync_delay, sizeof(p->cig_sync_delay));
|
||||||
|
memcpy(pdu->llctrl.cis_ind.cis_sync_delay, p->cis_sync_delay, sizeof(p->cis_sync_delay));
|
||||||
|
pdu->llctrl.cis_ind.conn_event_count = p->conn_event_count;
|
||||||
|
}
|
||||||
|
|
||||||
void helper_pdu_encode_cis_terminate_ind(struct pdu_data *pdu, void *param)
|
void helper_pdu_encode_cis_terminate_ind(struct pdu_data *pdu, void *param)
|
||||||
{
|
{
|
||||||
struct pdu_data_llctrl_cis_terminate_ind *p = param;
|
struct pdu_data_llctrl_cis_terminate_ind *p = param;
|
||||||
|
@ -983,6 +1043,144 @@ void helper_pdu_ntf_verify_cte_rsp(const char *file, uint32_t line, struct pdu_d
|
||||||
"Not a LL_CTE_RSP. Called at %s:%d\n", file, line);
|
"Not a LL_CTE_RSP. Called at %s:%d\n", file, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void helper_node_verify_cis_request(const char *file, uint32_t line, struct node_rx_pdu *rx,
|
||||||
|
void *param)
|
||||||
|
{
|
||||||
|
struct node_rx_conn_iso_req *p = (struct node_rx_conn_iso_req *)param;
|
||||||
|
struct node_rx_conn_iso_req *pdu = (struct node_rx_conn_iso_req *)rx->pdu;
|
||||||
|
|
||||||
|
zassert_equal(rx->hdr.type, NODE_RX_TYPE_CIS_REQUEST,
|
||||||
|
"Not a CIS_REQUEST node.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_equal(p->cig_id, pdu->cig_id,
|
||||||
|
"cig_id mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_equal(p->cis_handle, pdu->cis_handle,
|
||||||
|
"cis_handle mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_equal(p->cis_id, pdu->cis_id,
|
||||||
|
"cis_id mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void helper_node_verify_cis_established(const char *file, uint32_t line, struct node_rx_pdu *rx,
|
||||||
|
void *param)
|
||||||
|
{
|
||||||
|
struct node_rx_conn_iso_estab *p = (struct node_rx_conn_iso_estab *)param;
|
||||||
|
struct node_rx_conn_iso_estab *pdu = (struct node_rx_conn_iso_estab *)rx->pdu;
|
||||||
|
|
||||||
|
zassert_equal(rx->hdr.type, NODE_RX_TYPE_CIS_ESTABLISHED,
|
||||||
|
"Not a CIS_ESTABLISHED node.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_equal(p->status, pdu->status,
|
||||||
|
"status mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_equal(p->cis_handle, pdu->cis_handle,
|
||||||
|
"cis_handle mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void helper_pdu_verify_cis_req(const char *file, uint32_t line, struct pdu_data *pdu, void *param)
|
||||||
|
{
|
||||||
|
struct pdu_data_llctrl_cis_req *p = param;
|
||||||
|
|
||||||
|
pdu->ll_id = PDU_DATA_LLID_CTRL;
|
||||||
|
pdu->len = offsetof(struct pdu_data_llctrl, cis_req) +
|
||||||
|
sizeof(struct pdu_data_llctrl_cis_req);
|
||||||
|
pdu->llctrl.opcode = PDU_DATA_LLCTRL_TYPE_CIS_REQ;
|
||||||
|
|
||||||
|
zassert_equal(pdu->llctrl.cis_req.cig_id, p->cig_id,
|
||||||
|
"cig_id mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_equal(pdu->llctrl.cis_req.cis_id, p->cis_id,
|
||||||
|
"cis_id mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_equal(pdu->llctrl.cis_req.c_phy, p->c_phy,
|
||||||
|
"c_phy mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_equal(pdu->llctrl.cis_req.p_phy, p->p_phy,
|
||||||
|
"p_phy mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_equal(pdu->llctrl.cis_req.c_max_pdu, p->c_max_pdu,
|
||||||
|
"c_max_pdu mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_equal(pdu->llctrl.cis_req.p_max_pdu, p->p_max_pdu,
|
||||||
|
"p_max_pdu mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_equal(pdu->llctrl.cis_req.nse, p->nse,
|
||||||
|
"nse mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_equal(pdu->llctrl.cis_req.p_bn, p->p_bn,
|
||||||
|
"p_bn mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_equal(pdu->llctrl.cis_req.c_bn, p->c_bn,
|
||||||
|
"c_bn mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_equal(pdu->llctrl.cis_req.c_ft, p->c_ft,
|
||||||
|
"c_ft mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_equal(pdu->llctrl.cis_req.p_ft, p->p_ft,
|
||||||
|
"p_ft mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_equal(pdu->llctrl.cis_req.iso_interval, p->iso_interval,
|
||||||
|
"iso_interval mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_equal(pdu->llctrl.cis_req.conn_event_count, p->conn_event_count,
|
||||||
|
"conn_event_count mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_mem_equal(pdu->llctrl.cis_req.c_max_sdu_packed, p->c_max_sdu_packed,
|
||||||
|
sizeof(p->c_max_sdu_packed),
|
||||||
|
"c_max_sdu_packed mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_mem_equal(pdu->llctrl.cis_req.p_max_sdu, p->p_max_sdu,
|
||||||
|
sizeof(p->p_max_sdu),
|
||||||
|
"p_max_sdu mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_mem_equal(pdu->llctrl.cis_req.c_sdu_interval, p->c_sdu_interval,
|
||||||
|
sizeof(p->c_sdu_interval),
|
||||||
|
"c_sdu_interval mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_mem_equal(pdu->llctrl.cis_req.p_sdu_interval, p->p_sdu_interval,
|
||||||
|
sizeof(p->p_sdu_interval),
|
||||||
|
"p_sdu_interval mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_mem_equal(pdu->llctrl.cis_req.sub_interval, p->sub_interval,
|
||||||
|
sizeof(p->sub_interval),
|
||||||
|
"sub_interval mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_mem_equal(pdu->llctrl.cis_req.cis_offset_min, p->cis_offset_min,
|
||||||
|
sizeof(p->cis_offset_min),
|
||||||
|
"cis_offset_min mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_mem_equal(pdu->llctrl.cis_req.cis_offset_max, p->cis_offset_max,
|
||||||
|
sizeof(p->cis_offset_max),
|
||||||
|
"cis_offset_max mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void helper_pdu_verify_cis_rsp(const char *file, uint32_t line, struct pdu_data *pdu, void *param)
|
||||||
|
{
|
||||||
|
struct pdu_data_llctrl_cis_rsp *p = param;
|
||||||
|
|
||||||
|
zassert_equal(pdu->ll_id, PDU_DATA_LLID_CTRL, "Not a Control PDU.\nCalled at %s:%d\n", file,
|
||||||
|
line);
|
||||||
|
zassert_equal(pdu->len,
|
||||||
|
offsetof(struct pdu_data_llctrl, cis_rsp) +
|
||||||
|
sizeof(struct pdu_data_llctrl_cis_rsp),
|
||||||
|
"Wrong length.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_equal(pdu->llctrl.opcode, PDU_DATA_LLCTRL_TYPE_CIS_RSP,
|
||||||
|
"Not a LL_CIS_RSP.\nCalled at %s:%d\n", file, line);
|
||||||
|
|
||||||
|
zassert_mem_equal(pdu->llctrl.cis_rsp.cis_offset_min, p->cis_offset_min,
|
||||||
|
sizeof(p->cis_offset_min),
|
||||||
|
"cis_offset_min mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_mem_equal(pdu->llctrl.cis_rsp.cis_offset_max, p->cis_offset_max,
|
||||||
|
sizeof(p->cis_offset_max),
|
||||||
|
"cis_offset_max mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_equal(pdu->llctrl.cis_rsp.conn_event_count, p->conn_event_count,
|
||||||
|
"conn_event_count mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void helper_pdu_verify_cis_ind(const char *file, uint32_t line, struct pdu_data *pdu, void *param)
|
||||||
|
{
|
||||||
|
struct pdu_data_llctrl_cis_ind *p = param;
|
||||||
|
|
||||||
|
zassert_equal(pdu->ll_id, PDU_DATA_LLID_CTRL, "Not a Control PDU.\nCalled at %s:%d\n", file,
|
||||||
|
line);
|
||||||
|
zassert_equal(pdu->len,
|
||||||
|
offsetof(struct pdu_data_llctrl, cis_ind) +
|
||||||
|
sizeof(struct pdu_data_llctrl_cis_ind),
|
||||||
|
"Wrong length.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_equal(pdu->llctrl.opcode, PDU_DATA_LLCTRL_TYPE_CIS_IND,
|
||||||
|
"Not a LL_CIS_IND.\nCalled at %s:%d\n", file, line);
|
||||||
|
|
||||||
|
zassert_mem_equal(pdu->llctrl.cis_ind.aa, p->aa, sizeof(p->aa),
|
||||||
|
"aa mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_mem_equal(pdu->llctrl.cis_ind.cis_offset, p->cis_offset, sizeof(p->cis_offset),
|
||||||
|
"cis_offset mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_mem_equal(pdu->llctrl.cis_ind.cig_sync_delay, p->cig_sync_delay,
|
||||||
|
sizeof(p->cig_sync_delay),
|
||||||
|
"cig_sync_delay mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
zassert_mem_equal(pdu->llctrl.cis_ind.cis_sync_delay, p->cis_sync_delay,
|
||||||
|
sizeof(p->cis_sync_delay),
|
||||||
|
"cis_sync_delay mismatch.\nCalled at %s:%d\n", file, line);
|
||||||
|
|
||||||
|
pdu->llctrl.cis_ind.conn_event_count = p->conn_event_count;
|
||||||
|
}
|
||||||
|
|
||||||
void helper_pdu_verify_cis_terminate_ind(const char *file, uint32_t line, struct pdu_data *pdu,
|
void helper_pdu_verify_cis_terminate_ind(const char *file, uint32_t line, struct pdu_data *pdu,
|
||||||
void *param)
|
void *param)
|
||||||
{
|
{
|
||||||
|
|
|
@ -87,6 +87,9 @@ helper_pdu_encode_func_t *const helper_pdu_encode[] = {
|
||||||
[LL_LENGTH_RSP] = helper_pdu_encode_length_rsp,
|
[LL_LENGTH_RSP] = helper_pdu_encode_length_rsp,
|
||||||
[LL_CTE_REQ] = helper_pdu_encode_cte_req,
|
[LL_CTE_REQ] = helper_pdu_encode_cte_req,
|
||||||
[LL_CTE_RSP] = helper_pdu_encode_cte_rsp,
|
[LL_CTE_RSP] = helper_pdu_encode_cte_rsp,
|
||||||
|
[LL_CIS_REQ] = helper_pdu_encode_cis_req,
|
||||||
|
[LL_CIS_RSP] = helper_pdu_encode_cis_rsp,
|
||||||
|
[LL_CIS_IND] = helper_pdu_encode_cis_ind,
|
||||||
[LL_CIS_TERMINATE_IND] = helper_pdu_encode_cis_terminate_ind,
|
[LL_CIS_TERMINATE_IND] = helper_pdu_encode_cis_terminate_ind,
|
||||||
[LL_ZERO] = helper_pdu_encode_zero,
|
[LL_ZERO] = helper_pdu_encode_zero,
|
||||||
};
|
};
|
||||||
|
@ -120,6 +123,9 @@ helper_pdu_verify_func_t *const helper_pdu_verify[] = {
|
||||||
[LL_LENGTH_RSP] = helper_pdu_verify_length_rsp,
|
[LL_LENGTH_RSP] = helper_pdu_verify_length_rsp,
|
||||||
[LL_CTE_REQ] = helper_pdu_verify_cte_req,
|
[LL_CTE_REQ] = helper_pdu_verify_cte_req,
|
||||||
[LL_CTE_RSP] = helper_pdu_verify_cte_rsp,
|
[LL_CTE_RSP] = helper_pdu_verify_cte_rsp,
|
||||||
|
[LL_CIS_REQ] = helper_pdu_verify_cis_req,
|
||||||
|
[LL_CIS_RSP] = helper_pdu_verify_cis_rsp,
|
||||||
|
[LL_CIS_IND] = helper_pdu_verify_cis_ind,
|
||||||
[LL_CIS_TERMINATE_IND] = helper_pdu_verify_cis_terminate_ind,
|
[LL_CIS_TERMINATE_IND] = helper_pdu_verify_cis_terminate_ind,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -151,6 +157,9 @@ helper_pdu_ntf_verify_func_t *const helper_pdu_ntf_verify[] = {
|
||||||
[LL_CTE_REQ] = NULL,
|
[LL_CTE_REQ] = NULL,
|
||||||
[LL_CTE_RSP] = helper_pdu_ntf_verify_cte_rsp,
|
[LL_CTE_RSP] = helper_pdu_ntf_verify_cte_rsp,
|
||||||
[LL_CTE_RSP] = NULL,
|
[LL_CTE_RSP] = NULL,
|
||||||
|
[LL_CIS_REQ] = NULL,
|
||||||
|
[LL_CIS_RSP] = NULL,
|
||||||
|
[LL_CIS_IND] = NULL,
|
||||||
[LL_CIS_TERMINATE_IND] = NULL,
|
[LL_CIS_TERMINATE_IND] = NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -179,6 +188,9 @@ helper_node_encode_func_t *const helper_node_encode[] = {
|
||||||
[LL_CHAN_MAP_UPDATE_IND] = NULL,
|
[LL_CHAN_MAP_UPDATE_IND] = NULL,
|
||||||
[LL_CTE_REQ] = NULL,
|
[LL_CTE_REQ] = NULL,
|
||||||
[LL_CTE_RSP] = helper_node_encode_cte_rsp,
|
[LL_CTE_RSP] = helper_node_encode_cte_rsp,
|
||||||
|
[LL_CIS_REQ] = NULL,
|
||||||
|
[LL_CIS_RSP] = NULL,
|
||||||
|
[LL_CIS_IND] = NULL,
|
||||||
[LL_CIS_TERMINATE_IND] = NULL,
|
[LL_CIS_TERMINATE_IND] = NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -187,6 +199,8 @@ helper_node_verify_func_t *const helper_node_verify[] = {
|
||||||
[NODE_CONN_UPDATE] = helper_node_verify_conn_update,
|
[NODE_CONN_UPDATE] = helper_node_verify_conn_update,
|
||||||
[NODE_ENC_REFRESH] = helper_node_verify_enc_refresh,
|
[NODE_ENC_REFRESH] = helper_node_verify_enc_refresh,
|
||||||
[NODE_CTE_RSP] = helper_node_verify_cte_rsp,
|
[NODE_CTE_RSP] = helper_node_verify_cte_rsp,
|
||||||
|
[NODE_CIS_REQUEST] = helper_node_verify_cis_request,
|
||||||
|
[NODE_CIS_ESTABLISHED] = helper_node_verify_cis_established,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
16
tests/bluetooth/controller/ctrl_cis_create/CMakeLists.txt
Normal file
16
tests/bluetooth/controller/ctrl_cis_create/CMakeLists.txt
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.13.1)
|
||||||
|
|
||||||
|
if (NOT BOARD STREQUAL unit_testing)
|
||||||
|
message(FATAL_ERROR "This project can only be used with '-DBOARD=unit_testing'.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
FILE(GLOB SOURCES
|
||||||
|
src/*.c
|
||||||
|
)
|
||||||
|
|
||||||
|
project(bluetooth_ull_llcp_cis_create)
|
||||||
|
find_package(ZephyrUnittest HINTS $ENV{ZEPHYR_BASE})
|
||||||
|
include(${ZEPHYR_BASE}/tests/bluetooth/controller/common/defaults_cmake.txt)
|
||||||
|
target_sources(testbinary PRIVATE ${ll_sw_sources} ${mock_sources} ${common_sources})
|
468
tests/bluetooth/controller/ctrl_cis_create/src/main.c
Normal file
468
tests/bluetooth/controller/ctrl_cis_create/src/main.c
Normal file
|
@ -0,0 +1,468 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 Demant
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr/types.h>
|
||||||
|
#include <ztest.h>
|
||||||
|
#include "kconfig.h"
|
||||||
|
|
||||||
|
#include <bluetooth/hci.h>
|
||||||
|
#include <sys/byteorder.h>
|
||||||
|
#include <sys/slist.h>
|
||||||
|
#include <sys/util.h>
|
||||||
|
#include "hal/ccm.h"
|
||||||
|
|
||||||
|
#include "util/util.h"
|
||||||
|
#include "util/mem.h"
|
||||||
|
#include "util/memq.h"
|
||||||
|
#include "util/dbuf.h"
|
||||||
|
|
||||||
|
#include "pdu.h"
|
||||||
|
#include "ll.h"
|
||||||
|
#include "ll_settings.h"
|
||||||
|
|
||||||
|
#include "lll.h"
|
||||||
|
#include "lll_df_types.h"
|
||||||
|
#include "lll_conn_iso.h"
|
||||||
|
#include "lll_conn.h"
|
||||||
|
|
||||||
|
#include "ull_tx_queue.h"
|
||||||
|
|
||||||
|
#include "isoal.h"
|
||||||
|
#include "ull_iso_types.h"
|
||||||
|
#include "ull_conn_types.h"
|
||||||
|
#include "ull_conn_iso_types.h"
|
||||||
|
#include "ull_llcp.h"
|
||||||
|
#include "ull_conn_internal.h"
|
||||||
|
#include "ull_llcp_internal.h"
|
||||||
|
|
||||||
|
#include "helper_pdu.h"
|
||||||
|
#include "helper_util.h"
|
||||||
|
|
||||||
|
struct ll_conn conn;
|
||||||
|
|
||||||
|
static void setup(void)
|
||||||
|
{
|
||||||
|
test_setup(&conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_instant_reached(struct ll_conn *conn, uint16_t instant)
|
||||||
|
{
|
||||||
|
return ((event_counter(conn) - instant) & 0xFFFF) <= 0x7FFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct pdu_data_llctrl_cis_req remote_cis_req = {
|
||||||
|
.cig_id = 0x01,
|
||||||
|
.cis_id = 0x02,
|
||||||
|
.c_phy = 0x01,
|
||||||
|
.p_phy = 0x01,
|
||||||
|
.c_max_sdu_packed = { 0, 160},
|
||||||
|
.p_max_sdu = { 0, 160},
|
||||||
|
.c_max_pdu = 160,
|
||||||
|
.p_max_pdu = 160,
|
||||||
|
.nse = 2,
|
||||||
|
.p_bn = 1,
|
||||||
|
.c_bn = 1,
|
||||||
|
.c_ft = 1,
|
||||||
|
.p_ft = 1,
|
||||||
|
.iso_interval = 6,
|
||||||
|
.conn_event_count = 12,
|
||||||
|
.c_sdu_interval = { 0, 0, 0},
|
||||||
|
.p_sdu_interval = { 0, 0, 0},
|
||||||
|
.sub_interval = { 0, 0, 0},
|
||||||
|
.cis_offset_min = { 0, 0, 0},
|
||||||
|
.cis_offset_max = { 0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct pdu_data_llctrl_cis_ind remote_cis_ind = {
|
||||||
|
.aa = { 0, 0, 0, 0},
|
||||||
|
.cig_sync_delay = { 0, 0, 0},
|
||||||
|
.cis_offset = { 0, 0, 0},
|
||||||
|
.cis_sync_delay = { 0, 0, 0},
|
||||||
|
.conn_event_count = 12
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ERROR_CODE 0x17
|
||||||
|
/*
|
||||||
|
* Central-initiated CIS Create procedure.
|
||||||
|
* Central requests CIS, peripheral Host rejects.
|
||||||
|
*
|
||||||
|
* +-----+ +-------+ +-----+
|
||||||
|
* | UT | | LL_S | | LT |
|
||||||
|
* +-----+ +-------+ +-----+
|
||||||
|
* | | |
|
||||||
|
* | | LL_CIS_REQ |
|
||||||
|
* | |<--------------------------|
|
||||||
|
* | | |
|
||||||
|
* | LE CIS Request | |
|
||||||
|
* |<--------------------------| |
|
||||||
|
* | LE CIS Request | |
|
||||||
|
* | Accept | |
|
||||||
|
* |-------------------------->| |
|
||||||
|
* | | |
|
||||||
|
* | | LL_CIS_RSP |
|
||||||
|
* | |-------------------------->|
|
||||||
|
* | | |
|
||||||
|
* | | LL_CIS_IND |
|
||||||
|
* | |<--------------------------|
|
||||||
|
* | | |
|
||||||
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
* | | |
|
||||||
|
* | LE CIS ESTABLISHED | |
|
||||||
|
* |<--------------------------| |
|
||||||
|
*/
|
||||||
|
static void test_cc_create_periph_rem_host_accept(void)
|
||||||
|
{
|
||||||
|
struct node_tx *tx;
|
||||||
|
struct node_rx_pdu *ntf;
|
||||||
|
struct node_rx_conn_iso_req cis_req = {
|
||||||
|
.cig_id = 0x01,
|
||||||
|
.cis_handle = 0x00,
|
||||||
|
.cis_id = 0x02
|
||||||
|
};
|
||||||
|
struct pdu_data_llctrl_cis_rsp local_cis_rsp = {
|
||||||
|
.cis_offset_max = { 0, 0, 0},
|
||||||
|
.cis_offset_min = { 0, 0, 0},
|
||||||
|
.conn_event_count = 12
|
||||||
|
};
|
||||||
|
struct node_rx_conn_iso_estab cis_estab = {
|
||||||
|
.cis_handle = 0x00,
|
||||||
|
.status = 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Role */
|
||||||
|
test_set_role(&conn, BT_HCI_ROLE_PERIPHERAL);
|
||||||
|
|
||||||
|
/* Connect */
|
||||||
|
ull_cp_state_set(&conn, ULL_CP_CONNECTED);
|
||||||
|
|
||||||
|
/* Prepare */
|
||||||
|
event_prepare(&conn);
|
||||||
|
|
||||||
|
/* Rx */
|
||||||
|
lt_tx(LL_CIS_REQ, &conn, &remote_cis_req);
|
||||||
|
|
||||||
|
/* Done */
|
||||||
|
event_done(&conn);
|
||||||
|
|
||||||
|
/* There should be excactly one host notification */
|
||||||
|
ut_rx_node(NODE_CIS_REQUEST, &ntf, &cis_req);
|
||||||
|
ut_rx_q_is_empty();
|
||||||
|
|
||||||
|
/* Release Ntf */
|
||||||
|
ull_cp_release_ntf(ntf);
|
||||||
|
|
||||||
|
/* Accept request */
|
||||||
|
ull_cp_cc_accept(&conn);
|
||||||
|
|
||||||
|
/* Prepare */
|
||||||
|
event_prepare(&conn);
|
||||||
|
|
||||||
|
/* Tx Queue should have one LL Control PDU */
|
||||||
|
lt_rx(LL_CIS_RSP, &conn, &tx, &local_cis_rsp);
|
||||||
|
lt_rx_q_is_empty(&conn);
|
||||||
|
|
||||||
|
/* Done */
|
||||||
|
event_done(&conn);
|
||||||
|
|
||||||
|
/* Prepare */
|
||||||
|
event_prepare(&conn);
|
||||||
|
|
||||||
|
/* Release Tx */
|
||||||
|
ull_cp_release_tx(&conn, tx);
|
||||||
|
|
||||||
|
/* Rx */
|
||||||
|
lt_tx(LL_CIS_IND, &conn, &remote_cis_ind);
|
||||||
|
|
||||||
|
/* Done */
|
||||||
|
event_done(&conn);
|
||||||
|
|
||||||
|
/* */
|
||||||
|
while (!is_instant_reached(&conn, remote_cis_ind.conn_event_count)) {
|
||||||
|
/* Prepare */
|
||||||
|
event_prepare(&conn);
|
||||||
|
|
||||||
|
/* Tx Queue should NOT have a LL Control PDU */
|
||||||
|
lt_rx_q_is_empty(&conn);
|
||||||
|
|
||||||
|
/* Done */
|
||||||
|
event_done(&conn);
|
||||||
|
|
||||||
|
/* There should NOT be a host notification */
|
||||||
|
ut_rx_q_is_empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Emulate CIS becoming established */
|
||||||
|
/* Prepare */
|
||||||
|
event_prepare(&conn);
|
||||||
|
|
||||||
|
/* Tx Queue should NOT have a LL Control PDU */
|
||||||
|
lt_rx_q_is_empty(&conn);
|
||||||
|
|
||||||
|
/* Done */
|
||||||
|
event_done(&conn);
|
||||||
|
|
||||||
|
/* There should NOT be a host notification */
|
||||||
|
ut_rx_q_is_empty();
|
||||||
|
|
||||||
|
/* Prepare */
|
||||||
|
event_prepare(&conn);
|
||||||
|
|
||||||
|
/* There should be excactly one host notification */
|
||||||
|
ut_rx_node(NODE_CIS_ESTABLISHED, &ntf, &cis_estab);
|
||||||
|
ut_rx_q_is_empty();
|
||||||
|
|
||||||
|
/* Done */
|
||||||
|
event_done(&conn);
|
||||||
|
|
||||||
|
zassert_equal(ctx_buffers_free(), test_ctx_buffers_cnt(),
|
||||||
|
"Free CTX buffers %d", ctx_buffers_free());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Central-initiated CIS Create procedure.
|
||||||
|
* Central requests CIS, peripheral Host rejects.
|
||||||
|
*
|
||||||
|
* +-----+ +-------+ +-----+
|
||||||
|
* | UT | | LL_S | | LT |
|
||||||
|
* +-----+ +-------+ +-----+
|
||||||
|
* | | |
|
||||||
|
* | | LL_CIS_REQ |
|
||||||
|
* | |<--------------------------|
|
||||||
|
* | | |
|
||||||
|
* | LE CIS Request | |
|
||||||
|
* |<--------------------------| |
|
||||||
|
* | LE CIS Request | |
|
||||||
|
* | Decline | |
|
||||||
|
* |-------------------------->| |
|
||||||
|
* | | |
|
||||||
|
* | | LL_REJECT_EXT_IND |
|
||||||
|
* | |-------------------------->|
|
||||||
|
* | | |
|
||||||
|
*/
|
||||||
|
static void test_cc_create_periph_rem_host_reject(void)
|
||||||
|
{
|
||||||
|
struct node_tx *tx;
|
||||||
|
struct node_rx_pdu *ntf;
|
||||||
|
struct node_rx_conn_iso_req cis_req = {
|
||||||
|
.cig_id = 0x01,
|
||||||
|
.cis_handle = 0x00,
|
||||||
|
.cis_id = 0x02
|
||||||
|
};
|
||||||
|
struct pdu_data_llctrl_reject_ext_ind local_reject = {
|
||||||
|
.error_code = ERROR_CODE,
|
||||||
|
.reject_opcode = PDU_DATA_LLCTRL_TYPE_CIS_REQ
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Role */
|
||||||
|
test_set_role(&conn, BT_HCI_ROLE_PERIPHERAL);
|
||||||
|
|
||||||
|
/* Connect */
|
||||||
|
ull_cp_state_set(&conn, ULL_CP_CONNECTED);
|
||||||
|
|
||||||
|
/* Prepare */
|
||||||
|
event_prepare(&conn);
|
||||||
|
|
||||||
|
/* Rx */
|
||||||
|
lt_tx(LL_CIS_REQ, &conn, &remote_cis_req);
|
||||||
|
|
||||||
|
/* Done */
|
||||||
|
event_done(&conn);
|
||||||
|
|
||||||
|
/* There should be excactly one host notification */
|
||||||
|
ut_rx_node(NODE_CIS_REQUEST, &ntf, &cis_req);
|
||||||
|
ut_rx_q_is_empty();
|
||||||
|
|
||||||
|
/* Decline request */
|
||||||
|
ull_cp_cc_reject(&conn, ERROR_CODE);
|
||||||
|
|
||||||
|
/* Prepare */
|
||||||
|
event_prepare(&conn);
|
||||||
|
|
||||||
|
/* Tx Queue should have one LL Control PDU */
|
||||||
|
lt_rx(LL_REJECT_EXT_IND, &conn, &tx, &local_reject);
|
||||||
|
lt_rx_q_is_empty(&conn);
|
||||||
|
|
||||||
|
/* Done */
|
||||||
|
event_done(&conn);
|
||||||
|
|
||||||
|
zassert_equal(ctx_buffers_free(), test_ctx_buffers_cnt(),
|
||||||
|
"Free CTX buffers %d", ctx_buffers_free());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Central-initiated CIS Create procedure.
|
||||||
|
* Central requests CIS, ask peripheral host peripheral Host fails to reply
|
||||||
|
*
|
||||||
|
* +-----+ +-------+ +-----+
|
||||||
|
* | UT | | LL_S | | LT |
|
||||||
|
* +-----+ +-------+ +-----+
|
||||||
|
* | | |
|
||||||
|
* | | LL_CIS_REQ |
|
||||||
|
* | |<--------------------------|
|
||||||
|
* | | |
|
||||||
|
* | LE CIS Request | |
|
||||||
|
* |<--------------------------| |
|
||||||
|
* | | |
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Let time pass ......
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* | | |
|
||||||
|
* | | LL_REJECT_EXT_IND (to) |
|
||||||
|
* | |-------------------------->|
|
||||||
|
* | | |
|
||||||
|
*/
|
||||||
|
static void test_cc_create_periph_rem_host_accept_to(void)
|
||||||
|
{
|
||||||
|
struct node_tx *tx;
|
||||||
|
struct node_rx_pdu *ntf;
|
||||||
|
struct node_rx_conn_iso_req cis_req = {
|
||||||
|
.cig_id = 0x01,
|
||||||
|
.cis_handle = 0x00,
|
||||||
|
.cis_id = 0x02
|
||||||
|
};
|
||||||
|
struct pdu_data_llctrl_reject_ext_ind local_reject = {
|
||||||
|
.error_code = BT_HCI_ERR_CONN_ACCEPT_TIMEOUT,
|
||||||
|
.reject_opcode = PDU_DATA_LLCTRL_TYPE_CIS_REQ
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Role */
|
||||||
|
test_set_role(&conn, BT_HCI_ROLE_PERIPHERAL);
|
||||||
|
|
||||||
|
/* Connect */
|
||||||
|
ull_cp_state_set(&conn, ULL_CP_CONNECTED);
|
||||||
|
|
||||||
|
/* Prepare */
|
||||||
|
event_prepare(&conn);
|
||||||
|
|
||||||
|
/* Rx */
|
||||||
|
lt_tx(LL_CIS_REQ, &conn, &remote_cis_req);
|
||||||
|
|
||||||
|
/* Done */
|
||||||
|
event_done(&conn);
|
||||||
|
|
||||||
|
/* There should be excactly one host notification */
|
||||||
|
ut_rx_node(NODE_CIS_REQUEST, &ntf, &cis_req);
|
||||||
|
ut_rx_q_is_empty();
|
||||||
|
|
||||||
|
/* Emulate that time passes real fast re. timeout */
|
||||||
|
conn.connect_accept_to = 0;
|
||||||
|
|
||||||
|
/* Prepare */
|
||||||
|
event_prepare(&conn);
|
||||||
|
|
||||||
|
/* Done */
|
||||||
|
event_done(&conn);
|
||||||
|
|
||||||
|
/* Prepare */
|
||||||
|
event_prepare(&conn);
|
||||||
|
|
||||||
|
/* Tx Queue should now have one LL Control PDU */
|
||||||
|
lt_rx(LL_REJECT_EXT_IND, &conn, &tx, &local_reject);
|
||||||
|
lt_rx_q_is_empty(&conn);
|
||||||
|
|
||||||
|
/* Done */
|
||||||
|
event_done(&conn);
|
||||||
|
|
||||||
|
zassert_equal(ctx_buffers_free(), test_ctx_buffers_cnt(),
|
||||||
|
"Free CTX buffers %d", ctx_buffers_free());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Central-initiated CIS Create procedure.
|
||||||
|
* Central requests CIS w. invalid PHY param, peripheral Host rejects.
|
||||||
|
*
|
||||||
|
* +-----+ +-------+ +-----+
|
||||||
|
* | UT | | LL_S | | LT |
|
||||||
|
* +-----+ +-------+ +-----+
|
||||||
|
* | | |
|
||||||
|
* | | LL_CIS_REQ (w. invald PHY) |
|
||||||
|
* | |<------------------------------|
|
||||||
|
* | | |
|
||||||
|
* | | |
|
||||||
|
* | | |
|
||||||
|
* | | |
|
||||||
|
* | | |
|
||||||
|
* | | |
|
||||||
|
* | | LL_REJECT_EXT_IND |
|
||||||
|
* | |------------------------------>|
|
||||||
|
* | | |
|
||||||
|
*/
|
||||||
|
static void test_cc_create_periph_rem_invalid_phy(void)
|
||||||
|
{
|
||||||
|
static struct pdu_data_llctrl_cis_req remote_cis_req_invalid_phy = {
|
||||||
|
.cig_id = 0x01,
|
||||||
|
.cis_id = 0x02,
|
||||||
|
.c_phy = 0x03,
|
||||||
|
.p_phy = 0x01,
|
||||||
|
.c_max_sdu_packed = { 0, 160},
|
||||||
|
.p_max_sdu = { 0, 160},
|
||||||
|
.c_max_pdu = 160,
|
||||||
|
.p_max_pdu = 160,
|
||||||
|
.nse = 2,
|
||||||
|
.p_bn = 1,
|
||||||
|
.c_bn = 1,
|
||||||
|
.c_ft = 1,
|
||||||
|
.p_ft = 1,
|
||||||
|
.iso_interval = 6,
|
||||||
|
.conn_event_count = 12,
|
||||||
|
.c_sdu_interval = { 0, 0, 0},
|
||||||
|
.p_sdu_interval = { 0, 0, 0},
|
||||||
|
.sub_interval = { 0, 0, 0},
|
||||||
|
.cis_offset_min = { 0, 0, 0},
|
||||||
|
.cis_offset_max = { 0, 0, 0}
|
||||||
|
};
|
||||||
|
struct node_tx *tx;
|
||||||
|
struct pdu_data_llctrl_reject_ext_ind local_reject = {
|
||||||
|
.error_code = BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL,
|
||||||
|
.reject_opcode = PDU_DATA_LLCTRL_TYPE_CIS_REQ
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Role */
|
||||||
|
test_set_role(&conn, BT_HCI_ROLE_PERIPHERAL);
|
||||||
|
|
||||||
|
/* Connect */
|
||||||
|
ull_cp_state_set(&conn, ULL_CP_CONNECTED);
|
||||||
|
|
||||||
|
/* Prepare */
|
||||||
|
event_prepare(&conn);
|
||||||
|
|
||||||
|
/* Rx */
|
||||||
|
lt_tx(LL_CIS_REQ, &conn, &remote_cis_req_invalid_phy);
|
||||||
|
|
||||||
|
/* Done */
|
||||||
|
event_done(&conn);
|
||||||
|
|
||||||
|
/* Prepare */
|
||||||
|
event_prepare(&conn);
|
||||||
|
|
||||||
|
/* Tx Queue should have one LL Control PDU */
|
||||||
|
lt_rx(LL_REJECT_EXT_IND, &conn, &tx, &local_reject);
|
||||||
|
lt_rx_q_is_empty(&conn);
|
||||||
|
|
||||||
|
/* Done */
|
||||||
|
event_done(&conn);
|
||||||
|
|
||||||
|
zassert_equal(ctx_buffers_free(), test_ctx_buffers_cnt(),
|
||||||
|
"Free CTX buffers %d", ctx_buffers_free());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_main(void)
|
||||||
|
{
|
||||||
|
ztest_test_suite(
|
||||||
|
cis_create,
|
||||||
|
ztest_unit_test_setup_teardown(test_cc_create_periph_rem_host_accept, setup,
|
||||||
|
unit_test_noop),
|
||||||
|
ztest_unit_test_setup_teardown(test_cc_create_periph_rem_host_reject, setup,
|
||||||
|
unit_test_noop),
|
||||||
|
ztest_unit_test_setup_teardown(test_cc_create_periph_rem_host_accept_to, setup,
|
||||||
|
unit_test_noop),
|
||||||
|
ztest_unit_test_setup_teardown(test_cc_create_periph_rem_invalid_phy, setup,
|
||||||
|
unit_test_noop));
|
||||||
|
|
||||||
|
ztest_run_test_suite(cis_create);
|
||||||
|
}
|
5
tests/bluetooth/controller/ctrl_cis_create/testcase.yaml
Normal file
5
tests/bluetooth/controller/ctrl_cis_create/testcase.yaml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
common:
|
||||||
|
tags: test_framework bluetooth bt_cis_create bt_ull_llcp
|
||||||
|
tests:
|
||||||
|
bluetooth.controller.ctrl_cis_create.test:
|
||||||
|
type: unit
|
|
@ -35,6 +35,7 @@
|
||||||
#include "ull_conn_iso_types.h"
|
#include "ull_conn_iso_types.h"
|
||||||
#include "ull_conn_types.h"
|
#include "ull_conn_types.h"
|
||||||
#include "ull_llcp.h"
|
#include "ull_llcp.h"
|
||||||
|
#include "ull_conn_internal.h"
|
||||||
#include "ull_llcp_internal.h"
|
#include "ull_llcp_internal.h"
|
||||||
|
|
||||||
#include "helper_pdu.h"
|
#include "helper_pdu.h"
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 Demant
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr.h>
|
||||||
|
#include <bluetooth/buf.h>
|
||||||
|
#include <sys/byteorder.h>
|
||||||
|
|
||||||
|
#include "util/util.h"
|
||||||
|
#include "util/memq.h"
|
||||||
|
#include "util/dbuf.h"
|
||||||
|
#include "util/mayfly.h"
|
||||||
|
|
||||||
|
#include "hal/ccm.h"
|
||||||
|
#include "hal/ticker.h"
|
||||||
|
|
||||||
|
#include "ticker/ticker.h"
|
||||||
|
|
||||||
|
#include "pdu.h"
|
||||||
|
|
||||||
|
#include "lll.h"
|
||||||
|
#include "lll/lll_vendor.h"
|
||||||
|
#include "lll_df_types.h"
|
||||||
|
#include "lll_conn.h"
|
||||||
|
#include "lll_conn_iso.h"
|
||||||
|
|
||||||
|
#include "ull_tx_queue.h"
|
||||||
|
|
||||||
|
#include "isoal.h"
|
||||||
|
#include "ull_iso_types.h"
|
||||||
|
|
||||||
|
#include "ull_conn_types.h"
|
||||||
|
#include "ull_conn_iso_types.h"
|
||||||
|
#include "ull_internal.h"
|
||||||
|
|
||||||
|
#include "ull_conn_internal.h"
|
||||||
|
#include "ull_conn_iso_internal.h"
|
||||||
|
#include "lll_peripheral_iso.h"
|
||||||
|
|
||||||
|
uint8_t ull_peripheral_iso_acquire(struct ll_conn *acl,
|
||||||
|
struct pdu_data_llctrl_cis_req *req,
|
||||||
|
uint16_t *cis_handle)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ull_peripheral_iso_setup(struct pdu_data_llctrl_cis_ind *ind,
|
||||||
|
uint8_t cig_id, uint16_t cis_handle)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ull_peripheral_iso_start(struct ll_conn *acl, uint32_t ticks_at_expire,
|
||||||
|
uint16_t cis_handle)
|
||||||
|
{
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue