This is an automated email from the ASF dual-hosted git repository.
sjanc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git
The following commit(s) were added to refs/heads/master by this push:
new 332ca8253 nimble/host: add a pairing request GAP event
332ca8253 is described below
commit 332ca8253a5812bead745a0f24310ed757492458
Author: Gerard Marull-Paretas <[email protected]>
AuthorDate: Thu Oct 8 07:49:39 2026 +0200
nimble/host: add a pairing request GAP event
A peripheral has no way to refuse a pairing request from a peer: the
only point where the application is consulted is
BLE_GAP_EVENT_REPEAT_PAIRING, which is reported for peers that are
already bonded. Devices that accept new pairings only at certain times
(e.g. while the user has a pairing screen open, or until a first phone
is bonded) cannot enforce that, and a peer that knows the device's
address can start pairing whenever it likes.
Report BLE_GAP_EVENT_PAIRING_REQUEST in the peripheral role once an
incoming Pairing Request has passed the local security checks, before
the repeat pairing check. The application returns 0 to continue, or
BLE_SM_ERR_PAIR_NOT_SUPP to reject the request with a Pairing Failed
command, ending the procedure. Any other non-zero value is sent as
BLE_SM_ERR_UNSPECIFIED.
Signed-off-by: Gerard Marull-Paretas <[email protected]>
---
nimble/host/include/host/ble_gap.h | 21 +++++++++++++++++++++
nimble/host/src/ble_gap.c | 15 +++++++++++++++
nimble/host/src/ble_gap_priv.h | 1 +
nimble/host/src/ble_sm.c | 14 ++++++++++++++
4 files changed, 51 insertions(+)
diff --git a/nimble/host/include/host/ble_gap.h
b/nimble/host/include/host/ble_gap.h
index d9da3c6ca..d8e5966c3 100644
--- a/nimble/host/include/host/ble_gap.h
+++ b/nimble/host/include/host/ble_gap.h
@@ -258,6 +258,9 @@ struct hci_conn_update;
/** GAP event: BIG (Broadcast Isochronous Group) information report */
#define BLE_GAP_EVENT_BIGINFO_REPORT 30
+/** GAP event: Pairing request received from peer */
+#define BLE_GAP_EVENT_PAIRING_REQUEST 31
+
/** @} */
/**
@@ -992,6 +995,24 @@ struct ble_gap_event {
*/
struct ble_gap_repeat_pairing repeat_pairing;
+ /**
+ * Represents a pairing request received from the peer. Only
+ * reported in the peripheral role. The request has already been
+ * validated against the local security configuration. Return 0 to
+ * continue the pairing procedure, or BLE_SM_ERR_PAIR_NOT_SUPP to
+ * reject it with a Pairing Failed command (e.g. when the device is
+ * not accepting new pairings). Any other non-zero value rejects it
+ * with BLE_SM_ERR_UNSPECIFIED. If the peer is already bonded, this
+ * event is reported before BLE_GAP_EVENT_REPEAT_PAIRING.
+ *
+ * Valid for the following event types:
+ * o BLE_GAP_EVENT_PAIRING_REQUEST
+ */
+ struct {
+ /** The handle of the relevant connection. */
+ uint16_t conn_handle;
+ } pairing_request;
+
/**
* Represents a change of PHY. This is issue after successful
* change on PHY.
diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c
index 01f8e20ac..03ffeb05e 100644
--- a/nimble/host/src/ble_gap.c
+++ b/nimble/host/src/ble_gap.c
@@ -6896,6 +6896,21 @@ ble_gap_repeat_pairing_event(const struct
ble_gap_repeat_pairing *rp)
#endif
}
+int
+ble_gap_pairing_request_event(uint16_t conn_handle)
+{
+#if NIMBLE_BLE_SM && MYNEWT_VAL(BLE_ROLE_PERIPHERAL)
+ struct ble_gap_event event;
+
+ memset(&event, 0, sizeof event);
+ event.type = BLE_GAP_EVENT_PAIRING_REQUEST;
+ event.pairing_request.conn_handle = conn_handle;
+ return ble_gap_call_conn_event_cb(&event, conn_handle);
+#else
+ return 0;
+#endif
+}
+
void
ble_gap_pairing_complete_event(uint16_t conn_handle, int status)
{
diff --git a/nimble/host/src/ble_gap_priv.h b/nimble/host/src/ble_gap_priv.h
index 2f875ddf0..e99bcd566 100644
--- a/nimble/host/src/ble_gap_priv.h
+++ b/nimble/host/src/ble_gap_priv.h
@@ -140,6 +140,7 @@ void ble_gap_subscribe_event(uint16_t conn_handle, uint16_t
attr_handle,
void ble_gap_mtu_event(uint16_t conn_handle, uint16_t cid, uint16_t mtu);
void ble_gap_identity_event(uint16_t conn_handle, const ble_addr_t
*peer_id_addr);
int ble_gap_repeat_pairing_event(const struct ble_gap_repeat_pairing *rp);
+int ble_gap_pairing_request_event(uint16_t conn_handle);
void ble_gap_pairing_complete_event(uint16_t conn_handle, int status);
void ble_gap_unhandled_hci_event(bool is_le_meta, bool is_vs, const void *buf,
uint8_t len);
diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c
index c2fac2553..2ddfdbf11 100644
--- a/nimble/host/src/ble_sm.c
+++ b/nimble/host/src/ble_sm.c
@@ -1890,6 +1890,20 @@ ble_sm_pair_req_rx(uint16_t conn_handle, struct os_mbuf
**om,
ble_hs_unlock();
+ /* Give the application an opportunity to reject the request. */
+ if (res->app_status == 0) {
+ rc = ble_gap_pairing_request_event(conn_handle);
+ if (rc != 0) {
+ if (rc != BLE_SM_ERR_PAIR_NOT_SUPP) {
+ rc = BLE_SM_ERR_UNSPECIFIED;
+ }
+ res->sm_err = rc;
+ res->app_status = BLE_HS_SM_US_ERR(rc);
+ res->execute = 0;
+ return;
+ }
+ }
+
/* Check if we are already bonded to this peer. If so, give the
* application an opportunity to delete the old bond.
*/