diff --git a/src/NimBLEDevice.cpp b/src/NimBLEDevice.cpp index e125aeb9d..0663fdf48 100644 --- a/src/NimBLEDevice.cpp +++ b/src/NimBLEDevice.cpp @@ -1221,6 +1221,18 @@ void NimBLEDevice::setSecurityAuth(uint8_t auth_req) { * * 0x03 BLE_HS_IO_NO_INPUT_OUTPUT NoInputNoOutput IO capability * * 0x04 BLE_HS_IO_KEYBOARD_DISPLAY KeyboardDisplay Only IO capability */ +/** + * @brief Set whether a Security Request from a peer we have no keys for + * automatically sends a Pairing Request. + * @param [in] enable true (default): pair immediately. false: ignore the + * request; the application pairs via NimBLEClient::secureConnection(). + * @details Some peripherals never answer a Pairing Request sent in the same + * instant as their own Security Request. + */ +void NimBLEDevice::setSecurityAutoPairOnSecReq(bool enable) { + ble_hs_cfg.sm_sec_req_auto_pair = enable; +} // setSecurityAutoPairOnSecReq + void NimBLEDevice::setSecurityIOCap(uint8_t iocap) { ble_hs_cfg.sm_io_cap = iocap; } // setSecurityIOCap diff --git a/src/NimBLEDevice.h b/src/NimBLEDevice.h index fb64c83db..1aa5836b0 100644 --- a/src/NimBLEDevice.h +++ b/src/NimBLEDevice.h @@ -141,6 +141,7 @@ class NimBLEDevice { static void setSecurityAuth(bool bonding, bool mitm, bool sc); static void setSecurityAuth(uint8_t auth); static void setSecurityIOCap(uint8_t iocap); + static void setSecurityAutoPairOnSecReq(bool enable); static void setSecurityInitKey(uint8_t initKey); static void setSecurityRespKey(uint8_t respKey); static void setSecurityPasskey(uint32_t passKey); diff --git a/src/nimble/nimble/host/include/host/ble_hs.h b/src/nimble/nimble/host/include/host/ble_hs.h index 6a6c2e7b4..af8930fff 100644 --- a/src/nimble/nimble/host/include/host/ble_hs.h +++ b/src/nimble/nimble/host/include/host/ble_hs.h @@ -319,6 +319,16 @@ struct ble_hs_cfg { */ unsigned sm_keypress:1; + /** @brief Security Manager - auto-pair on Security Request + * + * If set (default), a Security Request from a peer we have no keys for + * immediately triggers a Pairing Request. If clear, it is ignored and the + * application initiates pairing (ble_gap_security_initiate). Some + * peripherals never answer a Pairing Request sent in the same instant as + * their Security Request. Peers we have keys for are unaffected. + */ + unsigned sm_sec_req_auto_pair:1; + /** @brief Security Manager Local Key Distribution Mask */ uint8_t sm_our_key_dist; diff --git a/src/nimble/nimble/host/src/ble_hs_cfg.c b/src/nimble/nimble/host/src/ble_hs_cfg.c index 4b9700628..2145a061b 100644 --- a/src/nimble/nimble/host/src/ble_hs_cfg.c +++ b/src/nimble/nimble/host/src/ble_hs_cfg.c @@ -28,6 +28,7 @@ struct ble_hs_cfg ble_hs_cfg = { .sm_mitm = MYNEWT_VAL(BLE_SM_MITM), .sm_sc = MYNEWT_VAL(BLE_SM_SC), .sm_keypress = MYNEWT_VAL(BLE_SM_KEYPRESS), + .sm_sec_req_auto_pair = MYNEWT_VAL(BLE_SM_SEC_REQ_AUTO_PAIR), .sm_our_key_dist = MYNEWT_VAL(BLE_SM_OUR_KEY_DIST), .sm_their_key_dist = MYNEWT_VAL(BLE_SM_THEIR_KEY_DIST), }; diff --git a/src/nimble/nimble/host/src/ble_sm.c b/src/nimble/nimble/host/src/ble_sm.c index 198c6fc87..c1345bd71 100644 --- a/src/nimble/nimble/host/src/ble_sm.c +++ b/src/nimble/nimble/host/src/ble_sm.c @@ -2090,7 +2090,16 @@ ble_sm_sec_req_rx(uint16_t conn_handle, struct os_mbuf **om, } } } else { - /* no keys present, start pairing */ + /* no keys present: start pairing, unless the application wants to + * initiate pairing itself. In that case only a clean "no keys" + * result is ignored; store errors are propagated. + */ + if (!ble_hs_cfg.sm_sec_req_auto_pair) { + if (res->app_status == BLE_HS_ENOENT) { + res->app_status = 0; + } + return; + } start_pairing = true; } diff --git a/src/syscfg/syscfg.h b/src/syscfg/syscfg.h index e5a511fea..0bb59a625 100644 --- a/src/syscfg/syscfg.h +++ b/src/syscfg/syscfg.h @@ -835,6 +835,10 @@ #define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) #endif +#ifndef MYNEWT_VAL_BLE_SM_SEC_REQ_AUTO_PAIR +#define MYNEWT_VAL_BLE_SM_SEC_REQ_AUTO_PAIR (1) +#endif + #ifndef MYNEWT_VAL_BLE_SM_SC_ONLY #define MYNEWT_VAL_BLE_SM_SC_ONLY (0) #endif