mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-10-01 04:57:22 +00:00
nimble/host: Check if controller supports LE on init
NimBLE requires LE support in controller. This allows for early error in case one tries to run NimBLE host with BR/EDR only controller eg on Linux.
This commit is contained in:
@@ -96,9 +96,8 @@ int ble_hs_hci_util_set_data_len(uint16_t conn_handle, uint16_t tx_octets,
|
||||
uint16_t tx_time);
|
||||
int ble_hs_hci_util_data_hdr_strip(struct os_mbuf *om,
|
||||
struct hci_data_hdr *out_hdr);
|
||||
|
||||
int ble_hs_hci_evt_process(uint8_t *data);
|
||||
uint16_t ble_hs_hci_util_opcode_join(uint8_t ogf, uint16_t ocf);
|
||||
|
||||
void ble_hs_hci_cmd_write_hdr(uint8_t ogf, uint16_t ocf, uint8_t len,
|
||||
void *buf);
|
||||
int ble_hs_hci_cmd_send_buf(uint16_t opcode, void *buf, uint8_t buf_len);
|
||||
|
||||
@@ -22,12 +22,6 @@
|
||||
#include "host/ble_hs_hci.h"
|
||||
#include "ble_hs_priv.h"
|
||||
|
||||
uint16_t
|
||||
ble_hs_hci_util_opcode_join(uint8_t ogf, uint16_t ocf)
|
||||
{
|
||||
return (ogf << 10) | ocf;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
ble_hs_hci_util_handle_pb_bc_join(uint16_t handle, uint8_t pb, uint8_t bc)
|
||||
{
|
||||
|
||||
@@ -23,6 +23,38 @@
|
||||
#include "host/ble_hs_hci.h"
|
||||
#include "ble_hs_priv.h"
|
||||
|
||||
#if !MYNEWT_VAL(BLE_DEVICE)
|
||||
static int
|
||||
ble_hs_startup_read_sup_f_tx(void)
|
||||
{
|
||||
uint8_t ack_params[BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN];
|
||||
uint8_t ack_params_len;
|
||||
int rc;
|
||||
|
||||
rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS,
|
||||
BLE_HCI_OCF_IP_RD_LOC_SUPP_FEAT),
|
||||
NULL,0, ack_params, sizeof ack_params,
|
||||
&ack_params_len);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (ack_params_len != BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN) {
|
||||
return BLE_HS_ECONTROLLER;
|
||||
}
|
||||
|
||||
/* for now we don't use it outside of init sequence so check this here
|
||||
* LE Supported (Controller) byte 4, bit 6
|
||||
*/
|
||||
if (!(ack_params[4] & 0x60)) {
|
||||
BLE_HS_LOG(ERROR, "Controller doesn't support LE\n");
|
||||
return BLE_HS_ECONTROLLER;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
ble_hs_startup_read_local_ver_tx(void)
|
||||
{
|
||||
@@ -232,7 +264,7 @@ ble_hs_startup_le_set_evmask_tx(void)
|
||||
mask |= 0x00000000000f1800;
|
||||
}
|
||||
|
||||
ble_hs_hci_cmd_build_le_set_event_mask(0x00000000000F1A7F, buf, sizeof buf);
|
||||
ble_hs_hci_cmd_build_le_set_event_mask(mask, buf, sizeof buf);
|
||||
rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE,
|
||||
BLE_HCI_OCF_LE_SET_EVENT_MASK),
|
||||
buf, sizeof(buf));
|
||||
@@ -316,9 +348,14 @@ ble_hs_startup_go(void)
|
||||
/* we need to check this only if using external controller */
|
||||
#if !MYNEWT_VAL(BLE_DEVICE)
|
||||
if (ble_hs_hci_get_hci_version() < BLE_HCI_VER_BCS_4_0) {
|
||||
BLE_HS_LOG(ERROR, "Required controller version is 4.0 (6)");
|
||||
BLE_HS_LOG(ERROR, "Required controller version is 4.0 (6)\n");
|
||||
return BLE_HS_ECONTROLLER;
|
||||
}
|
||||
|
||||
rc = ble_hs_startup_read_sup_f_tx();
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
rc = ble_hs_startup_set_evmask_tx();
|
||||
|
||||
@@ -125,7 +125,7 @@ ble_hs_pvcy_test_util_start_host(int num_expected_irks)
|
||||
TEST_ASSERT_FATAL(rc == 0);
|
||||
|
||||
/* Discard startup HCI commands. */
|
||||
ble_hs_test_util_hci_out_adj(13);
|
||||
ble_hs_test_util_hci_out_adj(ble_hs_test_util_hci_startup_seq_cnt());
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -226,8 +226,81 @@ ble_hs_test_util_hci_ack_append(uint16_t opcode, uint8_t status)
|
||||
ble_hs_test_util_hci_ack_append_params(opcode, status, NULL, 0);
|
||||
}
|
||||
|
||||
static const struct ble_hs_test_util_hci_ack hci_startup_seq[] = {
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(BLE_HCI_OGF_CTLR_BASEBAND,
|
||||
BLE_HCI_OCF_CB_RESET),
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_LOCAL_VER),
|
||||
.evt_params = { 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
.evt_params_len = 8,
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_LOC_SUPP_FEAT),
|
||||
.evt_params = { 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00},
|
||||
.evt_params_len = 8,
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_CTLR_BASEBAND, BLE_HCI_OCF_CB_SET_EVENT_MASK),
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_CTLR_BASEBAND, BLE_HCI_OCF_CB_SET_EVENT_MASK2),
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_EVENT_MASK),
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_BUF_SIZE),
|
||||
/* Use a very low buffer size (20) to test fragmentation.
|
||||
* Use a large num-pkts (200) to prevent controller buf exhaustion.
|
||||
*/
|
||||
.evt_params = { 0x14, 0x00, 200 },
|
||||
.evt_params_len = 3,
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_LOC_SUPP_FEAT),
|
||||
.evt_params = { 0 },
|
||||
.evt_params_len = 8,
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_BD_ADDR),
|
||||
.evt_params = BLE_HS_TEST_UTIL_PUB_ADDR_VAL,
|
||||
.evt_params_len = 6,
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_ADDR_RES_EN),
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_CLR_RESOLV_LIST),
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_ADDR_RES_EN),
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_ADD_RESOLV_LIST),
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PRIVACY_MODE),
|
||||
},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
void
|
||||
ble_hs_test_util_hci_ack_set_seq(struct ble_hs_test_util_hci_ack *acks)
|
||||
ble_hs_test_util_hci_ack_set_seq(const struct ble_hs_test_util_hci_ack *acks)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -239,78 +312,20 @@ ble_hs_test_util_hci_ack_set_seq(struct ble_hs_test_util_hci_ack *acks)
|
||||
ble_hs_hci_set_phony_ack_cb(ble_hs_test_util_hci_ack_cb);
|
||||
}
|
||||
|
||||
int
|
||||
ble_hs_test_util_hci_startup_seq_cnt(void)
|
||||
{
|
||||
/* last element is terminator, don't count it*/
|
||||
return sizeof(hci_startup_seq)/sizeof(hci_startup_seq[0]) - 1;
|
||||
}
|
||||
|
||||
void
|
||||
ble_hs_test_util_hci_ack_set_startup(void)
|
||||
{
|
||||
/* Receive acknowledgements for the startup sequence. We sent the
|
||||
* corresponding requests when the host task was started.
|
||||
*/
|
||||
ble_hs_test_util_hci_ack_set_seq(((struct ble_hs_test_util_hci_ack[]) {
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(BLE_HCI_OGF_CTLR_BASEBAND,
|
||||
BLE_HCI_OCF_CB_RESET),
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_LOCAL_VER),
|
||||
.evt_params = { 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
.evt_params_len = 8,
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_CTLR_BASEBAND, BLE_HCI_OCF_CB_SET_EVENT_MASK),
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_CTLR_BASEBAND, BLE_HCI_OCF_CB_SET_EVENT_MASK2),
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_EVENT_MASK),
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_BUF_SIZE),
|
||||
/* Use a very low buffer size (20) to test fragmentation.
|
||||
* Use a large num-pkts (200) to prevent controller buf exhaustion.
|
||||
*/
|
||||
.evt_params = { 0x14, 0x00, 200 },
|
||||
.evt_params_len = 3,
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_LOC_SUPP_FEAT),
|
||||
.evt_params = { 0 },
|
||||
.evt_params_len = 8,
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_BD_ADDR),
|
||||
.evt_params = BLE_HS_TEST_UTIL_PUB_ADDR_VAL,
|
||||
.evt_params_len = 6,
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_ADDR_RES_EN),
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_CLR_RESOLV_LIST),
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_ADDR_RES_EN),
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_ADD_RESOLV_LIST),
|
||||
},
|
||||
{
|
||||
.opcode = ble_hs_hci_util_opcode_join(
|
||||
BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PRIVACY_MODE),
|
||||
},
|
||||
{ 0 }
|
||||
}));
|
||||
ble_hs_test_util_hci_ack_set_seq(hci_startup_seq);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* leave this as macro so it may be used for static const initialization */
|
||||
#define ble_hs_hci_util_opcode_join(ogf, ocf) (((ogf) << 10) | (ocf))
|
||||
|
||||
#define BLE_HS_TEST_UTIL_PHONY_ACK_MAX 64
|
||||
struct ble_hs_test_util_hci_ack {
|
||||
uint16_t opcode;
|
||||
@@ -60,12 +63,14 @@ void ble_hs_test_util_hci_ack_set(uint16_t opcode, uint8_t status);
|
||||
void ble_hs_test_util_hci_ack_append_params(uint16_t opcode, uint8_t status,
|
||||
void *params, uint8_t params_len);
|
||||
void ble_hs_test_util_hci_ack_append(uint16_t opcode, uint8_t status);
|
||||
void ble_hs_test_util_hci_ack_set_seq(struct ble_hs_test_util_hci_ack *acks);
|
||||
void ble_hs_test_util_hci_ack_set_seq(const struct ble_hs_test_util_hci_ack *acks);
|
||||
void ble_hs_test_util_hci_ack_set_startup(void);
|
||||
void ble_hs_test_util_hci_ack_set_disc(uint8_t own_addr_type,
|
||||
int fail_idx, uint8_t fail_status);
|
||||
void ble_hs_test_util_hci_ack_set_disconnect(uint8_t hci_status);
|
||||
|
||||
int ble_hs_test_util_hci_startup_seq_cnt(void);
|
||||
|
||||
/* $verify tx */
|
||||
void ble_hs_test_util_hci_verify_tx_add_irk(uint8_t addr_type,
|
||||
const uint8_t *addr,
|
||||
|
||||
Reference in New Issue
Block a user