diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 26c992652..94ea42c4b 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -58,6 +58,8 @@ extern "C" { /* Definition for RSSI when the RSSI is unknown */ #define BLE_LL_CONN_UNKNOWN_RSSI (127) +#define BLE_LL_CONN_HANDLE_ISO_OFFSET (0x0100) + #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) /* * Encryption states for a connection diff --git a/nimble/controller/include/controller/ble_ll_ctrl.h b/nimble/controller/include/controller/ble_ll_ctrl.h index 8432422a8..15a45b2a0 100644 --- a/nimble/controller/include/controller/ble_ll_ctrl.h +++ b/nimble/controller/include/controller/ble_ll_ctrl.h @@ -40,7 +40,8 @@ extern "C" { #define BLE_LL_CTRL_PROC_DATA_LEN_UPD (8) #define BLE_LL_CTRL_PROC_PHY_UPDATE (9) #define BLE_LL_CTRL_PROC_SCA_UPDATE (10) -#define BLE_LL_CTRL_PROC_NUM (11) +#define BLE_LL_CTRL_PROC_CIS_CREATE (11) +#define BLE_LL_CTRL_PROC_NUM (12) #define BLE_LL_CTRL_PROC_IDLE (255) /* Checks if a particular control procedure is running */ @@ -55,45 +56,51 @@ extern "C" { * -> Opcode (1 byte) * -> Data (0 - 26 bytes) */ -#define BLE_LL_CTRL_CONN_UPDATE_IND (0) -#define BLE_LL_CTRL_CHANNEL_MAP_REQ (1) -#define BLE_LL_CTRL_TERMINATE_IND (2) -#define BLE_LL_CTRL_ENC_REQ (3) -#define BLE_LL_CTRL_ENC_RSP (4) -#define BLE_LL_CTRL_START_ENC_REQ (5) -#define BLE_LL_CTRL_START_ENC_RSP (6) -#define BLE_LL_CTRL_UNKNOWN_RSP (7) -#define BLE_LL_CTRL_FEATURE_REQ (8) -#define BLE_LL_CTRL_FEATURE_RSP (9) -#define BLE_LL_CTRL_PAUSE_ENC_REQ (10) -#define BLE_LL_CTRL_PAUSE_ENC_RSP (11) -#define BLE_LL_CTRL_VERSION_IND (12) -#define BLE_LL_CTRL_REJECT_IND (13) -#define BLE_LL_CTRL_SLAVE_FEATURE_REQ (14) -#define BLE_LL_CTRL_CONN_PARM_REQ (15) -#define BLE_LL_CTRL_CONN_PARM_RSP (16) -#define BLE_LL_CTRL_REJECT_IND_EXT (17) -#define BLE_LL_CTRL_PING_REQ (18) -#define BLE_LL_CTRL_PING_RSP (19) -#define BLE_LL_CTRL_LENGTH_REQ (20) -#define BLE_LL_CTRL_LENGTH_RSP (21) -#define BLE_LL_CTRL_PHY_REQ (22) -#define BLE_LL_CTRL_PHY_RSP (23) -#define BLE_LL_CTRL_PHY_UPDATE_IND (24) -#define BLE_LL_CTRL_MIN_USED_CHAN_IND (25) -#define BLE_LL_CTRL_CTE_REQ (26) -#define BLE_LL_CTRL_CTE_RSP (27) -#define BLE_LL_CTRL_PERIODIC_SYNC_IND (28) -#define BLE_LL_CTRL_CLOCK_ACCURACY_REQ (29) -#define BLE_LL_CTRL_CLOCK_ACCURACY_RSP (30) +#define BLE_LL_CTRL_CONN_UPDATE_IND (0x00) +#define BLE_LL_CTRL_CHANNEL_MAP_REQ (0x01) +#define BLE_LL_CTRL_TERMINATE_IND (0x02) +#define BLE_LL_CTRL_ENC_REQ (0x03) +#define BLE_LL_CTRL_ENC_RSP (0x04) +#define BLE_LL_CTRL_START_ENC_REQ (0x05) +#define BLE_LL_CTRL_START_ENC_RSP (0x06) +#define BLE_LL_CTRL_UNKNOWN_RSP (0x07) +#define BLE_LL_CTRL_FEATURE_REQ (0x08) +#define BLE_LL_CTRL_FEATURE_RSP (0x09) +#define BLE_LL_CTRL_PAUSE_ENC_REQ (0x0A) +#define BLE_LL_CTRL_PAUSE_ENC_RSP (0x0B) +#define BLE_LL_CTRL_VERSION_IND (0x0C) +#define BLE_LL_CTRL_REJECT_IND (0x0D) +#define BLE_LL_CTRL_SLAVE_FEATURE_REQ (0x0E) +#define BLE_LL_CTRL_CONN_PARM_REQ (0x0F) +#define BLE_LL_CTRL_CONN_PARM_RSP (0x10) +#define BLE_LL_CTRL_REJECT_IND_EXT (0x11) +#define BLE_LL_CTRL_PING_REQ (0x12) +#define BLE_LL_CTRL_PING_RSP (0x13) +#define BLE_LL_CTRL_LENGTH_REQ (0x14) +#define BLE_LL_CTRL_LENGTH_RSP (0x15) +#define BLE_LL_CTRL_PHY_REQ (0x16) +#define BLE_LL_CTRL_PHY_RSP (0x17) +#define BLE_LL_CTRL_PHY_UPDATE_IND (0x18) +#define BLE_LL_CTRL_MIN_USED_CHAN_IND (0x19) +#define BLE_LL_CTRL_CTE_REQ (0x1A) +#define BLE_LL_CTRL_CTE_RSP (0x1B) +#define BLE_LL_CTRL_PERIODIC_SYNC_IND (0x1C) +#define BLE_LL_CTRL_CLOCK_ACCURACY_REQ (0x1D) +#define BLE_LL_CTRL_CLOCK_ACCURACY_RSP (0x1E) +#define BLE_LL_CTRL_CIS_REQ (0x1F) +#define BLE_LL_CTRL_CIS_RSP (0x20) +#define BLE_LL_CTRL_CIS_IND (0x21) +#define BLE_LL_CTRL_CIS_TERMINATE_IND (0x22) /* Maximum opcode value */ -#define BLE_LL_CTRL_OPCODES (BLE_LL_CTRL_CLOCK_ACCURACY_RSP + 1) +#define BLE_LL_CTRL_OPCODES (BLE_LL_CTRL_CIS_TERMINATE_IND + 1) extern const uint8_t g_ble_ll_ctrl_pkt_lengths[BLE_LL_CTRL_OPCODES]; /* Maximum LL control PDU size */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) +#if MYNEWT_VAL(BLE_ISO) +#define BLE_LL_CTRL_MAX_PDU_LEN (42) +#elif MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) #define BLE_LL_CTRL_MAX_PDU_LEN (35) #else #define BLE_LL_CTRL_MAX_PDU_LEN (27) @@ -262,6 +269,12 @@ struct ble_ll_len_req #define BLE_LL_CTRL_CLOCK_ACCURACY_REQ_LEN (1) #define BLE_LL_CTRL_CLOCK_ACCURACY_RSP_LEN (1) +/* BLE ISO */ +#define BLE_LL_CTRL_CIS_REQ_LEN (42) +#define BLE_LL_CTRL_CIS_RSP_LEN (8) +#define BLE_LL_CTRL_CIS_IND_LEN (15) +#define BLE_LL_CTRL_CIS_TERMINATE_LEN (3) + /* API */ struct ble_ll_conn_sm; void ble_ll_ctrl_proc_start(struct ble_ll_conn_sm *connsm, int ctrl_proc); diff --git a/nimble/controller/include/controller/ble_ll_iso.h b/nimble/controller/include/controller/ble_ll_iso.h new file mode 100644 index 000000000..2944b0747 --- /dev/null +++ b/nimble/controller/include/controller/ble_ll_iso.h @@ -0,0 +1,53 @@ +/* + * 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. + */ + +#ifndef H_BLE_LL_ISO +#define H_BLE_LL_ISO + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int ble_ll_iso_read_tx_sync(const uint8_t *cmdbuf, uint8_t len); +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); +int ble_ll_iso_create_big(const uint8_t *cmdbuf, uint8_t len); +int ble_ll_iso_create_big_test(const uint8_t *cmdbuf, uint8_t len); +int ble_ll_iso_terminate_big(const uint8_t *cmdbuf, uint8_t len); +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); +int ble_ll_iso_remove_iso_data_path(const uint8_t *cmdbuf, uint8_t len); +int ble_ll_iso_transmit_test(const uint8_t *cmdbuf, uint8_t len); +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); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index c6eefcf57..b0eced617 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1681,6 +1681,17 @@ ble_ll_init(void) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE) features |= BLE_LL_FEAT_SCA_UPDATE; #endif + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) + features |= BLE_LL_FEAT_CIS_MASTER; + features |= BLE_LL_FEAT_CIS_SLAVE; + features |= BLE_LL_FEAT_ISO_BROADCASTER; + features |= BLE_LL_FEAT_ISO_HOST_SUPPORT; + + /* Set features controller by the Host */ + g_ble_ll_supported_host_features |= BLE_LL_FEAT_ISO_HOST_SUPPORT; +#endif + /* Initialize random number generation */ ble_ll_rand_init(); diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index f6f3b0bc5..ade8d7b82 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -112,6 +112,10 @@ const uint8_t g_ble_ll_ctrl_pkt_lengths[BLE_LL_CTRL_OPCODES] = BLE_LL_CTRL_PERIODIC_SYNC_IND_LEN, BLE_LL_CTRL_CLOCK_ACCURACY_REQ_LEN, BLE_LL_CTRL_CLOCK_ACCURACY_RSP_LEN, + BLE_LL_CTRL_CIS_REQ_LEN, + BLE_LL_CTRL_CIS_RSP_LEN, + BLE_LL_CTRL_CIS_IND_LEN, + BLE_LL_CTRL_CIS_TERMINATE_LEN }; /** @@ -1100,8 +1104,30 @@ ble_ll_ctrl_rx_sca_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr) ble_ll_hci_ev_sca_update(connsm, BLE_ERR_SUCCESS, dptr[0]); return BLE_ERR_MAX; } + #endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) +static uint8_t +ble_ll_ctrl_rx_cis_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, + uint8_t *rspdata) +{ + return BLE_LL_CTRL_UNKNOWN_RSP; +} + +static uint8_t +ble_ll_ctrl_rx_cis_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr, + uint8_t *rspdata) +{ + return BLE_LL_CTRL_UNKNOWN_RSP; +} + +static uint8_t +ble_ll_ctrl_rx_cis_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr) +{ + return BLE_LL_CTRL_UNKNOWN_RSP; +} +#endif /** * Create a link layer length request or length response PDU. * @@ -1307,6 +1333,15 @@ ble_ll_ctrl_start_enc_send(struct ble_ll_conn_sm *connsm) return rc; } +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) +static void +ble_ll_ctrl_cis_create(struct ble_ll_conn_sm *connsm, uint8_t *dptr) +{ + /* TODO Implement */ + return; +} +#endif + /** * Create a link layer control "encrypt request" PDU. * @@ -2207,6 +2242,12 @@ ble_ll_ctrl_proc_init(struct ble_ll_conn_sm *connsm, int ctrl_proc) opcode = BLE_LL_CTRL_CLOCK_ACCURACY_REQ; ble_ll_ctrl_sca_req_rsp_make(connsm, ctrdata); break; +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) + case BLE_LL_CTRL_PROC_CIS_CREATE: + opcode = BLE_LL_CTRL_CIS_REQ; + ble_ll_ctrl_cis_create(connsm, ctrdata); + break; #endif default: BLE_LL_ASSERT(0); @@ -2645,6 +2686,18 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) rsp_opcode = ble_ll_ctrl_rx_sca_rsp(connsm, dptr); break; #endif + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) + case BLE_LL_CTRL_CIS_REQ: + rsp_opcode = ble_ll_ctrl_rx_cis_req(connsm, dptr, rspdata); + break; + case BLE_LL_CTRL_CIS_RSP: + rsp_opcode = ble_ll_ctrl_rx_cis_rsp(connsm, dptr, rspdata); + break; + case BLE_LL_CTRL_CIS_IND: + rsp_opcode = ble_ll_ctrl_rx_cis_ind(connsm, dptr); + break; +#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) case BLE_LL_CTRL_PERIODIC_SYNC_IND: rsp_opcode = ble_ll_ctrl_rx_periodic_sync_ind(connsm, dptr); diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index 39693679f..c42e24dc0 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -33,6 +33,7 @@ #include "controller/ble_ll_whitelist.h" #include "controller/ble_ll_resolv.h" #include "controller/ble_ll_sync.h" +#include "controller/ble_ll_iso.h" #include "ble_ll_priv.h" #include "ble_ll_conn_priv.h" @@ -327,6 +328,31 @@ ble_ll_hci_le_read_bufsize(uint8_t *rspbuf, uint8_t *rsplen) return BLE_ERR_SUCCESS; } +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) +/** + * HCI read buffer size v2 command. Returns the ACL and ISO data packet length and + * num data packets. + * + * @param rspbuf Pointer to response buffer + * @param rsplen Length of response buffer + * + * @return int BLE error code + */ +static int +ble_ll_hci_le_read_bufsize_v2(uint8_t *rspbuf, uint8_t *rsplen) +{ + struct ble_hci_le_rd_buf_size_v2_rp *rp = (void *) rspbuf; + + rp->data_len = htole16(g_ble_ll_data.ll_acl_pkt_size); + rp->data_packets = g_ble_ll_data.ll_num_acl_pkts; + rp->iso_data_len = 0; + rp->iso_data_packets = 0; + + *rsplen = sizeof(*rp); + return BLE_ERR_SUCCESS; +} +#endif + #if (BLE_LL_BT5_PHY_SUPPORTED == 1) /** * Checks the preferred phy masks for validity and places the preferred masks @@ -1152,6 +1178,67 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, rc = ble_ll_set_default_sync_transfer_params(cmdbuf, len); break; #endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) + case BLE_HCI_OCF_LE_READ_ISO_TX_SYNC: + rc = ble_ll_iso_read_tx_sync(cmdbuf, len); + break; + case BLE_HCI_OCF_LE_SET_CIG_PARAM: + rc = ble_ll_iso_set_cig_param(cmdbuf, len, rspbuf, rsplen); + break; + case BLE_HCI_OCF_LE_CREATE_CIS: + rc = ble_ll_iso_create_cis(cmdbuf, len); + break; + case BLE_HCI_OCF_LE_REMOVE_CIG: + rc = ble_ll_iso_remove_cig(cmdbuf, len, rspbuf, rsplen); + break; + case BLE_HCI_OCF_LE_ACCEPT_CIS_REQ: + rc = ble_ll_iso_accept_cis_req(cmdbuf, len); + break; + case BLE_HCI_OCF_LE_REJECT_CIS_REQ: + rc = ble_ll_iso_reject_cis_req(cmdbuf, len); + break; + case BLE_HCI_OCF_LE_CREATE_BIG: + rc = ble_ll_iso_create_big(cmdbuf, len); + break; + case BLE_HCI_OCF_LE_TERMINATE_BIG: + rc = ble_ll_iso_terminate_big(cmdbuf, len); + break; + case BLE_HCI_OCF_LE_BIG_CREATE_SYNC: + rc = ble_ll_iso_big_create_sync(cmdbuf, len); + break; + case BLE_HCI_OCF_LE_BIG_TERMINATE_SYNC: + rc = ble_ll_iso_big_terminate_sync(cmdbuf,len); + break; + case BLE_HCI_OCF_LE_SETUP_ISO_DATA_PATH: + rc = ble_ll_iso_setup_iso_data_path(cmdbuf, len); + break; + case BLE_HCI_OCF_LE_REMOVE_ISO_DATA_PATH: + rc = ble_ll_iso_remove_iso_data_path(cmdbuf, len); + break; + case BLE_HCI_OCF_LE_RD_BUF_SIZE_V2: + rc = ble_ll_hci_le_read_bufsize_v2(rspbuf, rsplen); + break; +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO_TEST) + case BLE_HCI_OCF_LE_SET_CIG_PARAM_TEST: + rc = ble_ll_iso_set_cig_param_test(cmdbuf, len, rspbuf, rsplen); + break; + case BLE_HCI_OCF_LE_CREATE_BIG_TEST: + rc = ble_ll_iso_create_big_test(cmdbuf, len); + break; + case BLE_HCI_OCF_LE_ISO_TRANSMIT_TEST: + rc = ble_ll_iso_transmit_test(cmdbuf, len); + break; + case BLE_HCI_OCF_LE_ISO_RECEIVE_TEST: + rc = ble_ll_iso_receive_test(cmdbuf, len); + break; + case BLE_HCI_OCF_LE_ISO_READ_TEST_COUNTERS: + rc = ble_ll_iso_read_counters_test(cmdbuf, len); + break; + case BLE_HCI_OCF_LE_ISO_TEST_END: + rc = ble_ll_iso_end_test(cmdbuf, len); + break; +#endif #if MYNEWT_VAL(BLE_VERSION) >= 52 case BLE_HCI_OCF_LE_SET_HOST_FEAT: rc = ble_ll_set_host_feat(cmdbuf, len); @@ -1194,6 +1281,12 @@ ble_ll_hci_disconnect(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_INV_HCI_CMD_PARMS; } +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) + if (le16toh(cmd->conn_handle) >= BLE_LL_CONN_HANDLE_ISO_OFFSET) { + return ble_ll_iso_disconnect_cmd(cmd); + } +#endif + return ble_ll_conn_hci_disconnect_cmd(cmd); } diff --git a/nimble/controller/src/ble_ll_iso.c b/nimble/controller/src/ble_ll_iso.c new file mode 100644 index 000000000..a6186fe1a --- /dev/null +++ b/nimble/controller/src/ble_ll_iso.c @@ -0,0 +1,146 @@ +/* + * 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 +#include "syscfg/syscfg.h" +#include "nimble/ble.h" +#include "nimble/hci_common.h" +#include "controller/ble_ll_iso.h" + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) + +int +ble_ll_iso_read_tx_sync(const uint8_t *cmdbuf, uint8_t len) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_iso_set_cig_param(const uint8_t *cmdbuf, uint8_t len, + uint8_t *rspbuf, uint8_t *rsplen) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_iso_create_cis(const uint8_t *cmdbuf, uint8_t len) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_iso_disconnect_cmd(const struct ble_hci_lc_disconnect_cp *cmd) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_iso_remove_cig(const uint8_t *cmdbuf, uint8_t len, + uint8_t *rspbuf, uint8_t *rsplen) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_iso_accept_cis_req(const uint8_t *cmdbuf, uint8_t len) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_iso_reject_cis_req(const uint8_t *cmdbuf, uint8_t len) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_iso_setup_iso_data_path(const uint8_t *cmdbuf, uint8_t len) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_iso_remove_iso_data_path(const uint8_t *cmdbuf, uint8_t len) +{ + /* Nothing to do here for now when HCI is supported */ + return 0; +} +int +ble_ll_iso_create_big(const uint8_t *cmdbuf, uint8_t len) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_iso_terminate_big(const uint8_t *cmdbuf, uint8_t len) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_iso_big_create_sync(const uint8_t *cmdbuf, uint8_t len) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_iso_big_terminate_sync(const uint8_t *cmdbuf, uint8_t len) +{ + return BLE_ERR_UNSUPPORTED; +} + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO_TEST) +int +ble_ll_iso_set_cig_param_test(const uint8_t *cmdbuf, uint8_t len, + uint8_t *rspbuf, uint8_t *rsplen) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_iso_create_big_test(const uint8_t *cmdbuf, uint8_t len) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_iso_transmit_test(const uint8_t *cmdbuf, uint8_t len) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_iso_receive_test(const uint8_t *cmdbuf, uint8_t len) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_iso_read_counters_test(const uint8_t *cmdbuf, uint8_t len) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_iso_end_test(const uint8_t *cmdbuf, uint8_t len) +{ + return BLE_ERR_UNSUPPORTED; +} +#endif +#endif diff --git a/nimble/controller/src/ble_ll_supp_cmd.c b/nimble/controller/src/ble_ll_supp_cmd.c index 10943703f..863e69816 100644 --- a/nimble/controller/src/ble_ll_supp_cmd.c +++ b/nimble/controller/src/ble_ll_supp_cmd.c @@ -404,10 +404,55 @@ #define BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER_PARAMS (0 << 0) #define BLE_SUPP_CMD_LE_PADV_DEFAULT_SYNC_TRANSFER_PARAMS (0 << 1) #endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) +#define BLE_SUPP_CMD_LE_READ_BUF_SIZE_V2 (1 << 5) +#define BLE_SUPP_CMD_LE_READ_ISO_TX_SYNC (1 << 6) +#define BLE_SUPP_CMD_LE_SET_CIG_PARAM (1 << 7) +#else +#define BLE_SUPP_CMD_LE_READ_BUF_SIZE_V2 (0 << 5) +#define BLE_SUPP_CMD_LE_READ_ISO_TX_SYNC (0 << 6) +#define BLE_SUPP_CMD_LE_SET_CIG_PARAM (0 << 7) +#endif + #define BLE_LL_SUPP_CMD_OCTET_41 \ ( \ - BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER_PARAMS | \ - BLE_SUPP_CMD_LE_PADV_DEFAULT_SYNC_TRANSFER_PARAMS \ + BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER_PARAMS | \ + BLE_SUPP_CMD_LE_PADV_DEFAULT_SYNC_TRANSFER_PARAMS | \ + BLE_SUPP_CMD_LE_READ_BUF_SIZE_V2 | \ + BLE_SUPP_CMD_LE_READ_ISO_TX_SYNC | \ + BLE_SUPP_CMD_LE_SET_CIG_PARAM \ +) + +/* Octet 42 */ +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) +#define BLE_SUPP_CMD_LE_SET_CIG_PARAM_TEST (1 << 0) +#define BLE_SUPP_CMD_LE_CREATE_CIS (1 << 1) +#define BLE_SUPP_CMD_LE_REMOVE_CIG (1 << 2) +#define BLE_SUPP_CMD_LE_ACCEPT_CIS_REQ (1 << 3) +#define BLE_SUPP_CMD_LE_REJECT_CIS_REQ (1 << 4) +#define BLE_SUPP_CMD_LE_CREATE_BIG (1 << 5) +#define BLE_SUPP_CMD_LE_CREATE_BIG_TEST (1 << 6) +#define BLE_SUPP_CMD_LE_TERMINATE_BIG (1 << 7) +#else +#define BLE_SUPP_CMD_LE_SET_CIG_PARAM_TEST (0 << 0) +#define BLE_SUPP_CMD_LE_CREATE_CIS (0 << 1) +#define BLE_SUPP_CMD_LE_REMOVE_CIG (0 << 2) +#define BLE_SUPP_CMD_LE_ACCEPT_CIS_REQ (0 << 3) +#define BLE_SUPP_CMD_LE_REJECT_CIS_REQ (0 << 4) +#define BLE_SUPP_CMD_LE_CREATE_BIG (0 << 5) +#define BLE_SUPP_CMD_LE_CREATE_BIG_TEST (0 << 6) +#define BLE_SUPP_CMD_LE_TERMINATE_BIG (0 << 7) +#endif +#define BLE_LL_SUPP_CMD_OCTET_42 \ +( \ + BLE_SUPP_CMD_LE_SET_CIG_PARAM_TEST | \ + BLE_SUPP_CMD_LE_CREATE_CIS | \ + BLE_SUPP_CMD_LE_REMOVE_CIG | \ + BLE_SUPP_CMD_LE_ACCEPT_CIS_REQ | \ + BLE_SUPP_CMD_LE_REJECT_CIS_REQ | \ + BLE_SUPP_CMD_LE_CREATE_BIG | \ + BLE_SUPP_CMD_LE_CREATE_BIG_TEST | \ + BLE_SUPP_CMD_LE_TERMINATE_BIG \ ) /* Octet 43 */ @@ -477,7 +522,7 @@ const uint8_t g_ble_ll_supp_cmds[BLE_LL_SUPP_CMD_LEN] = BLE_LL_SUPP_CMD_OCTET_39, BLE_LL_SUPP_CMD_OCTET_40, /* Octet 40 */ BLE_LL_SUPP_CMD_OCTET_41, - 0, + BLE_LL_SUPP_CMD_OCTET_42, BLE_LL_SUPP_CMD_OCTET_43, BLE_LL_SUPP_CMD_OCTET_44, }; diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 2327263b1..ea043885a 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -267,6 +267,21 @@ syscfg.defs: restrictions: - '(BLE_VERSION >= 52) if 1' + BLE_LL_CFG_FEAT_LL_ISO: + description: > + This option is used to enable/disable support for LE Isochronous Channels + as per Bluetooth v5.2 channels + value: MYNEWT_VAL(BLE_ISO) + restrictions: + - '(BLE_VERSION >= 52) if 1' + + BLE_LL_CFG_FEAT_LL_ISO_TEST: + description: > + This option is used to enable/disbale test commands for ISO support + value: MYNEWT_VAL(BLE_ISO_TEST) + restrictions: + - 'BLE_LL_CFG_FEAT_LL_ISO if 1' + BLE_LL_EXT_ADV_AUX_PTR_CNT: description: > This option configure a max number of scheduled outstanding auxiliary diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index b52dccd99..1461c5cbd 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -201,6 +201,14 @@ struct ble_hci_le_rd_buf_size_rp { uint8_t data_packets; } __attribute__((packed)); +#define BLE_HCI_OCF_LE_RD_BUF_SIZE_V2 (0x0060) +struct ble_hci_le_rd_buf_size_v2_rp { + uint16_t data_len; + uint8_t data_packets; + uint16_t iso_data_len; + uint8_t iso_data_packets; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_RD_LOC_SUPP_FEAT (0x0003) struct ble_hci_le_rd_loc_supp_feat_rp { uint64_t features; @@ -825,11 +833,228 @@ struct ble_hci_le_set_default_periodic_sync_transfer_params_cp { #define BLE_HCI_OCF_LE_GENERATE_DHKEY_V2 (0x005E) #define BLE_HCI_OCF_LE_MODIFY_SCA (0x005F) +#if MYNEWT_VAL(BLE_ISO) +#define BLE_HCI_OCF_LE_READ_ISO_TX_SYNC (0x0061) +struct ble_hci_le_read_iso_tx_sync_cp { + uint16_t conn_handle; +} __attribute__((packed)); + +struct ble_hci_le_read_iso_tx_sync_rp { + uint16_t conn_handle; + uint16_t packet_seq_num; + uint32_t timestamp; + uint8_t timeoffset[3]; +} __attribute__((packed)); + +#define BLE_HCI_LE_SET_CIG_CIS_MAX_NUM (0x1F) +#define BLE_HCI_OCF_LE_SET_CIG_PARAM (0x0062) +struct ble_hci_le_cis_params { + uint8_t cis_id; + uint16_t max_sdu_mtos; + uint16_t max_sdu_stom; + uint8_t phy_mtos; + uint8_t phy_stom; + uint8_t rnt_mtos; + uint8_t rnt_stom; +} __attribute__((packed)); + +struct ble_hci_le_set_cig_params_cp { + uint8_t cig_id; + uint8_t sdu_interval_mtos[3]; + uint8_t sdu_interval_stom[3]; + uint8_t sca; + uint8_t packing; + uint8_t framing; + uint16_t max_latency_mtos; + uint16_t max_latency_stom; + uint8_t cis_cnt; + struct ble_hci_le_cis_params cis_params[0]; +} __attribute__((packed)); + +struct ble_hci_le_set_cig_params_rp { + uint8_t cig_id; + uint8_t cis_cnt; + uint16_t cis_handle[0]; +} __attribute__((packed)); + +#if MYNEWT_VAL(BLE_ISO_TEST) +#define BLE_HCI_OCF_LE_SET_CIG_PARAM_TEST (0x0063) +struct ble_hci_le_cis_params_test { + uint8_t cis_id; + uint8_t nse; + uint16_t max_sdu_mtos; + uint16_t max_sdu_stom; + uint16_t max_pdu_mtos; + uint16_t max_pdu_stom; + uint8_t phy_mtos; + uint8_t phy_stom; + uint8_t bn_mtos; + uint8_t bn_stom; +} __attribute__((packed)); + +struct ble_hci_le_set_cig_params_test_cp { + uint8_t cig_id; + uint8_t sdu_interval_mtos[3]; + uint8_t sdu_interval_stom[3]; + uint8_t ft_mtos; + uint8_t ft_stom; + uint16_t iso_interval; + uint8_t sca; + uint8_t packing; + uint8_t framing; + uint8_t cis_cnt; + struct ble_hci_le_cis_params_test cis_params[0]; +} __attribute__((packed)); +#endif + +#define BLE_HCI_LE_CREATE_CIS_MAX_CIS_NUM (0x1F) +#define BLE_HCI_OCF_LE_CREATE_CIS (0x0064) +struct ble_hci_le_create_cis_params { + uint16_t cis_handle; + uint16_t conn_handle; +} __attribute__((packed)); + +struct ble_hci_le_create_cis_cp { + uint8_t cis_cnt; + struct ble_hci_le_create_cis_params params[0]; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_REMOVE_CIG (0x0065) +struct ble_hci_le_remove_cig_cp { + uint8_t cig_id; +} __attribute__((packed)); + +struct ble_hci_le_remove_cig_rp { + uint8_t cig_id; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_ACCEPT_CIS_REQ (0x0066) +struct ble_hci_le_accept_cis_request_cp { + uint16_t cis_handle; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_REJECT_CIS_REQ (0x0067) +struct ble_hci_le_reject_cis_request_cp { + uint16_t cis_handle; + uint8_t reason; +} __attribute__((packed)); + +struct ble_hci_le_reject_cis_request_rp { + uint16_t conn_handle; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_CREATE_BIG (0x0068) +struct ble_hci_le_create_big_cp { + uint8_t big_handle; + uint8_t adv_handle; + uint8_t bis_cnt; + uint8_t sdu_interval[3]; + uint16_t max_sdu; + uint16_t max_transport_latency; + uint8_t rnt; + uint8_t phy; + uint8_t packing; + uint8_t framing; + uint8_t encryption; + uint8_t broadcast_code[16]; +} __attribute__((packed)); + +#if MYNEWT_VAL(BLE_ISO_TEST) +#define BLE_HCI_OCF_LE_CREATE_BIG_TEST (0x0069) +struct ble_hci_le_create_big_test_cp { + uint8_t big_handle; + uint8_t adv_handle; + uint8_t bis_cnt; + uint8_t sdu_interval[3]; + uint16_t iso_interval; + uint8_t nse; + uint16_t max_sdu; + uint16_t max_pdu; + uint8_t phy; + uint8_t packing; + uint8_t framing; + uint8_t bn; + uint8_t irc; + uint8_t pto; + uint8_t encryption; + uint8_t broadcast_code[16]; +} __attribute__((packed)); +#endif + +#define BLE_HCI_OCF_LE_TERMINATE_BIG (0x006a) +struct ble_hci_le_terminate_big_cp { + uint8_t big_handle; + uint8_t reason; +} __attribute__((packed)); + +#define BLE_HCI_LE_BIG_CREATE_SYNC_LEN_MIN (25) +#define BLE_HCI_OCF_LE_BIG_CREATE_SYNC (0x006b) +struct ble_hci_le_big_create_sync_cp { + uint8_t big_handle; + uint16_t sync_handle; + uint8_t big_cnt; + uint8_t encryption; + uint8_t broadcast_code[16]; + uint8_t mse; + uint16_t timeout; + uint8_t bis[0]; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_BIG_TERMINATE_SYNC (0x006c) +struct ble_hci_le_terminate_big_sync_cp { + uint8_t big_handle; +} __attribute__((packed)); +#endif + #define BLE_HCI_OCF_LE_REQ_PEER_SCA (0x006d) struct ble_hci_le_request_peer_sca_cp { uint16_t conn_handle; } __attribute__((packed)); +#if MYNEWT_VAL(BLE_ISO) +#define BLE_HCI_OCF_LE_SETUP_ISO_DATA_PATH (0x006e) +struct ble_hci_le_iso_setup_data_path_cp { + uint16_t iso_handle; + uint8_t direction; + uint8_t id; + uint8_t codec_id[5]; + uint8_t controller_delay[3]; + uint8_t codec_conf_len; + uint8_t codec_conf[0]; +} __attribute__((packed)); + +#define BLE_HCI_LE_REMOVE_INPUT_DATA_PATH_BIT (0x01) +#define BLE_HCI_LE_REMOVE_OUTPUT_DATA_PATH_BIT (0x02) +#define BLE_HCI_OCF_LE_REMOVE_ISO_DATA_PATH (0x006f) +struct ble_hci_le_iso_remove_data_path_cp { + uint16_t iso_handle; + uint8_t direction; +} __attribute__((packed)); + +#if MYNEWT_VAL(BLE_ISO_TEST) +#define BLE_HCI_OCF_LE_ISO_TRANSMIT_TEST (0x0070) +struct ble_hci_le_iso_transmit_test_cp { + uint16_t iso_handle; + uint8_t payload_type; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_ISO_RECEIVE_TEST (0x0071) +struct ble_hci_le_iso_receive_test_cp { + uint16_t iso_handle; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_ISO_READ_TEST_COUNTERS (0x0072) +struct ble_hci_le_iso_read_test_counters_cp { + uint16_t iso_handle; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_ISO_TEST_END (0x0073) +struct ble_hci_le_iso_test_end_cp { + uint16_t iso_handle; +} __attribute__((packed)); +#endif +#endif + #define BLE_HCI_OCF_LE_SET_HOST_FEAT (0x0074) struct ble_hci_le_set_host_feat_cp { uint8_t bit_num; @@ -1449,6 +1674,84 @@ struct ble_hci_ev_le_subev_periodic_adv_sync_transfer { uint8_t aca; } __attribute__((packed)); +#define BLE_HCI_LE_SUBEV_CIS_ESTAB (0x19) +struct ble_hci_ev_le_subev_cis_established { + uint8_t subev_code; + uint8_t status; + uint16_t cis_handle; + uint8_t cig_sync_delay[3]; + uint8_t cis_sync_delay[3]; + uint8_t trans_latency_mtos[3]; + uint8_t trans_latency_stom[3]; + uint8_t phy_mtos; + uint8_t phy_stom; + uint8_t nse; + uint8_t bn_mtos; + uint8_t bn_stom; + uint8_t ft_mtos; + uint8_t ft_stom; + uint16_t max_pdu_mtos; + uint16_t max_pdu_stom; + uint16_t iso_interval; +} __attribute__((packed)); + +#define BLE_HCI_LE_SUBEV_CIS_REQUEST (0x1A) +struct ble_hci_ev_le_subev_cis_request { + uint8_t subev_code; + uint16_t conn_handle; + uint16_t cis_handle; + uint8_t cig_id; + uint8_t cis_id; +} __attribute__((packed)); + +#define BLE_HCI_LE_SUBEV_BIG_COMP (0x1B) +struct ble_hci_ev_le_subev_big_complete { + uint8_t subev_code; + uint8_t status; + uint8_t big_handle; + uint8_t big_sync_delay[3]; + uint8_t transport_latency[3]; + uint8_t phy; + uint8_t nse; + uint8_t bn; + uint8_t pto; + uint8_t irc; + uint16_t max_pdu; + uint16_t iso_interval; + uint8_t bis_cnt; + uint16_t bis[0]; +} __attribute__((packed)); + +#define BLE_HCI_LE_SUBEV_BIG_TERMINATE_COMP (0x1C) +struct ble_hci_ev_le_subev_big_terminate_complete { + uint8_t subev_code; + uint8_t big_handle; + uint8_t reason; +} __attribute__((packed)); + +#define BLE_HCI_LE_SUBEV_BIG_SYNC_ESTAB (0x1D) +struct ble_hci_ev_le_subev_big_sync_established { + uint8_t subev_code; + uint8_t status; + uint8_t big_handle; + uint8_t transport_latency[3]; + uint8_t nse; + uint8_t bn; + uint8_t pto; + uint8_t irc; + uint16_t max_pdu; + uint16_t iso_interval; + uint8_t bis_cnt; + uint16_t bis_handles[0]; +} __attribute__((packed)); + +#define BLE_HCI_LE_SUBEV_BIG_SYNC_LOST (0x1E) +struct ble_hci_ev_le_subev_big_sync_lost { + uint8_t subev_code; + uint8_t big_handle; + uint8_t reason; +} __attribute__((packed)); + #define BLE_HCI_LE_SUBEV_REQ_PEER_SCA_COMP (0x1F) struct ble_hci_ev_le_subev_peer_sca_complete { uint8_t subev_code; @@ -1457,6 +1760,24 @@ struct ble_hci_ev_le_subev_peer_sca_complete { uint8_t sca; } __attribute__((packed)); +#define BLE_HCI_LE_SUBEV_BIGINFO_ADV_REPORT (0x22) +struct ble_hci_ev_le_subev_biginfo_adv_report { + uint8_t subev_code; + uint16_t sync_handle; + uint8_t bis_cnt; + uint8_t nse; + uint16_t iso_interval; + uint8_t bn; + uint8_t pto; + uint8_t irc; + uint16_t max_pdu; + uint8_t sdu_interval[3]; + uint16_t max_sdu; + uint8_t phy; + uint8_t framing; + uint8_t encryption; +} __attribute__((packed)); + /* Data buffer overflow event */ #define BLE_HCI_EVENT_ACL_BUF_OVERFLOW (0x01) diff --git a/nimble/syscfg.yml b/nimble/syscfg.yml index 537fd9ba5..35a6ef810 100644 --- a/nimble/syscfg.yml +++ b/nimble/syscfg.yml @@ -77,6 +77,19 @@ syscfg.defs: integer for easy comparison. range: 50, 51, 52 value: 50 + BLE_ISO: + description: > + This enables LE Isochronous Channels as per Bluetooth v5.2 + value: 0 + restrictions: + - '(BLE_VERSION >= 52) if 1' + + BLE_ISO_TEST: + description: > + Enables BLE ISO Testing commands + value: 0 + restrictions: + - 'BLE_ISO if 1' # Allow periodic sync transfer only if 5.1 or higher syscfg.restrictions: