mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-08-05 09:37:53 +00:00
nimble/ll: Add support for custom DTM extensions
This allows to enable custom extensions for DTM which currently allow to override interval between test packets and number of packets to be transmitted. See description of new syscfg setting for details. This is not enabled by default since it extends HCI command defined by Core specification so we need to be compliant by default. However even if extensions are enabled, NimBLE still accepts HCI command as defined in Core specification but also accepts extended one.
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <stdbool.h>
|
||||
#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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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: >
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) */
|
||||
|
||||
Reference in New Issue
Block a user