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_MONITOR_ADV_REPORT 52
|
||||||
|
|
||||||
#define BLE_GAP_EVENT_CACHE_ASSOC 53
|
#define BLE_GAP_EVENT_CACHE_ASSOC 53
|
||||||
|
#define BLE_GAP_EVENT_FRAME_SPACE_UPDATE 54
|
||||||
|
#define BLE_GAP_EVENT_UTP_RECEIVE 55
|
||||||
|
|
||||||
/* DTM events */
|
/* DTM events */
|
||||||
#define BLE_GAP_DTM_TX_START_EVT 0
|
#define BLE_GAP_DTM_TX_START_EVT 0
|
||||||
@@ -2038,6 +2040,54 @@ struct ble_gap_event {
|
|||||||
|
|
||||||
} monitor_adv_report;
|
} monitor_adv_report;
|
||||||
#endif
|
#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);
|
int ble_gap_set_host_feat(uint8_t bit_num,uint8_t bit_val);
|
||||||
#endif
|
#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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -2501,6 +2501,59 @@ ble_gap_rx_rd_monitor_adv_report(const struct ble_hci_ev_le_subev_monitor_adv_re
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
void
|
||||||
ble_gap_rx_adv_report(struct ble_gap_disc_desc *desc)
|
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 */
|
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);
|
void ble_gap_rx_rd_monitor_adv_report(const struct ble_hci_ev_le_subev_monitor_adv_report *ev);
|
||||||
#endif
|
#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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -215,6 +215,12 @@ static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_cis_estab_v2;
|
|||||||
#if NIMBLE_BLE_CONNECT
|
#if NIMBLE_BLE_CONNECT
|
||||||
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_rd_all_rem_feat;
|
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_rd_all_rem_feat;
|
||||||
#endif
|
#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)
|
#if MYNEWT_VAL(BLE_MONITOR_ADV)
|
||||||
static ble_hs_hci_evt_le_fn ble_hci_ev_le_subev_monitor_adv_report;
|
static ble_hs_hci_evt_le_fn ble_hci_ev_le_subev_monitor_adv_report;
|
||||||
#endif
|
#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)
|
#if MYNEWT_VAL(BLE_MONITOR_ADV)
|
||||||
[BLE_HCI_LE_SUBEV_MONITOR_ADV_REPORT] = ble_hci_ev_le_subev_monitor_adv_report,
|
[BLE_HCI_LE_SUBEV_MONITOR_ADV_REPORT] = ble_hci_ev_le_subev_monitor_adv_report,
|
||||||
#endif
|
#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
|
#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)
|
#if MYNEWT_VAL(BLE_MONITOR_ADV)
|
||||||
static int
|
static int
|
||||||
ble_hci_ev_le_subev_monitor_adv_report(uint8_t subevent, const void *data,
|
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;
|
uint8_t enable;
|
||||||
} __attribute__((packed));
|
} __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) */
|
/* --- Vendor specific commands (OGF 0x003F) */
|
||||||
/* Read Random Static Address */
|
/* Read Random Static Address */
|
||||||
#define BLE_HCI_OCF_VS_RD_STATIC_ADDR (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x0001))
|
#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;
|
uint8_t condition;
|
||||||
} __attribute__((packed));
|
} __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)
|
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
|
||||||
// LE vendor hci event
|
// LE vendor hci event
|
||||||
#define BLE_HCI_LE_SUBEV_DISCARD_REPORT_EVT 0XF0
|
#define BLE_HCI_LE_SUBEV_DISCARD_REPORT_EVT 0XF0
|
||||||
|
|||||||
Reference in New Issue
Block a user