nimble/gap: Add API to manage LE PHY
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/c7aa21c3 Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/c7aa21c3 Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/c7aa21c3 Branch: refs/heads/bluetooth5 Commit: c7aa21c3f49e01393af9c94f67bcd62a5e45f447 Parents: 2210e7e Author: Åukasz Rymanowski <[email protected]> Authored: Tue Apr 11 11:22:17 2017 +0200 Committer: Åukasz Rymanowski <[email protected]> Committed: Wed Apr 19 11:04:09 2017 +0200 ---------------------------------------------------------------------- net/nimble/host/include/host/ble_gap.h | 35 +++++++++++ net/nimble/host/src/ble_gap.c | 94 +++++++++++++++++++++++++++++ net/nimble/host/src/ble_gap_priv.h | 1 + net/nimble/host/src/ble_hs_hci_evt.c | 23 +++++++ net/nimble/include/nimble/hci_common.h | 13 ++++ 5 files changed, 166 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c7aa21c3/net/nimble/host/include/host/ble_gap.h ---------------------------------------------------------------------- diff --git a/net/nimble/host/include/host/ble_gap.h b/net/nimble/host/include/host/ble_gap.h index f40789a..b32071d 100644 --- a/net/nimble/host/include/host/ble_gap.h +++ b/net/nimble/host/include/host/ble_gap.h @@ -111,6 +111,7 @@ struct hci_conn_update; #define BLE_GAP_EVENT_SUBSCRIBE 14 #define BLE_GAP_EVENT_MTU 15 #define BLE_GAP_EVENT_IDENTITY_RESOLVED 16 +#define BLE_GAP_EVENT_PHY_UPDATE_COMPLETE 17 /*** Reason codes for the subscribe GAP event. */ @@ -517,6 +518,24 @@ struct ble_gap_event { /** The handle of the relevant connection. */ uint16_t conn_handle; } identity_resolved; + + /** + * Represents a change of PHY. This is issue after successful + * change on PHY. + */ + struct { + int status; + uint16_t conn_handle; + + /** + * Indicates enabled TX/RX PHY. Possible values: + * o BLE_GAP_LE_PHY_1M + * o BLE_GAP_LE_PHY_2M + * o BLE_GAP_LE_PHY_CODED + */ + uint8_t tx_phy; + uint8_t rx_phy; + } phy_updated; }; }; @@ -570,6 +589,22 @@ int ble_gap_conn_rssi(uint16_t conn_handle, int8_t *out_rssi); #define BLE_GAP_PRIVATE_MODE_DEVICE 1 int ble_gap_set_priv_mode(const ble_addr_t *peer_addr, uint8_t priv_mode); +#define BLE_GAP_LE_PHY_1M 1 +#define BLE_GAP_LE_PHY_2M 2 +#define BLE_GAP_LE_CODED 3 +int ble_gap_read_le_phy(uint16_t conn_handle, uint8_t *tx_phy, uint8_t *rx_phy); + +#define BLE_GAP_LE_PHY_1M_MASK 0x01 +#define BLE_GAP_LE_PHY_2M_MASK 0x02 +#define BLE_GAP_LE_PHY_CODED_MASK 0x04 +int ble_gap_set_prefered_default_le_phy(uint8_t tx_phys_mask, + uint8_t rx_phys_mask); + +#define BLE_GAP_LE_PHY_CODED_ANY 0 +#define BLE_GAP_LE_PHY_CODED_S2 1 +#define BLE_GAP_LE_PHY_CODED_S8 2 +int ble_gap_set_prefered_le_phy(uint16_t conn_handle, uint8_t tx_phys_mask, + uint8_t rx_phys_mask, uint16_t phy_opts); #ifdef __cplusplus } #endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c7aa21c3/net/nimble/host/src/ble_gap.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_gap.c b/net/nimble/host/src/ble_gap.c index 6318a9e..99ab5cf 100644 --- a/net/nimble/host/src/ble_gap.c +++ b/net/nimble/host/src/ble_gap.c @@ -437,6 +437,85 @@ ble_gap_set_priv_mode(const ble_addr_t *peer_addr, uint8_t priv_mode) return ble_hs_pvcy_set_mode(peer_addr, priv_mode); } +int +ble_gap_read_le_phy(uint16_t conn_handle, uint8_t *tx_phy, uint8_t *rx_phy) +{ + struct ble_hs_conn *conn; + uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_LE_RD_PHY_LEN]; + uint8_t rspbuf[4]; + uint8_t rsplen; + int rc; + + ble_hs_lock(); + conn = ble_hs_conn_find(conn_handle); + ble_hs_unlock(); + + if (conn == NULL) { + return BLE_HS_ENOTCONN; + } + + rc = ble_hs_hci_build_le_read_phy(conn_handle, buf, sizeof(buf)); + if (rc != 0) { + return rc; + } + + rc = ble_hs_hci_cmd_tx(buf, rspbuf, sizeof(rspbuf), &rsplen); + if (rc != 0) { + return rc; + } + + if (rsplen != sizeof(rspbuf)) { + return BLE_HS_ECONTROLLER; + } + + /* First two octets is conn_handle. We can ignore it */ + + *tx_phy = rspbuf[2]; + *rx_phy = rspbuf[3]; + + return 0; +} + +int +ble_gap_set_prefered_default_le_phy(uint8_t tx_phys_mask, uint8_t rx_phys_mask) +{ + uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_LE_SET_DEFAULT_PHY_LEN]; + int rc; + + rc = ble_hs_hci_build_le_set_default_phy(tx_phys_mask, rx_phys_mask, buf, + sizeof(buf)); + if (rc != 0) { + return rc; + } + + return ble_hs_hci_cmd_tx(buf, NULL, 0, NULL); +} + +int +ble_gap_set_prefered_le_phy(uint16_t conn_handle, uint8_t tx_phys_mask, + uint8_t rx_phys_mask, uint16_t phy_opts) +{ + struct ble_hs_conn *conn; + uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_LE_SET_PHY_LEN]; + int rc; + + ble_hs_lock(); + conn = ble_hs_conn_find(conn_handle); + ble_hs_unlock(); + + if (conn == NULL) { + return BLE_HS_ENOTCONN; + } + + rc = ble_hs_hci_build_le_set_phy(conn_handle, tx_phys_mask, rx_phys_mask, + phy_opts, buf, sizeof(buf)); + if (rc != 0) { + return rc; + } + + return ble_hs_hci_cmd_tx(buf, NULL, 0, NULL); +} + /***************************************************************************** * $misc * *****************************************************************************/ @@ -1217,6 +1296,21 @@ ble_gap_rx_l2cap_update_req(uint16_t conn_handle, return rc; } +void +ble_gap_rx_phy_update_complete(struct hci_le_phy_upd_complete *evt) +{ + struct ble_gap_event event; + + memset(&event, 0, sizeof event); + event.type = BLE_GAP_EVENT_PHY_UPDATE_COMPLETE; + event.phy_updated.status = evt->status; + event.phy_updated.conn_handle = evt->connection_handle; + event.phy_updated.tx_phy = evt->tx_phy; + event.phy_updated.rx_phy = evt->rx_phy; + + ble_gap_call_conn_event_cb(&event, evt->connection_handle); +} + static int32_t ble_gap_master_timer(void) { http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c7aa21c3/net/nimble/host/src/ble_gap_priv.h ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_gap_priv.h b/net/nimble/host/src/ble_gap_priv.h index 2e2bc75..8c35223 100644 --- a/net/nimble/host/src/ble_gap_priv.h +++ b/net/nimble/host/src/ble_gap_priv.h @@ -81,6 +81,7 @@ void ble_gap_rx_update_complete(struct hci_le_conn_upd_complete *evt); void ble_gap_rx_param_req(struct hci_le_conn_param_req *evt); int ble_gap_rx_l2cap_update_req(uint16_t conn_handle, struct ble_gap_upd_params *params); +void ble_gap_rx_phy_update_complete(struct hci_le_phy_upd_complete *evt); void ble_gap_enc_event(uint16_t conn_handle, int status, int security_restored); void ble_gap_passkey_event(uint16_t conn_handle, http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c7aa21c3/net/nimble/host/src/ble_hs_hci_evt.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_hs_hci_evt.c b/net/nimble/host/src/ble_hs_hci_evt.c index a9655e3..7af8db5 100644 --- a/net/nimble/host/src/ble_hs_hci_evt.c +++ b/net/nimble/host/src/ble_hs_hci_evt.c @@ -46,6 +46,7 @@ static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_conn_upd_complete; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_lt_key_req; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_conn_parm_req; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_dir_adv_rpt; +static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_phy_update_complete; /* Statistics */ struct host_hci_stats @@ -92,6 +93,8 @@ static const struct ble_hs_hci_evt_le_dispatch_entry { BLE_HCI_LE_SUBEV_REM_CONN_PARM_REQ, ble_hs_hci_evt_le_conn_parm_req }, { BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE, ble_hs_hci_evt_le_conn_complete }, { BLE_HCI_LE_SUBEV_DIRECT_ADV_RPT, ble_hs_hci_evt_le_dir_adv_rpt }, + { BLE_HCI_LE_SUBEV_PHY_UPDATE_COMPLETE, + ble_hs_hci_evt_le_phy_update_complete }, }; #define BLE_HS_HCI_EVT_LE_DISPATCH_SZ \ @@ -563,6 +566,26 @@ ble_hs_hci_evt_le_conn_parm_req(uint8_t subevent, uint8_t *data, int len) return 0; } +static int +ble_hs_hci_evt_le_phy_update_complete(uint8_t subevent, uint8_t *data, int len) +{ + struct hci_le_phy_upd_complete evt; + + if (len < BLE_HCI_LE_PHY_UPD_LEN) { + return BLE_HS_ECONTROLLER; + } + + evt.subevent_code = data[0]; + evt.status = data[1]; + evt.connection_handle = get_le16(data + 2); + evt.tx_phy = data[4]; + evt.rx_phy = data[5]; + + ble_gap_rx_phy_update_complete(&evt); + + return 0; +} + int ble_hs_hci_evt_process(uint8_t *data) { http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c7aa21c3/net/nimble/include/nimble/hci_common.h ---------------------------------------------------------------------- diff --git a/net/nimble/include/nimble/hci_common.h b/net/nimble/include/nimble/hci_common.h index 689869e..8ae29dc 100644 --- a/net/nimble/include/nimble/hci_common.h +++ b/net/nimble/include/nimble/hci_common.h @@ -671,6 +671,9 @@ extern "C" { /* LE data length change event (sub event 0x07) */ #define BLE_HCI_LE_DATA_LEN_CHG_LEN (11) +/* LE PHY update complete event (sub event 0x0C) */ +#define BLE_HCI_LE_PHY_UPD_LEN (6) + /* LE Channel Selection Algorithm event (sub event 0x14) */ #define BLE_HCI_LE_SUBEV_CHAN_SEL_ALG_LEN (4) @@ -874,6 +877,16 @@ struct hci_read_rssi_ack_params int8_t rssi; }; +/* PHY updated completed LE meta subevent */ +struct hci_le_phy_upd_complete +{ + uint8_t subevent_code; + uint8_t status; + uint16_t connection_handle; + uint8_t tx_phy; + uint8_t rx_phy; +}; + #define BLE_HCI_DATA_HDR_SZ 4 #define BLE_HCI_DATA_HANDLE(handle_pb_bc) (((handle_pb_bc) & 0x0fff) >> 0) #define BLE_HCI_DATA_PB(handle_pb_bc) (((handle_pb_bc) & 0x3000) >> 12)
