Add support for dtm related functions

This commit is contained in:
Rahul Tank
2024-02-29 16:23:47 +05:30
committed by Abhinav Kudnar
parent c7b5c73456
commit 396f1e6ebd
7 changed files with 319 additions and 1 deletions
+4
View File
@@ -197,6 +197,10 @@ int ble_gap_set_chan_select(uint8_t select);
#endif
void ble_gap_rx_test_evt(const void *buf, uint8_t len);
void ble_gap_tx_test_evt(const void *buf, uint8_t len);
void ble_gap_end_test_evt(const void *buf, uint8_t len);
#ifdef __cplusplus
}
#endif
+96
View File
@@ -159,6 +159,13 @@ struct hci_conn_update;
#define BLE_GAP_EVENT_BIGINFO_REPORT 30
#define BLE_GAP_EVENT_REATTEMPT_COUNT 31
#define BLE_GAP_EVENT_AUTHORIZE 32
#define BLE_GAP_EVENT_TEST_UPDATE 33
/* DTM events */
#define BLE_GAP_DTM_TX_START_EVT 0
#define BLE_GAP_DTM_RX_START_EVT 1
#define BLE_GAP_DTM_END_EVT 2
/*** Reason codes for the subscribe GAP event. */
@@ -1212,6 +1219,30 @@ struct ble_gap_event {
uint8_t count;
} reattempt_cnt;
#endif
/**
* Represent a event for DTM test results
*
* Valid for the following event types:
* o BLE_GAP_EVENT_TEST_UPDATE
*/
struct {
/* Indicate DTM operation status */
uint8_t status;
/* DTM state change event. Can be following constants:
* o BLE_GAP_DTM_TX_START_EVT
* o BLE_GAP_DTM_RX_START_EVT
* o BLE_GAP_DTM_END_EVT
*/
uint8_t update_evt;
/* Number of packets received.
*
* Valid only for BLE_GAP_DTM_END_EVT
* shall be 0 for a transmitter.
*/
uint8_t num_pkt;
} dtm_state;
};
};
@@ -2740,6 +2771,71 @@ int ble_gap_set_path_loss_reporting_param(uint16_t conn_handle, uint8_t high_thr
*/
int ble_gap_set_data_related_addr_change_param(uint8_t adv_handle, uint8_t change_reason);
/**
* Start a test where the DUT generates reference packets at a fixed interval.
*
* @param tx_chan Channel for sending test data,
* tx_channel = (Frequency -2402)/2, tx_channel range = 0x00-0x27,
* Frequency range = 2402 MHz to 2480 MHz.
*
* @param test_data_len Length in bytes of payload data in each packet
* @param payload Packet Payload type. Valid range: 0x00 - 0x07
*
* @return 0 on success; nonzero on failure
*/
int ble_gap_dtm_tx_start(uint8_t tx_chan, uint8_t test_data_len, uint8_t payload);
/**
* Start a test where the DUT receives test reference packets at a fixed interval.
*
* @param rx_chan Channel for test data reception,
* rx_channel = (Frequency -2402)/2, tx_channel range = 0x00-0x27,
* Frequency range = 2402 MHz to 2480 MHz.
*
* @return 0 on success; nonzero on failure
*/
int ble_gap_dtm_rx_start(uint8_t rx_chan);
/**
* Stop any test which is in progress
*
* @return 0 on success; nonzero on failure
*/
int ble_gap_dtm_stop(void);
/**
* Start a test where the DUT generates reference packets at a fixed interval.
*
* @param tx_chan Channel for sending test data,
* tx_channel = (Frequency -2402)/2, tx_channel range = 0x00-0x27,
* Frequency range: 2402 MHz to 2480 MHz
*
* @param test_data_len Length in bytes of payload data in each packet
* @param payload Packet payload type. Valid range: 0x00 - 0x07
* @param phy Phy used by transmitter 1M phy: 0x01, 2M phy:0x02, coded phy:0x03.
*
* @return 0 on sucess; nonzero on failure
*/
int ble_gap_dtm_enh_tx_start(uint8_t tx_chan, uint8_t test_data_len, uint8_t payload,
uint8_t phy);
/**
* Start a test where the DUT receives test reference packets at fixed interval
*
* @param rx_chan Channel for test data reception,
* rx_channel = (Frequency -2402)/2, tx_channel range = 0x00-0x27,
* Frequency range: 2402 MHz to 2480 MHz
*
* @param index modulation index, 0x00:standard modulation index, 0x01:stable modulation index
* @param phy Phy type used by the receiver, 1M phy: 0x01, 2M phy:0x02, coded phy:0x03
*
* @return 0 on success; nonzero on failure
*/
int ble_gap_dtm_enh_rx_start(uint8_t rx_chan, uint8_t index, uint8_t phy);
#ifdef __cplusplus
}
#endif
+90
View File
@@ -7153,6 +7153,65 @@ ble_gap_authorize_event(uint16_t conn_handle, uint16_t attr_handle,
return BLE_GAP_AUTHORIZE_REJECT;
}
void
ble_gap_rx_test_evt(const void *buf, uint8_t len)
{
struct ble_gap_event event;
struct ble_hci_ev_command_complete *cmd_complete = (void *) buf;
uint8_t status;
status = cmd_complete->status;
memset(&event, 0, sizeof event);
event.type = BLE_GAP_EVENT_TEST_UPDATE;
event.dtm_state.status = status ;
event.dtm_state.update_evt = BLE_GAP_DTM_RX_START_EVT;
event.dtm_state.num_pkt = 0;
ble_gap_event_listener_call(&event);
}
void
ble_gap_tx_test_evt(const void *buf, uint8_t len)
{
struct ble_gap_event event;
struct ble_hci_ev_command_complete *cmd_complete = (void *) buf;
uint8_t status;
status = cmd_complete->status;
memset(&event, 0, sizeof event);
event.type = BLE_GAP_EVENT_TEST_UPDATE;
event.dtm_state.status = status ;
event.dtm_state.update_evt = BLE_GAP_DTM_TX_START_EVT;
event.dtm_state.num_pkt = 0;
ble_gap_event_listener_call(&event);
}
void
ble_gap_end_test_evt(const void *buf, uint8_t len)
{
struct ble_gap_event event;
struct ble_hci_ev_command_complete *cmd_complete = (void *) buf;
uint8_t status, *ptr;
uint16_t num_pkt;
status = cmd_complete->status;
ptr = (uint8_t *)cmd_complete->return_params;
num_pkt = htole16(*ptr);
memset(&event, 0, sizeof event);
event.type = BLE_GAP_EVENT_TEST_UPDATE;
event.dtm_state.status = status ;
event.dtm_state.update_evt = BLE_GAP_DTM_END_EVT;
event.dtm_state.num_pkt = num_pkt;
ble_gap_event_listener_call(&event);
}
/*****************************************************************************
* $preempt *
*****************************************************************************/
@@ -7665,6 +7724,37 @@ ble_gap_set_data_related_addr_change_param(uint8_t adv_handle, uint8_t change_re
return ble_hs_hci_util_set_data_addr_change(adv_handle, change_reason);
}
int
ble_gap_dtm_tx_start(uint8_t tx_chan, uint8_t test_data_len, uint8_t payload)
{
return ble_hs_hci_dtm_tx_start(tx_chan, test_data_len, payload);
}
int
ble_gap_dtm_rx_start(uint8_t rx_chan)
{
return ble_hs_hci_dtm_rx_start(rx_chan);
}
int
ble_gap_dtm_stop(void)
{
return ble_hs_hci_dtm_stop();
}
int
ble_gap_dtm_enh_tx_start(uint8_t tx_chan, uint8_t test_data_len, uint8_t payload,
uint8_t phy)
{
return ble_hs_hci_dtm_enh_tx_start(tx_chan, test_data_len, payload, phy);
}
int
ble_gap_dtm_enh_rx_start(uint8_t rx_chan, uint8_t index, uint8_t phy)
{
return ble_hs_hci_dtm_enh_rx_start(rx_chan, index, phy);
}
void
ble_gap_deinit(void)
{
+11
View File
@@ -400,6 +400,17 @@ ble_hs_hci_rx_evt(uint8_t *hci_ev, void *arg)
switch (ev->opcode) {
case BLE_HCI_EVCODE_COMMAND_COMPLETE:
enqueue = (cmd_complete->opcode == BLE_HCI_OPCODE_NOP);
/* Check for BLE transmit opcodes which come in command complete */
switch(cmd_complete->opcode) {
case BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RX_TEST):
case BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_TX_TEST):
case BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_TEST_END):
case BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RX_TEST_V2):
case BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_TX_TEST_V2):
enqueue = 1;
break;
}
break;
case BLE_HCI_EVCODE_COMMAND_STATUS:
enqueue = (cmd_status->opcode == BLE_HCI_OPCODE_NOP);
+41 -1
View File
@@ -67,6 +67,10 @@ static ble_hs_hci_evt_fn ble_hs_hci_evt_le_meta;
static ble_hs_hci_evt_fn ble_hs_hci_evt_vs;
#endif
static ble_hs_hci_evt_fn ble_hs_hci_evt_rx_test;
static ble_hs_hci_evt_fn ble_hs_hci_evt_tx_test;
static ble_hs_hci_evt_fn ble_hs_hci_evt_end_test;
typedef int ble_hs_hci_evt_le_fn(uint8_t subevent, const void *data,
unsigned int len);
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_adv_rpt;
@@ -127,6 +131,11 @@ static const struct ble_hs_hci_evt_dispatch_entry ble_hs_hci_evt_dispatch[] = {
#if MYNEWT_VAL(BLE_HCI_VS)
{ BLE_HCI_EVCODE_VS, ble_hs_hci_evt_vs },
#endif
{ BLE_HCI_OCF_LE_RX_TEST, ble_hs_hci_evt_rx_test },
{ BLE_HCI_OCF_LE_TX_TEST, ble_hs_hci_evt_tx_test },
{ BLE_HCI_OCF_LE_TEST_END, ble_hs_hci_evt_end_test },
{ BLE_HCI_OCF_LE_RX_TEST_V2, ble_hs_hci_evt_rx_test },
{ BLE_HCI_OCF_LE_TX_TEST_V2, ble_hs_hci_evt_tx_test },
};
#define BLE_HS_HCI_EVT_DISPATCH_SZ \
@@ -410,6 +419,30 @@ ble_hs_hci_evt_vs(uint8_t event_code, const void *data, unsigned int len)
}
#endif
static int
ble_hs_hci_evt_rx_test(uint8_t event_code, const void *data, unsigned int len)
{
ble_gap_rx_test_evt(data, len);
return 0;
}
static int
ble_hs_hci_evt_tx_test(uint8_t event_code, const void *data, unsigned int len)
{
ble_gap_tx_test_evt(data, len);
return 0;
}
static int
ble_hs_hci_evt_end_test(uint8_t event_code, const void *data, unsigned int len)
{
ble_gap_end_test_evt(data, len);
return 0;
}
static int
ble_hs_hci_evt_le_meta(uint8_t event_code, const void *data, unsigned int len)
{
@@ -1066,8 +1099,15 @@ ble_hs_hci_evt_process(struct ble_hci_ev *ev)
/* Count events received */
STATS_INC(ble_hs_stats, hci_event);
if(ev->opcode == BLE_HCI_EVCODE_COMMAND_COMPLETE) {
/* Check if this Command complete has a parsable opcode */
struct ble_hci_ev_command_complete *cmd_complete = (void *) ev->data;
entry = ble_hs_hci_evt_dispatch_find(cmd_complete->opcode);
}
else {
entry = ble_hs_hci_evt_dispatch_find(ev->opcode);
}
entry = ble_hs_hci_evt_dispatch_find(ev->opcode);
if (entry == NULL) {
STATS_INC(ble_hs_stats, hci_unknown_event);
rc = BLE_HS_ENOTSUP;
+8
View File
@@ -126,6 +126,14 @@ int ble_hs_hci_frag_num_mbufs(void);
int ble_hs_hci_frag_num_mbufs_free(void);
int ble_hs_hci_util_set_data_addr_change(uint8_t adv_handle, uint8_t change_reason);
int ble_hs_hci_dtm_tx_start(uint8_t tx_chan, uint8_t test_data_len, uint8_t payload);
int ble_hs_hci_dtm_rx_start(uint8_t rx_chan);
int ble_hs_hci_dtm_enh_rx_start(uint8_t rx_chan, uint8_t index, uint8_t phy);
int ble_hs_hci_dtm_enh_tx_start(uint8_t tx_chan, uint8_t test_data_len,
uint8_t payload, uint8_t phy);
int ble_hs_hci_dtm_stop(void);
#ifdef __cplusplus
}
#endif
+69
View File
@@ -291,3 +291,72 @@ ble_hs_hci_util_set_data_addr_change(uint8_t adv_handle, uint8_t change_reason)
return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0);
}
int
ble_hs_hci_dtm_tx_start(const uint8_t tx_chan, const uint8_t test_data_len,
const uint8_t payload)
{
struct ble_hci_le_tx_test_cp cmd;
uint16_t opcode;
opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_TX_TEST);
cmd.tx_chan = tx_chan;
cmd.test_data_len = test_data_len;
cmd.payload = payload;
return ble_hs_hci_cmd_tx_no_rsp(opcode, &cmd, sizeof(cmd));
}
int
ble_hs_hci_dtm_rx_start(const uint8_t rx_chan)
{
struct ble_hci_le_rx_test_cp cmd;
uint16_t opcode;
opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RX_TEST);
cmd.rx_chan = rx_chan;
return ble_hs_hci_cmd_tx_no_rsp(opcode, &cmd, sizeof(cmd));
}
int
ble_hs_hci_dtm_stop(void)
{
return ble_hs_hci_cmd_tx_no_rsp(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_TEST_END),
NULL, 0);
}
int
ble_hs_hci_dtm_enh_tx_start(const uint8_t tx_chan, const uint8_t test_data_len,
const uint8_t payload, const uint8_t phy)
{
struct ble_hci_le_tx_test_v2_cp cmd;
uint16_t opcode;
opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_TX_TEST_V2);
cmd.tx_chan = tx_chan;
cmd.test_data_len = test_data_len;
cmd.payload = payload;
cmd.phy = phy;
return ble_hs_hci_cmd_tx_no_rsp(opcode, &cmd, sizeof(cmd));
}
int
ble_hs_hci_dtm_enh_rx_start(const uint8_t rx_chan, const uint8_t index,
const uint8_t phy)
{
struct ble_hci_le_rx_test_v2_cp cmd;
uint16_t opcode;
opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RX_TEST_V2);
cmd.rx_chan = rx_chan;
cmd.index = index;
cmd.phy = phy;
return ble_hs_hci_cmd_tx_no_rsp(opcode, &cmd, sizeof(cmd));
}