diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index fe303909c..73e38b270 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -143,6 +143,7 @@ struct hci_conn_update; #define BLE_GAP_EVENT_REATTEMPT_COUNT 25 #define BLE_GAP_EVENT_VS_HCI 26 #define BLE_GAP_EVENT_DATA_LEN_CHG 27 +#define BLE_GAP_EVENT_PAIRING_REQUEST 28 /*** Reason codes for the subscribe GAP event. */ @@ -447,6 +448,15 @@ struct ble_gap_disc_desc { ble_addr_t direct_addr; }; +struct ble_gap_pairing_req { + uint16_t conn_handle; + /** Properties of the existing pairing request */ + uint8_t io_cap; + uint8_t oob_data_flag; + uint8_t authreq; + uint8_t max_enc_key_size; +}; + struct ble_gap_repeat_pairing { /** The handle of the relevant connection. */ uint16_t conn_handle; @@ -816,6 +826,20 @@ struct ble_gap_event { uint16_t conn_handle; } identity_resolved; + /** + * Represents a pairing request from peer. + * + * Valid for following event types: + * o BLE_GAP_EVENT_PAIRING_REQUEST + * The application can accept or reject pairing request. For accepting + * the application should return 0 and for rejecting the request the + * application should provide appropriate error return code, + * e.g. BLE_SM_ERR_AUTHREQ + * o Accept : Return 0 + * o Reject : Return appropriate error BLE_SM_* + */ + struct ble_gap_pairing_req pairing_req; + /** * Represents a peer's attempt to pair despite a bond already existing. * The application has two options for handling this event type: diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index a2ca5d5f7..c26b4c4db 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -6411,6 +6411,27 @@ ble_gap_identity_event(uint16_t conn_handle) #endif } +int +ble_gap_pairing_req_event(const struct ble_gap_pairing_req *req) +{ +#if !NIMBLE_BLE_SM + return 0; +#endif + + struct ble_gap_event event; + int rc; + + memset(&event, 0, sizeof event); + event.type = BLE_GAP_EVENT_PAIRING_REQUEST; + event.pairing_req.io_cap = req->io_cap; + event.pairing_req.oob_data_flag = req->oob_data_flag; + event.pairing_req.authreq = req->authreq; + event.pairing_req.max_enc_key_size = req->max_enc_key_size; + + rc = ble_gap_call_conn_event_cb(&event, req->conn_handle); + return rc; +} + int ble_gap_repeat_pairing_event(const struct ble_gap_repeat_pairing *rp) { diff --git a/nimble/host/src/ble_gap_priv.h b/nimble/host/src/ble_gap_priv.h index 3f8375aa0..dc358758c 100644 --- a/nimble/host/src/ble_gap_priv.h +++ b/nimble/host/src/ble_gap_priv.h @@ -129,6 +129,7 @@ void ble_gap_subscribe_event(uint16_t conn_handle, uint16_t attr_handle, uint8_t prev_indicate, uint8_t cur_indicate); void ble_gap_mtu_event(uint16_t conn_handle, uint16_t cid, uint16_t mtu); void ble_gap_identity_event(uint16_t conn_handle); +int ble_gap_pairing_req_event(const struct ble_gap_pairing_req *req); int ble_gap_repeat_pairing_event(const struct ble_gap_repeat_pairing *rp); void ble_gap_vs_hci_event(const void *buf, uint8_t len); int ble_gap_master_in_progress(void); diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index 25afaf242..7af28a8f7 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -885,6 +885,25 @@ ble_sm_read_bond(uint16_t conn_handle, struct ble_store_value_sec *out_bond) return rc; } +/** + * The application is queried about pairing request, depending upon the + * application's response the pairing request is accepted or rejected + */ +static int +ble_sm_pairing_req(uint16_t conn_handle, struct ble_sm_pair_cmd *req) +{ + struct ble_gap_pairing_req pair_req; + int rc; + + pair_req.conn_handle = conn_handle; + pair_req.io_cap = req->io_cap; + pair_req.oob_data_flag = req->oob_data_flag; + pair_req.authreq = req->authreq; + pair_req.max_enc_key_size = req->max_enc_key_size; + + return ble_gap_pairing_req_event(&pair_req); +} + /** * Checks if the specified peer is already bonded. If it is, the application * is queried about how to proceed: retry or ignore. The application should @@ -1862,6 +1881,18 @@ ble_sm_pair_req_rx(uint16_t conn_handle, struct os_mbuf **om, ble_hs_unlock(); + /* Ask the application to provide response if pairing is to be accepted or + * not + */ + rc = ble_sm_pairing_req(conn_handle, req); + if (rc != 0) { + /* The app indicated that the pairing request should be rejected. */ + res->sm_err = rc; + res->app_status = BLE_HS_SM_US_ERR(rc); + return; + } + + /* Check if there is storage capacity for a new bond. If there isn't, ask * the application to make room. */