mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-06-05 21:04:49 +00:00
feat(nimble): Add support to 6.2 BLE HCI Command Event(FSU, UTP over OTA)
This commit is contained in:
@@ -186,6 +186,8 @@ struct hci_conn_update;
|
||||
#define BLE_GAP_EVENT_MONITOR_ADV_REPORT 52
|
||||
|
||||
#define BLE_GAP_EVENT_CACHE_ASSOC 53
|
||||
#define BLE_GAP_EVENT_FRAME_SPACE_UPDATE 54
|
||||
#define BLE_GAP_EVENT_UTP_RECEIVE 55
|
||||
|
||||
/* DTM events */
|
||||
#define BLE_GAP_DTM_TX_START_EVT 0
|
||||
@@ -2038,6 +2040,54 @@ struct ble_gap_event {
|
||||
|
||||
} monitor_adv_report;
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_FRAME_SPACE_UPDATE)
|
||||
/*
|
||||
* Represents a change in the Inter-Frame Space (IFS).
|
||||
*/
|
||||
struct {
|
||||
/* The status of the frame space update attempt (0 on success). */
|
||||
int status;
|
||||
|
||||
/* The handle of the connection where the update occurred. */
|
||||
uint16_t conn_handle;
|
||||
|
||||
/*
|
||||
* Indicates whether the local Host initiated the update.
|
||||
* 0: Controller initiated
|
||||
* 1: Local Host initiated
|
||||
*/
|
||||
uint8_t initiator;
|
||||
|
||||
/* The new frame space value in microseconds. */
|
||||
uint16_t frame_space;
|
||||
|
||||
/* Bitmask indicating the PHYs to which the frame space applies. */
|
||||
uint8_t phys;
|
||||
|
||||
/* Bitmask indicating the spacing types. */
|
||||
uint16_t spacing_types;
|
||||
} frame_space_update;
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_UTP_OTA)
|
||||
/*
|
||||
* Represents a received Unified Test Protocol (UTP) packet.
|
||||
*/
|
||||
struct {
|
||||
/* The connection handle associated with the packet.
|
||||
* Note: Currently set to BLE_HS_CONN_HANDLE_NONE as the
|
||||
* controller event does not provide a handle.
|
||||
*/
|
||||
uint16_t conn_handle;
|
||||
|
||||
/* The length of the UTP data payload. */
|
||||
uint8_t len;
|
||||
|
||||
/* Pointer to the UTP data payload. */
|
||||
const uint8_t *data;
|
||||
} utp_receive;
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
@@ -4175,6 +4225,24 @@ int ble_gap_read_local_irk(uint8_t * out_irk);
|
||||
int ble_gap_set_host_feat(uint8_t bit_num,uint8_t bit_val);
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_FRAME_SPACE_UPDATE)
|
||||
/* * Request a Frame Space Update.
|
||||
* phys: Bitmask of PHYs (0=1M, 1=2M, 2=Coded)
|
||||
* spacing_types: Bitmask of spacing types to update
|
||||
*/
|
||||
int ble_gap_frame_space_update(uint16_t conn_handle,
|
||||
uint16_t frame_space_min,
|
||||
uint16_t frame_space_max,
|
||||
uint8_t phys,
|
||||
uint16_t spacing_types);
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_UTP_OTA)
|
||||
int ble_gap_enable_utp_ota_mode(uint8_t enable);
|
||||
|
||||
int ble_gap_utp_send(uint8_t len, const uint8_t *data);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2501,6 +2501,59 @@ ble_gap_rx_rd_monitor_adv_report(const struct ble_hci_ev_le_subev_monitor_adv_re
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_FRAME_SPACE_UPDATE)
|
||||
void
|
||||
ble_gap_rx_frame_space_update_complete(const struct ble_hci_ev_le_subev_frame_space_update_complete *ev)
|
||||
{
|
||||
#if NIMBLE_BLE_CONNECT
|
||||
struct ble_gap_event event;
|
||||
uint16_t conn_handle;
|
||||
|
||||
conn_handle = le16toh(ev->conn_handle);
|
||||
|
||||
memset(&event, 0, sizeof(event));
|
||||
event.type = BLE_GAP_EVENT_FRAME_SPACE_UPDATE;
|
||||
|
||||
event.frame_space_update.status = ev->status;
|
||||
event.frame_space_update.conn_handle = conn_handle;
|
||||
event.frame_space_update.initiator = ev->initiator;
|
||||
event.frame_space_update.frame_space = le16toh(ev->frame_space);
|
||||
event.frame_space_update.phys = ev->phys;
|
||||
event.frame_space_update.spacing_types = le16toh(ev->spacing_types);
|
||||
|
||||
ble_gap_event_listener_call(&event);
|
||||
ble_gap_call_conn_event_cb(&event, conn_handle);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_UTP_OTA)
|
||||
void
|
||||
ble_gap_rx_utp_receive(const struct ble_hci_ev_le_subev_utp_receive *ev, uint8_t len)
|
||||
{
|
||||
struct ble_gap_event event;
|
||||
const uint8_t *data_ptr;
|
||||
|
||||
if (len < sizeof(*ev)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (len < (sizeof(*ev) + ev->len)) {
|
||||
return;
|
||||
}
|
||||
|
||||
data_ptr = (const uint8_t *)ev + sizeof(*ev);
|
||||
|
||||
memset(&event, 0, sizeof(event));
|
||||
event.type = BLE_GAP_EVENT_UTP_RECEIVE;
|
||||
event.utp_receive.conn_handle = BLE_HS_CONN_HANDLE_NONE;
|
||||
event.utp_receive.len = ev->len;
|
||||
event.utp_receive.data = data_ptr;
|
||||
|
||||
ble_gap_event_listener_call(&event);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
ble_gap_rx_adv_report(struct ble_gap_disc_desc *desc)
|
||||
{
|
||||
@@ -10954,3 +11007,92 @@ bool ble_gap_rpa_resolve(uint8_t *rpa, uint8_t *ida, uint8_t *addr_type)
|
||||
|
||||
return false; /* No match */
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(BLE_FRAME_SPACE_UPDATE)
|
||||
int
|
||||
ble_gap_frame_space_update(uint16_t conn_handle,
|
||||
uint16_t frame_space_min,
|
||||
uint16_t frame_space_max,
|
||||
uint8_t phys,
|
||||
uint16_t spacing_types)
|
||||
{
|
||||
#if NIMBLE_BLE_CONNECT
|
||||
struct ble_hci_le_frame_space_update_cp cmd;
|
||||
struct ble_hs_conn *conn;
|
||||
|
||||
ble_hs_lock();
|
||||
conn = ble_hs_conn_find(conn_handle);
|
||||
ble_hs_unlock();
|
||||
|
||||
if (conn == NULL) {
|
||||
return BLE_HS_ENOTCONN;
|
||||
}
|
||||
|
||||
if (frame_space_min > 10000 || frame_space_max > 10000) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
if (frame_space_min > frame_space_max) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
if ((phys & ~0x07) || (phys == 0)) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
if ((spacing_types & ~0x1F) || (spacing_types == 0)) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
cmd.conn_handle = htole16(conn_handle);
|
||||
cmd.frame_space_min = htole16(frame_space_min);
|
||||
cmd.frame_space_max = htole16(frame_space_max);
|
||||
cmd.phys = phys;
|
||||
cmd.spacing_types = htole16(spacing_types);
|
||||
|
||||
return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
|
||||
BLE_HCI_OCF_LE_FRAME_SPACE_UPDATE), &cmd, sizeof(cmd), NULL, 0);
|
||||
#else
|
||||
return BLE_HS_ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_UTP_OTA)
|
||||
int
|
||||
ble_gap_enable_utp_ota_mode(uint8_t enable)
|
||||
{
|
||||
struct ble_hci_le_enable_utp_ota_mode_cp cmd;
|
||||
|
||||
if (enable > 1) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
cmd.enable = enable;
|
||||
|
||||
return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
|
||||
BLE_HCI_OCF_LE_ENABLE_UTP_OTA_MODE), &cmd, sizeof(cmd), NULL, 0);
|
||||
}
|
||||
|
||||
int
|
||||
ble_gap_utp_send(uint8_t len, const uint8_t *data)
|
||||
{
|
||||
uint8_t buf[sizeof(struct ble_hci_le_utp_send_cp) + 254];
|
||||
struct ble_hci_le_utp_send_cp *cmd = (void *)buf;
|
||||
|
||||
if (len == 0 || len > 254) {
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
|
||||
cmd->len = len;
|
||||
|
||||
if (data == NULL)
|
||||
{
|
||||
return BLE_HS_EINVAL;
|
||||
}
|
||||
memcpy(buf + sizeof(*cmd), data, len);
|
||||
|
||||
return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
|
||||
BLE_HCI_OCF_LE_UTP_SEND), cmd, sizeof(*cmd) + len, NULL, 0);
|
||||
}
|
||||
#endif
|
||||
@@ -208,6 +208,14 @@ void ble_gap_rx_rd_all_remote_feat(const struct ble_hci_ev_le_subev_rd_all_rem_f
|
||||
void ble_gap_rx_rd_monitor_adv_report(const struct ble_hci_ev_le_subev_monitor_adv_report *ev);
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_FRAME_SPACE_UPDATE)
|
||||
void ble_gap_rx_frame_space_update_complete(const struct ble_hci_ev_le_subev_frame_space_update_complete *ev);
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_UTP_OTA)
|
||||
void ble_gap_rx_utp_receive(const struct ble_hci_ev_le_subev_utp_receive *ev, uint8_t len);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -215,6 +215,12 @@ static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_cis_estab_v2;
|
||||
#if NIMBLE_BLE_CONNECT
|
||||
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_rd_all_rem_feat;
|
||||
#endif
|
||||
#if MYNEWT_VAL(BLE_FRAME_SPACE_UPDATE)
|
||||
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_frame_space_update;
|
||||
#endif
|
||||
#if MYNEWT_VAL(BLE_UTP_OTA)
|
||||
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_utp_receive;
|
||||
#endif
|
||||
#if MYNEWT_VAL(BLE_MONITOR_ADV)
|
||||
static ble_hs_hci_evt_le_fn ble_hci_ev_le_subev_monitor_adv_report;
|
||||
#endif
|
||||
@@ -364,6 +370,12 @@ static ble_hs_hci_evt_le_fn * const ble_hs_hci_evt_le_dispatch[] = {
|
||||
#if MYNEWT_VAL(BLE_MONITOR_ADV)
|
||||
[BLE_HCI_LE_SUBEV_MONITOR_ADV_REPORT] = ble_hci_ev_le_subev_monitor_adv_report,
|
||||
#endif
|
||||
#if MYNEWT_VAL(BLE_FRAME_SPACE_UPDATE)
|
||||
[BLE_HCI_LE_SUBEV_FRAME_SPACE_UPDATE_COMPLETE] = ble_hs_hci_evt_le_frame_space_update,
|
||||
#endif
|
||||
#if MYNEWT_VAL(BLE_UTP_OTA)
|
||||
[BLE_HCI_LE_SUBEV_UTP_RECEIVE] = ble_hs_hci_evt_le_utp_receive,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -1858,6 +1870,39 @@ ble_hs_hci_evt_le_rd_all_rem_feat(uint8_t subevent, const void *data,
|
||||
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_FRAME_SPACE_UPDATE)
|
||||
static int
|
||||
ble_hs_hci_evt_le_frame_space_update(uint8_t subevent, const void *data, unsigned int len)
|
||||
{
|
||||
/* FSU is strictly a connection-oriented feature.
|
||||
* If connections are disabled, ignore the event or return error.
|
||||
*/
|
||||
#if NIMBLE_BLE_CONNECT
|
||||
if (len != sizeof(struct ble_hci_ev_le_subev_frame_space_update_complete)) {
|
||||
return BLE_HS_EBADDATA;
|
||||
}
|
||||
ble_gap_rx_frame_space_update_complete(data);
|
||||
return 0;
|
||||
#else
|
||||
return BLE_HS_ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_UTP_OTA)
|
||||
static int
|
||||
ble_hs_hci_evt_le_utp_receive(uint8_t subevent, const void *data, unsigned int len)
|
||||
{
|
||||
const struct ble_hci_ev_le_subev_utp_receive *ev = data;
|
||||
|
||||
if (len < sizeof(*ev) || len != (sizeof(*ev) + ev->len)) {
|
||||
return BLE_HS_EBADDATA;
|
||||
}
|
||||
ble_gap_rx_utp_receive(data, (uint8_t)len);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_MONITOR_ADV)
|
||||
static int
|
||||
ble_hci_ev_le_subev_monitor_adv_report(uint8_t subevent, const void *data,
|
||||
|
||||
@@ -1583,6 +1583,25 @@ struct ble_hci_le_enable_monitor_adv_cp {
|
||||
uint8_t enable;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define BLE_HCI_OCF_LE_FRAME_SPACE_UPDATE (0x009D)
|
||||
struct ble_hci_le_frame_space_update_cp {
|
||||
uint16_t conn_handle;
|
||||
uint16_t frame_space_min;
|
||||
uint16_t frame_space_max;
|
||||
uint8_t phys;
|
||||
uint16_t spacing_types;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define BLE_HCI_OCF_LE_ENABLE_UTP_OTA_MODE (0x009F)
|
||||
struct ble_hci_le_enable_utp_ota_mode_cp {
|
||||
uint8_t enable;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define BLE_HCI_OCF_LE_UTP_SEND (0x00A0)
|
||||
struct ble_hci_le_utp_send_cp {
|
||||
uint8_t len;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* --- Vendor specific commands (OGF 0x003F) */
|
||||
/* Read Random Static Address */
|
||||
#define BLE_HCI_OCF_VS_RD_STATIC_ADDR (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x0001))
|
||||
@@ -2608,6 +2627,23 @@ struct ble_hci_ev_le_subev_monitor_adv_report {
|
||||
uint8_t condition;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define BLE_HCI_LE_SUBEV_FRAME_SPACE_UPDATE_COMPLETE (0x35)
|
||||
struct ble_hci_ev_le_subev_frame_space_update_complete {
|
||||
uint8_t subev_code;
|
||||
uint8_t status;
|
||||
uint16_t conn_handle;
|
||||
uint8_t initiator;
|
||||
uint16_t frame_space;
|
||||
uint8_t phys;
|
||||
uint16_t spacing_types;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define BLE_HCI_LE_SUBEV_UTP_RECEIVE (0x36)
|
||||
struct ble_hci_ev_le_subev_utp_receive {
|
||||
uint8_t subev_code;
|
||||
uint8_t len;
|
||||
} __attribute__((packed));
|
||||
|
||||
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
|
||||
// LE vendor hci event
|
||||
#define BLE_HCI_LE_SUBEV_DISCARD_REPORT_EVT 0XF0
|
||||
|
||||
Reference in New Issue
Block a user