diff --git a/nimble/host/src/ble_hs_hci_priv.h b/nimble/host/src/ble_hs_hci_priv.h index 24ced0a36..a152dde1e 100644 --- a/nimble/host/src/ble_hs_hci_priv.h +++ b/nimble/host/src/ble_hs_hci_priv.h @@ -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); diff --git a/nimble/host/src/ble_hs_hci_util.c b/nimble/host/src/ble_hs_hci_util.c index f210ee7ba..fabf65f1a 100644 --- a/nimble/host/src/ble_hs_hci_util.c +++ b/nimble/host/src/ble_hs_hci_util.c @@ -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) { diff --git a/nimble/host/src/ble_hs_startup.c b/nimble/host/src/ble_hs_startup.c index a70220b5d..63428a0fb 100644 --- a/nimble/host/src/ble_hs_startup.c +++ b/nimble/host/src/ble_hs_startup.c @@ -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(); diff --git a/nimble/host/test/src/ble_hs_pvcy_test.c b/nimble/host/test/src/ble_hs_pvcy_test.c index 27e95fded..f048efd90 100644 --- a/nimble/host/test/src/ble_hs_pvcy_test.c +++ b/nimble/host/test/src/ble_hs_pvcy_test.c @@ -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 diff --git a/nimble/host/test/src/ble_hs_test_util_hci.c b/nimble/host/test/src/ble_hs_test_util_hci.c index 8eb5c9479..af32d5e18 100644 --- a/nimble/host/test/src/ble_hs_test_util_hci.c +++ b/nimble/host/test/src/ble_hs_test_util_hci.c @@ -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 diff --git a/nimble/host/test/src/ble_hs_test_util_hci.h b/nimble/host/test/src/ble_hs_test_util_hci.h index 82df67e46..500f8ed68 100644 --- a/nimble/host/test/src/ble_hs_test_util_hci.h +++ b/nimble/host/test/src/ble_hs_test_util_hci.h @@ -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,