diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index 6d5dac950..5fe808410 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -567,7 +567,7 @@ extern uint32_t g_bletest_IVm; extern uint32_t g_bletest_IVs; #endif -#if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) +#if MYNEWT_VAL(BLE_LL_DTM) void ble_ll_dtm_init(void); #endif diff --git a/nimble/controller/include/controller/ble_ll_sched.h b/nimble/controller/include/controller/ble_ll_sched.h index 39955eb0b..4ad306ddc 100644 --- a/nimble/controller/include/controller/ble_ll_sched.h +++ b/nimble/controller/include/controller/ble_ll_sched.h @@ -214,7 +214,7 @@ void ble_ll_sched_stop(void); void ble_ll_sched_rfclk_chk_restart(void); #endif -#if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) +#if MYNEWT_VAL(BLE_LL_DTM) int ble_ll_sched_dtm(struct ble_ll_sched_item *sch); #endif diff --git a/nimble/controller/include/controller/ble_phy.h b/nimble/controller/include/controller/ble_phy.h index 463816250..dd5250cef 100644 --- a/nimble/controller/include/controller/ble_phy.h +++ b/nimble/controller/include/controller/ble_phy.h @@ -243,7 +243,7 @@ static inline int ble_ll_phy_to_phy_mode(int phy, int phy_options) return phy_mode; } -#if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) +#if MYNEWT_VAL(BLE_LL_DTM) void ble_phy_enable_dtm(void); void ble_phy_disable_dtm(void); #endif diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 79921758f..36c7619cb 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -45,7 +45,7 @@ #include "controller/ble_ll_sync.h" #include "ble_ll_conn_priv.h" -#if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) +#if MYNEWT_VAL(BLE_LL_DTM) #include "ble_ll_dtm_priv.h" #endif @@ -617,7 +617,7 @@ ble_ll_wfr_timer_exp(void *arg) case BLE_LL_STATE_INITIATING: ble_ll_conn_init_wfr_timer_exp(); break; -#if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) +#if MYNEWT_VAL(BLE_LL_DTM) case BLE_LL_STATE_DTM: ble_ll_dtm_wfr_timer_exp(); break; @@ -717,7 +717,7 @@ ble_ll_count_rx_stats(struct ble_mbuf_hdr *hdr, uint16_t len, uint8_t pdu_type) crcok = BLE_MBUF_HDR_CRC_OK(hdr); connection_data = (BLE_MBUF_HDR_RX_STATE(hdr) == BLE_LL_STATE_CONNECTION); -#if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) +#if MYNEWT_VAL(BLE_LL_DTM) /* Reuse connection stats for DTM */ connection_data = (BLE_MBUF_HDR_RX_STATE(hdr) == BLE_LL_STATE_DTM); #endif @@ -794,7 +794,7 @@ ble_ll_rx_pkt_in(void) case BLE_LL_STATE_INITIATING: ble_ll_init_rx_pkt_in(pdu_type, rxbuf, ble_hdr); break; -#if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) +#if MYNEWT_VAL(BLE_LL_DTM) case BLE_LL_STATE_DTM: ble_ll_dtm_rx_pkt_in(m, ble_hdr); break; @@ -930,7 +930,7 @@ ble_ll_rx_start(uint8_t *rxbuf, uint8_t chan, struct ble_mbuf_hdr *rxhdr) case BLE_LL_STATE_SCANNING: rc = ble_ll_scan_rx_isr_start(pdu_type, &rxhdr->rxinfo.flags); break; -#if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) +#if MYNEWT_VAL(BLE_LL_DTM) case BLE_LL_STATE_DTM: rc = ble_ll_dtm_rx_isr_start(rxhdr, ble_phy_access_addr_get()); break; @@ -983,7 +983,7 @@ ble_ll_rx_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) ble_ll_trace_u32x3(BLE_LL_TRACE_ID_RX_END, pdu_type, len, rxhdr->rxinfo.flags); -#if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) +#if MYNEWT_VAL(BLE_LL_DTM) if (BLE_MBUF_HDR_RX_STATE(rxhdr) == BLE_LL_STATE_DTM) { rc = ble_ll_dtm_rx_isr_end(rxbuf, rxhdr); return rc; @@ -1318,7 +1318,7 @@ ble_ll_reset(void) /* Stop any advertising */ ble_ll_adv_reset(); -#if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) +#if MYNEWT_VAL(BLE_LL_DTM) ble_ll_dtm_reset(); #endif @@ -1628,7 +1628,7 @@ ble_ll_init(void) "ble_ll"); SYSINIT_PANIC_ASSERT(rc == 0); -#if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) +#if MYNEWT_VAL(BLE_LL_DTM) ble_ll_dtm_init(); #endif diff --git a/nimble/controller/src/ble_ll_dtm.c b/nimble/controller/src/ble_ll_dtm.c index 4a92d8efa..0599aab6d 100644 --- a/nimble/controller/src/ble_ll_dtm.c +++ b/nimble/controller/src/ble_ll_dtm.c @@ -49,6 +49,9 @@ struct dtm_ctx { uint8_t itvl_rem_usec; uint16_t num_of_packets; uint32_t itvl_ticks; +#if MYNEWT_VAL(BLE_DTM_CLI_EXTENSIONS_ENABLE) + uint16_t num_of_packets_max; +#endif int active; uint8_t rf_channel; uint8_t phy_mode; @@ -140,6 +143,8 @@ static const uint8_t channel_rf_to_index[] = { #define BLE_DTM_SYNC_WORD (0x71764129) #define BLE_DTM_CRC (0x555555) +static void ble_ll_dtm_ctx_free(struct dtm_ctx * ctx); + static void ble_ll_dtm_set_next(struct dtm_ctx *ctx) { @@ -169,6 +174,18 @@ ble_ll_dtm_ev_tx_resched_cb(struct ble_npl_event *evt) { } OS_EXIT_CRITICAL(sr); +#if MYNEWT_VAL(BLE_DTM_CLI_EXTENSIONS_ENABLE) + if (g_ble_ll_dtm_ctx.num_of_packets_max && + (g_ble_ll_dtm_ctx.num_of_packets == g_ble_ll_dtm_ctx.num_of_packets_max)) { + /* + * XXX do not send more packets, but also do not stop DTM - it shall be + * stopped as usual by HCI command since there is no standard way to + * signal end of test to host. + */ + return; + } +#endif + ble_ll_dtm_set_next(ctx); rc = ble_ll_sched_dtm(&ctx->sch); BLE_LL_ASSERT(rc == 0); @@ -194,6 +211,8 @@ ble_ll_dtm_tx_done(void *arg) return; } + g_ble_ll_dtm_ctx.num_of_packets++; + /* Reschedule event in LL context */ ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &ctx->evt); @@ -249,7 +268,8 @@ resched: } static void -ble_ll_dtm_calculate_itvl(struct dtm_ctx *ctx, uint8_t len, int phy_mode) +ble_ll_dtm_calculate_itvl(struct dtm_ctx *ctx, uint8_t len, + uint16_t cmd_interval, int phy_mode) { uint32_t l; uint32_t itvl_usec; @@ -259,6 +279,12 @@ ble_ll_dtm_calculate_itvl(struct dtm_ctx *ctx, uint8_t len, int phy_mode) l = ble_ll_pdu_tx_time_get(len + BLE_LL_PDU_HDR_LEN, phy_mode); itvl_usec = ((l + 249 + 624) / 625) * 625; +#if MYNEWT_VAL(BLE_LL_DTM_EXTENSIONS_ENABLE) + if (cmd_interval > itvl_usec) { + itvl_usec = cmd_interval; + } +#endif + itvl_ticks = os_cputime_usecs_to_ticks(itvl_usec); ctx->itvl_rem_usec = (itvl_usec - os_cputime_ticks_to_usecs(itvl_ticks)); if (ctx->itvl_rem_usec == 31) { @@ -270,7 +296,8 @@ ble_ll_dtm_calculate_itvl(struct dtm_ctx *ctx, uint8_t len, int phy_mode) static int ble_ll_dtm_tx_create_ctx(uint8_t packet_payload, uint8_t len, - uint8_t rf_channel, uint8_t phy_mode) + uint8_t rf_channel, uint8_t phy_mode, + uint16_t cmd_interval, uint16_t cmd_pkt_count) { int rc = 0; uint8_t byte_pattern; @@ -285,6 +312,10 @@ ble_ll_dtm_tx_create_ctx(uint8_t packet_payload, uint8_t len, g_ble_ll_dtm_ctx.phy_mode = phy_mode; g_ble_ll_dtm_ctx.rf_channel = rf_channel; + g_ble_ll_dtm_ctx.num_of_packets = 0; +#if MYNEWT_VAL(BLE_DTM_CLI_EXTENSIONS_ENABLE) + g_ble_ll_dtm_ctx.num_of_packets_max = cmd_pkt_count; +#endif /* Set BLE transmit header */ ble_hdr = BLE_MBUF_HDR_PTR(m); @@ -344,7 +375,7 @@ schedule: ble_npl_event_init(&g_ble_ll_dtm_ctx.evt, ble_ll_dtm_ev_tx_resched_cb, &g_ble_ll_dtm_ctx); - ble_ll_dtm_calculate_itvl(&g_ble_ll_dtm_ctx, len, phy_mode); + ble_ll_dtm_calculate_itvl(&g_ble_ll_dtm_ctx, len, cmd_interval, phy_mode); /* Set some start point for TX packets */ rc = ble_ll_sched_dtm(sch); @@ -440,17 +471,28 @@ ble_ll_dtm_ctx_free(struct dtm_ctx * ctx) } int -ble_ll_dtm_tx_test(uint8_t *cmdbuf, bool enhanced) +ble_ll_dtm_tx_test(uint8_t *cmdbuf, uint8_t cmdlen, bool enhanced) { + uint8_t cmdlen_valid; uint8_t tx_chan = cmdbuf[0]; uint8_t len = cmdbuf[1]; uint8_t packet_payload = cmdbuf[2]; uint8_t phy_mode = BLE_PHY_MODE_1M; + uint16_t interval = 0; + uint16_t pkt_count = 0; if (g_ble_ll_dtm_ctx.active) { return BLE_ERR_CTLR_BUSY; } + cmdlen_valid = enhanced ? BLE_HCI_LE_ENH_TX_TEST_LEN : BLE_HCI_TX_TEST_LEN; + +#if !MYNEWT_VAL(BLE_LL_DTM_EXTENSIONS_ENABLE) + if (cmdlen != cmdlen_valid) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } +#endif + if (enhanced) { switch (cmdbuf[3]) { case BLE_HCI_LE_PHY_1M: @@ -478,7 +520,17 @@ ble_ll_dtm_tx_test(uint8_t *cmdbuf, bool enhanced) return BLE_ERR_INV_HCI_CMD_PARMS; } - if (ble_ll_dtm_tx_create_ctx(packet_payload, len, tx_chan, phy_mode)) { +#if MYNEWT_VAL(BLE_LL_DTM_EXTENSIONS_ENABLE) + if (cmdlen == cmdlen_valid + 4) { + interval = get_le16(cmdbuf + cmdlen_valid ); + pkt_count = get_le16(cmdbuf + cmdlen_valid + 2); + } else if (cmdlen != cmdlen_valid) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } +#endif + + if (ble_ll_dtm_tx_create_ctx(packet_payload, len, tx_chan, phy_mode, + interval, pkt_count)) { return BLE_ERR_UNSPECIFIED; } diff --git a/nimble/controller/src/ble_ll_dtm_priv.h b/nimble/controller/src/ble_ll_dtm_priv.h index 5341cd28d..d6633f158 100644 --- a/nimble/controller/src/ble_ll_dtm_priv.h +++ b/nimble/controller/src/ble_ll_dtm_priv.h @@ -24,7 +24,7 @@ #include #include "nimble/ble.h" -int ble_ll_dtm_tx_test(uint8_t *cmdbuf, bool enhanced); +int ble_ll_dtm_tx_test(uint8_t *cmdbuf, uint8_t cmdlen, bool enhanced); int ble_ll_dtm_rx_test(uint8_t *cmdbuf, bool enhanced); int ble_ll_dtm_end_test(uint8_t *rsp, uint8_t *rsplen); diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index c809a5ac5..817d8631c 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -38,7 +38,7 @@ #include "hal/hal_gpio.h" #endif -#if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) +#if MYNEWT_VAL(BLE_LL_DTM) #include "ble_ll_dtm_priv.h" #endif @@ -982,9 +982,7 @@ ble_ll_hci_le_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen, break; #if MYNEWT_VAL(BLE_LL_DTM) case BLE_HCI_OCF_LE_TX_TEST: - if (len == BLE_HCI_TX_TEST_LEN) { - rc = ble_ll_dtm_tx_test(cmdbuf, false); - } + rc = ble_ll_dtm_tx_test(cmdbuf, len, false); break; case BLE_HCI_OCF_LE_RX_TEST: if (len == BLE_HCI_RX_TEST_LEN) { @@ -1090,16 +1088,14 @@ ble_ll_hci_le_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen, } break; #endif -#if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) +#if MYNEWT_VAL(BLE_LL_DTM) case BLE_HCI_OCF_LE_ENH_RX_TEST: if (len == BLE_HCI_LE_ENH_RX_TEST_LEN) { rc = ble_ll_dtm_rx_test(cmdbuf, true); } break; case BLE_HCI_OCF_LE_ENH_TX_TEST: - if (len == BLE_HCI_LE_ENH_TX_TEST_LEN) { - rc = ble_ll_dtm_tx_test(cmdbuf, true); - } + rc = ble_ll_dtm_tx_test(cmdbuf, len, true); break; #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index fa9b013f3..29742c277 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -1793,7 +1793,7 @@ done: } #endif -#if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) +#if MYNEWT_VAL(BLE_LL_DTM) int ble_ll_sched_dtm(struct ble_ll_sched_item *sch) { int rc; diff --git a/nimble/controller/src/ble_ll_supp_cmd.c b/nimble/controller/src/ble_ll_supp_cmd.c index 74ad601cc..8f62ed30b 100644 --- a/nimble/controller/src/ble_ll_supp_cmd.c +++ b/nimble/controller/src/ble_ll_supp_cmd.c @@ -137,7 +137,7 @@ #endif #define BLE_SUPP_CMD_LE_READ_SUPP_STATES (1 << 3) -#if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) +#if MYNEWT_VAL(BLE_LL_DTM) #define BLE_SUPP_CMD_LE_RX_TEST (1 << 4) #define BLE_SUPP_CMD_LE_TX_TEST (1 << 5) #define BLE_SUPP_CMD_LE_TEST_END (1 << 6) @@ -233,7 +233,7 @@ #define BLE_SUPP_CMD_LE_SET_PHY (0 << 6) #endif -#if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) +#if MYNEWT_VAL(BLE_LL_DTM) #define BLE_SUPP_CMD_LE_ENHANCED_RX_TEST (1 << 7) #else #define BLE_SUPP_CMD_LE_ENHANCED_RX_TEST (0 << 7) @@ -252,7 +252,7 @@ ) /* Octet 36 */ -#if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) +#if MYNEWT_VAL(BLE_LL_DTM) #define BLE_SUPP_CMD_LE_ENHANCED_TX_TEST (1 << 0) #else #define BLE_SUPP_CMD_LE_ENHANCED_TX_TEST (0 << 0) diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 91b4bdc8a..e3c6b76ca 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -296,6 +296,24 @@ syscfg.defs: description: > Enables HCI Test commands needed for Bluetooth SIG certification value: MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) + BLE_LL_DTM_EXTENSIONS_ENABLE: + description: > + Enables non-standard extensions to HCI test commands. Once enabled, + HCI_LE_Transmitter_Test accepts extra parameters in addition to + those defined in Core specification + interval (2 octets) interval between packets (usecs), overrides + standard interval + pkt_count (2 octets) number of packets to transmit, controller + will automatically stop sending packets + after given number of packets was sent + Setting either of these parameters to 0 will configure for default + behavior, as per Core specification. + If specified interval is shorter then allowed by specification it + will be ignored. + Extended parameters shall immediately follow standard parameters. + Controller can accept both standard and extended version of command + depending on specified HCI command length. + value: 0 BLE_LL_VND_EVENT_ON_ASSERT: description: > diff --git a/nimble/drivers/nrf52/src/ble_phy.c b/nimble/drivers/nrf52/src/ble_phy.c index a08ca883f..3b62660a1 100644 --- a/nimble/drivers/nrf52/src/ble_phy.c +++ b/nimble/drivers/nrf52/src/ble_phy.c @@ -2061,7 +2061,7 @@ ble_phy_resolv_list_disable(void) } #endif -#if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) +#if MYNEWT_VAL(BLE_LL_DTM) void ble_phy_enable_dtm(void) { /* When DTM is enabled we need to disable whitening as per diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index 8fb670067..4fde49794 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -517,8 +517,8 @@ #define MYNEWT_VAL_BLE_LL_DBG_HCI_EV_PIN (-1) #endif -#ifndef MYNEWT_VAL_BLE_LL_DIRECT_TEST_MODE -#define MYNEWT_VAL_BLE_LL_DIRECT_TEST_MODE (0) +#ifndef MYNEWT_VAL_BLE_LL_DTM +#define MYNEWT_VAL_BLE_LL_DTM (0) #endif /* Overridden by nimble/controller (defined by nimble/controller) */