diff --git a/docs/Migration_guide.md b/docs/Migration_guide.md
index b6551902..d1fcee8a 100644
--- a/docs/Migration_guide.md
+++ b/docs/Migration_guide.md
@@ -383,18 +383,23 @@ The security callback methods are now incorporated in the `NimBLEServerCallbacks
The callback methods are:
-> `bool onConfirmPIN(uint32_t pin)`
+> `bool onConfirmPIN(const NimBLEConnInfo& connInfo, uint32_t pin)`
-Receives the pin when using numeric comparison authentication, `return true;` to accept.
+Receives the pin when using numeric comparison authentication.
+Call `NimBLEDevice::injectConfirmPIN(connInfo, true);` to accept or `NimBLEDevice::injectConfirmPIN(connInfo, false);` to reject.
-> `uint32_t onPassKeyRequest()`
+> `void onPassKeyEntry(const NimBLEConnInfo& connInfo)`
-For server callback; return the passkey expected from the client.
-For client callback; return the passkey to send to the server.
+Client callback; client should respond with the passkey (pin) by calling `NimBLEDevice::injectPassKey(connInfo, 123456);`
-> `void onAuthenticationComplete(NimBLEConnInfo& connInfo)`
+> `uint32_t onPassKeyDisplay()`
+
+Server callback; should return the passkey (pin) expected from the client.
+
+
+> `void onAuthenticationComplete(const NimBLEConnInfo& connInfo)`
Authentication complete, success or failed information is available from the `NimBLEConnInfo` methods.
diff --git a/examples/NimBLE_Client/NimBLE_Client.ino b/examples/NimBLE_Client/NimBLE_Client.ino
index ea34b827..7b6f8712 100644
--- a/examples/NimBLE_Client/NimBLE_Client.ino
+++ b/examples/NimBLE_Client/NimBLE_Client.ino
@@ -56,28 +56,29 @@ class ClientCallbacks : public NimBLEClientCallbacks {
/********************* Security handled here **********************
****** Note: these are the same return values as defaults ********/
- uint32_t onPassKeyRequest(){
- Serial.println("Client Passkey Request");
- /** return the passkey to send to the server */
- return 123456;
+ void onPassKeyEntry(const NimBLEConnInfo& connInfo){
+ Serial.println("Server Passkey Entry");
+ /** This should prompt the user to enter the passkey displayed
+ * on the peer device.
+ */
+ NimBLEDevice::injectPassKey(connInfo, 123456);
};
- bool onConfirmPIN(uint32_t pass_key){
- Serial.print("The passkey YES/NO number: ");
- Serial.println(pass_key);
- /** Return false if passkeys don't match. */
- return true;
+ void onConfirmPIN(const NimBLEConnInfo& connInfo, uint32_t pass_key){
+ Serial.print("The passkey YES/NO number: ");Serial.println(pass_key);
+ /** Inject false if passkeys don't match. */
+ NimBLEDevice::injectConfirmPIN(connInfo, true);
};
- /** Pairing process complete, we can check the results in NimBLEConnInfo */
- void onAuthenticationComplete(NimBLEConnInfo& connInfo){
+ /** Pairing process complete, we can check the results in connInfo */
+ void onAuthenticationComplete(const NimBLEConnInfo& connInfo){
if(!connInfo.isEncrypted()) {
Serial.println("Encrypt connection failed - disconnecting");
- /** Find the client with the connection handle provided in connInfo */
+ /** Find the client with the connection handle provided in desc */
NimBLEDevice::getClientByID(connInfo.getConnHandle())->disconnect();
return;
}
- };
+ }
};
diff --git a/examples/NimBLE_Secure_Client/NimBLE_Secure_Client.ino b/examples/NimBLE_Secure_Client/NimBLE_Secure_Client.ino
index c1c54951..d45c700c 100644
--- a/examples/NimBLE_Secure_Client/NimBLE_Secure_Client.ino
+++ b/examples/NimBLE_Secure_Client/NimBLE_Secure_Client.ino
@@ -12,9 +12,9 @@
class ClientCallbacks : public NimBLEClientCallbacks
{
- uint32_t onPassKeyRequest()
+ uint32_t onPassKeyEntry()
{
- Serial.println("Client Passkey Request");
+ Serial.println("Client Passkey Entry");
/** return the passkey to send to the server */
/** Change this to be different from NimBLE_Secure_Server if you want to test what happens on key mismatch */
return 123456;
diff --git a/examples/NimBLE_Server/NimBLE_Server.ino b/examples/NimBLE_Server/NimBLE_Server.ino
index eb9b8263..85616346 100644
--- a/examples/NimBLE_Server/NimBLE_Server.ino
+++ b/examples/NimBLE_Server/NimBLE_Server.ino
@@ -37,21 +37,21 @@ class ServerCallbacks: public NimBLEServerCallbacks {
/********************* Security handled here **********************
****** Note: these are the same return values as defaults ********/
- uint32_t onPassKeyRequest(){
- Serial.println("Server Passkey Request");
+ uint32_t onPassKeyDisplay() {
+ Serial.println("Server Passkey Display");
/** This should return a random 6 digit number for security
* or make your own static passkey as done here.
*/
return 123456;
};
- bool onConfirmPIN(uint32_t pass_key){
+ void onConfirmPIN(const NimBLEConnInfo& connInfo, uint32_t pass_key) {
Serial.print("The passkey YES/NO number: ");Serial.println(pass_key);
- /** Return false if passkeys don't match. */
- return true;
+ /** Inject false if passkeys don't match. */
+ NimBLEDevice::injectConfirmPIN(connInfo, true);
};
- void onAuthenticationComplete(NimBLEConnInfo& connInfo){
+ void onAuthenticationComplete(const NimBLEConnInfo& connInfo) {
/** Check that encryption was successful, if not we disconnect the client */
if(!connInfo.isEncrypted()) {
NimBLEDevice::getServer()->disconnect(connInfo.getConnHandle());
diff --git a/examples/Refactored_original_examples/BLE_client/BLE_client.ino b/examples/Refactored_original_examples/BLE_client/BLE_client.ino
index 58d6a3f7..4cd79620 100644
--- a/examples/Refactored_original_examples/BLE_client/BLE_client.ino
+++ b/examples/Refactored_original_examples/BLE_client/BLE_client.ino
@@ -51,16 +51,17 @@ class MyClientCallback : public BLEClientCallbacks {
}
/***************** New - Security handled here ********************
****** Note: these are the same return values as defaults ********/
- uint32_t onPassKeyRequest(){
- Serial.println("Client PassKeyRequest");
- return 123456;
+ void onPassKeyEntry() {
+ Serial.println("Client PassKey Entry");
+ NimBLEDevice::injectPassKey(connInfo, 123456);
}
- bool onConfirmPIN(uint32_t pass_key){
+
+ void onConfirmPIN(const BLEConnInfo& connInfo, uint32_t pass_key) {
Serial.print("The passkey YES/NO number: ");Serial.println(pass_key);
- return true;
+ NimBLEDevice::injectConfirmPIN(connInfo, true);
}
- void onAuthenticationComplete(BLEConnInfo& connInfo){
+ void onAuthenticationComplete(const BLEConnInfo& connInfo){
Serial.println("Starting BLE work!");
}
/*******************************************************************/
diff --git a/examples/Refactored_original_examples/BLE_notify/BLE_notify.ino b/examples/Refactored_original_examples/BLE_notify/BLE_notify.ino
index 3582bc85..876b7d11 100644
--- a/examples/Refactored_original_examples/BLE_notify/BLE_notify.ino
+++ b/examples/Refactored_original_examples/BLE_notify/BLE_notify.ino
@@ -43,7 +43,7 @@ uint32_t value = 0;
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
/** None of these are required as they will be handled by the library with defaults. **
- ** Remove as you see fit for your needs */
+ ** Remove as you see fit for your needs */
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer, BLEConnInfo& connInfo) {
deviceConnected = true;
@@ -54,19 +54,23 @@ class MyServerCallbacks: public BLEServerCallbacks {
}
/***************** New - Security handled here ********************
****** Note: these are the same return values as defaults ********/
- uint32_t onPassKeyRequest(){
- Serial.println("Server PassKeyRequest");
- return 123456;
- }
-
- bool onConfirmPIN(uint32_t pass_key){
- Serial.print("The passkey YES/NO number: ");Serial.println(pass_key);
- return true;
- }
-
- void onAuthenticationComplete(BLEConnInfo& connInfo){
- Serial.println("Starting BLE work!");
- }
+ uint32_t onPassKeyDisplay() {
+ Serial.println("Server Passkey Display");
+ /** This should return a random 6 digit number for security
+ * or make your own static passkey as done here.
+ */
+ return 123456;
+ }
+
+ void onConfirmPIN(const BLEConnInfo& connInfo, uint32_t pass_key) {
+ Serial.print("The passkey YES/NO number: ");Serial.println(pass_key);
+ /** Inject false if passkeys don't match. */
+ NimBLEDevice::injectConfirmPIN(connInfo, true);
+ }
+
+ void onAuthenticationComplete(const BLEConnInfo& connInfo) {
+ Serial.println("Starting BLE work!");
+ }
/*******************************************************************/
};
@@ -87,13 +91,13 @@ void setup() {
// Create a BLE Characteristic
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
- /******* Enum Type NIMBLE_PROPERTY now *******
+ /******* Enum Type NIMBLE_PROPERTY now *******
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY |
BLECharacteristic::PROPERTY_INDICATE
);
- **********************************************/
+ **********************************************/
NIMBLE_PROPERTY::READ |
NIMBLE_PROPERTY::WRITE |
NIMBLE_PROPERTY::NOTIFY |
@@ -102,11 +106,11 @@ void setup() {
// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
// Create a BLE Descriptor
- /***************************************************
- NOTE: DO NOT create a 2902 descriptor.
- it will be created automatically if notifications
+ /***************************************************
+ NOTE: DO NOT create a 2902 descriptor.
+ it will be created automatically if notifications
or indications are enabled on a characteristic.
-
+
pCharacteristic->addDescriptor(new BLE2902());
****************************************************/
// Start the service
diff --git a/examples/Refactored_original_examples/BLE_server_multiconnect/BLE_server_multiconnect.ino b/examples/Refactored_original_examples/BLE_server_multiconnect/BLE_server_multiconnect.ino
index 22c02859..44daf00e 100644
--- a/examples/Refactored_original_examples/BLE_server_multiconnect/BLE_server_multiconnect.ino
+++ b/examples/Refactored_original_examples/BLE_server_multiconnect/BLE_server_multiconnect.ino
@@ -44,7 +44,7 @@ uint32_t value = 0;
/** None of these are required as they will be handled by the library with defaults. **
- ** Remove as you see fit for your needs */
+ ** Remove as you see fit for your needs */
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer, BLEConnInfo& connInfo) {
deviceConnected = true;
@@ -56,17 +56,21 @@ class MyServerCallbacks: public BLEServerCallbacks {
}
/***************** New - Security handled here ********************
****** Note: these are the same return values as defaults ********/
- uint32_t onPassKeyRequest(){
- Serial.println("Server PassKeyRequest");
- return 123456;
+ uint32_t onPassKeyDisplay() {
+ Serial.println("Server Passkey Display");
+ /** This should return a random 6 digit number for security
+ * or make your own static passkey as done here.
+ */
+ return 123456;
}
- bool onConfirmPIN(uint32_t pass_key){
+ void onConfirmPIN(const BLEConnInfo& connInfo, uint32_t pass_key) {
Serial.print("The passkey YES/NO number: ");Serial.println(pass_key);
- return true;
+ /** Inject false if passkeys don't match. */
+ NimBLEDevice::injectConfirmPIN(connInfo, true);
}
- void onAuthenticationComplete(BLEConnInfo& connInfo){
+ void onAuthenticationComplete(const BLEConnInfo& connInfo) {
Serial.println("Starting BLE work!");
}
/*******************************************************************/
@@ -90,13 +94,13 @@ void setup() {
// Create a BLE Characteristic
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
- /******* Enum Type NIMBLE_PROPERTY now *******
+ /******* Enum Type NIMBLE_PROPERTY now *******
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY |
BLECharacteristic::PROPERTY_INDICATE
);
- **********************************************/
+ **********************************************/
NIMBLE_PROPERTY::READ |
NIMBLE_PROPERTY::WRITE |
NIMBLE_PROPERTY::NOTIFY |
@@ -105,11 +109,11 @@ void setup() {
// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
// Create a BLE Descriptor
- /***************************************************
- NOTE: DO NOT create a 2902 descriptor
- it will be created automatically if notifications
+ /***************************************************
+ NOTE: DO NOT create a 2902 descriptor
+ it will be created automatically if notifications
or indications are enabled on a characteristic.
-
+
pCharacteristic->addDescriptor(new BLE2902());
****************************************************/
diff --git a/examples/Refactored_original_examples/BLE_uart/BLE_uart.ino b/examples/Refactored_original_examples/BLE_uart/BLE_uart.ino
index 260b30a4..a609952e 100644
--- a/examples/Refactored_original_examples/BLE_uart/BLE_uart.ino
+++ b/examples/Refactored_original_examples/BLE_uart/BLE_uart.ino
@@ -5,7 +5,7 @@
Create a BLE server that, once we receive a connection, will send periodic notifications.
The service advertises itself as: 6E400001-B5A3-F393-E0A9-E50E24DCCA9E
- Has a characteristic of: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E - used for receiving data with "WRITE"
+ Has a characteristic of: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E - used for receiving data with "WRITE"
Has a characteristic of: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E - used to send data with "NOTIFY"
The design of creating the BLE server is:
@@ -17,7 +17,7 @@
6. Start advertising.
In this example rxValue is the data received (only accessible inside that function).
- And txValue is the data to be sent, in this example just a byte incremented every second.
+ And txValue is the data to be sent, in this example just a byte incremented every second.
*/
/** NimBLE differences highlighted in comment blocks **/
@@ -45,7 +45,7 @@ uint8_t txValue = 0;
/** None of these are required as they will be handled by the library with defaults. **
- ** Remove as you see fit for your needs */
+ ** Remove as you see fit for your needs */
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer, BLEConnInfo& connInfo) {
deviceConnected = true;
@@ -56,17 +56,21 @@ class MyServerCallbacks: public BLEServerCallbacks {
}
/***************** New - Security handled here ********************
****** Note: these are the same return values as defaults ********/
- uint32_t onPassKeyRequest(){
- Serial.println("Server PassKeyRequest");
- return 123456;
+ uint32_t onPassKeyDisplay() {
+ Serial.println("Server Passkey Display");
+ /** This should return a random 6 digit number for security
+ * or make your own static passkey as done here.
+ */
+ return 123456;
}
- bool onConfirmPIN(uint32_t pass_key){
+ void onConfirmPIN(const BLEConnInfo& connInfo, uint32_t pass_key) {
Serial.print("The passkey YES/NO number: ");Serial.println(pass_key);
- return true;
+ /** Inject false if passkeys don't match. */
+ NimBLEDevice::injectConfirmPIN(connInfo, true);
}
- void onAuthenticationComplete(BLEConnInfo& connInfo){
+ void onAuthenticationComplete(const BLEConnInfo& connInfo) {
Serial.println("Starting BLE work!");
}
/*******************************************************************/
@@ -105,27 +109,27 @@ void setup() {
// Create a BLE Characteristic
pTxCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_TX,
- /******* Enum Type NIMBLE_PROPERTY now *******
+ /******* Enum Type NIMBLE_PROPERTY now *******
BLECharacteristic::PROPERTY_NOTIFY
);
- **********************************************/
+ **********************************************/
NIMBLE_PROPERTY::NOTIFY
);
-
- /***************************************************
- NOTE: DO NOT create a 2902 descriptor
- it will be created automatically if notifications
+
+ /***************************************************
+ NOTE: DO NOT create a 2902 descriptor
+ it will be created automatically if notifications
or indications are enabled on a characteristic.
-
+
pCharacteristic->addDescriptor(new BLE2902());
- ****************************************************/
+ ****************************************************/
BLECharacteristic * pRxCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_RX,
- /******* Enum Type NIMBLE_PROPERTY now *******
+ /******* Enum Type NIMBLE_PROPERTY now *******
BLECharacteristic::PROPERTY_WRITE
);
- *********************************************/
+ *********************************************/
NIMBLE_PROPERTY::WRITE
);
diff --git a/src/NimBLEClient.cpp b/src/NimBLEClient.cpp
index 996b7590..ceed193f 100644
--- a/src/NimBLEClient.cpp
+++ b/src/NimBLEClient.cpp
@@ -1171,7 +1171,11 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) {
{
NimBLEConnInfo peerInfo;
rc = ble_gap_conn_find(event->enc_change.conn_handle, &peerInfo.m_desc);
- assert(rc == 0);
+ if (rc != 0) {
+ NIMBLE_LOGE(LOG_TAG, "Connection info not found");
+ rc = 0;
+ break;
+ }
if (event->enc_change.status == (BLE_HS_ERR_HCI_BASE + BLE_ERR_PINKEY_MISSING)) {
// Key is missing, try deleting.
@@ -1203,20 +1207,17 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) {
if(pClient->m_conn_id != event->passkey.conn_handle)
return 0;
- if (event->passkey.params.action == BLE_SM_IOACT_DISP) {
- pkey.action = event->passkey.params.action;
- pkey.passkey = NimBLEDevice::m_passkey; // This is the passkey to be entered on peer
- rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
- NIMBLE_LOGD(LOG_TAG, "ble_sm_inject_io result: %d", rc);
+ NimBLEConnInfo peerInfo;
+ rc = ble_gap_conn_find(event->passkey.conn_handle, &peerInfo.m_desc);
+ if (rc != 0) {
+ NIMBLE_LOGE(LOG_TAG, "Connection info not found");
+ rc = 0;
+ break;
+ }
- } else if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) {
+ if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) {
NIMBLE_LOGD(LOG_TAG, "Passkey on device's display: %" PRIu32, event->passkey.params.numcmp);
- pkey.action = event->passkey.params.action;
- pkey.numcmp_accept = pClient->m_pClientCallbacks->onConfirmPIN(event->passkey.params.numcmp);
-
- rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
- NIMBLE_LOGD(LOG_TAG, "ble_sm_inject_io result: %d", rc);
-
+ pClient->m_pClientCallbacks->onConfirmPIN(peerInfo, event->passkey.params.numcmp);
//TODO: Handle out of band pairing
} else if (event->passkey.params.action == BLE_SM_IOACT_OOB) {
static uint8_t tem_oob[16] = {0};
@@ -1229,12 +1230,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) {
////////
} else if (event->passkey.params.action == BLE_SM_IOACT_INPUT) {
NIMBLE_LOGD(LOG_TAG, "Enter the passkey");
- pkey.action = event->passkey.params.action;
- pkey.passkey = pClient->m_pClientCallbacks->onPassKeyRequest();
-
- rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
- NIMBLE_LOGD(LOG_TAG, "ble_sm_inject_io result: %d", rc);
-
+ pClient->m_pClientCallbacks->onPassKeyEntry(peerInfo);
} else if (event->passkey.params.action == BLE_SM_IOACT_NONE) {
NIMBLE_LOGD(LOG_TAG, "No passkey action required");
}
@@ -1321,17 +1317,18 @@ bool NimBLEClientCallbacks::onConnParamsUpdateRequest(NimBLEClient* pClient, con
return true;
}
-uint32_t NimBLEClientCallbacks::onPassKeyRequest(){
- NIMBLE_LOGD("NimBLEClientCallbacks", "onPassKeyRequest: default: 123456");
- return 123456;
-}
+void NimBLEClientCallbacks::onPassKeyEntry(const NimBLEConnInfo& connInfo){
+ NIMBLE_LOGD("NimBLEClientCallbacks", "onPassKeyEntry: default: 123456");
+ NimBLEDevice::injectPassKey(connInfo, 123456);
+} //onPassKeyEntry
-void NimBLEClientCallbacks::onAuthenticationComplete(NimBLEConnInfo& peerInfo){
+void NimBLEClientCallbacks::onAuthenticationComplete(const NimBLEConnInfo& connInfo){
NIMBLE_LOGD("NimBLEClientCallbacks", "onAuthenticationComplete: default");
}
-bool NimBLEClientCallbacks::onConfirmPIN(uint32_t pin){
+
+void NimBLEClientCallbacks::onConfirmPIN(const NimBLEConnInfo& connInfo, uint32_t pin){
NIMBLE_LOGD("NimBLEClientCallbacks", "onConfirmPIN: default: true");
- return true;
+ NimBLEDevice::injectConfirmPIN(connInfo, true);
}
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */
diff --git a/src/NimBLEClient.h b/src/NimBLEClient.h
index 03061987..52f389e3 100644
--- a/src/NimBLEClient.h
+++ b/src/NimBLEClient.h
@@ -147,23 +147,23 @@ class NimBLEClientCallbacks {
/**
* @brief Called when server requests a passkey for pairing.
- * @return The passkey to be sent to the server.
+ * @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info.
*/
- virtual uint32_t onPassKeyRequest();
+ virtual void onPassKeyEntry(const NimBLEConnInfo& connInfo);
/**
* @brief Called when the pairing procedure is complete.
* @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info.\n
* This can be used to check the status of the connection encryption/pairing.
*/
- virtual void onAuthenticationComplete(NimBLEConnInfo& connInfo);
+ virtual void onAuthenticationComplete(const NimBLEConnInfo& connInfo);
/**
* @brief Called when using numeric comparision for pairing.
+ * @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info.
* @param [in] pin The pin to compare with the server.
- * @return True to accept the pin.
*/
- virtual bool onConfirmPIN(uint32_t pin);
+ virtual void onConfirmPIN(const NimBLEConnInfo& connInfo, uint32_t pin);
};
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */
diff --git a/src/NimBLEConnInfo.h b/src/NimBLEConnInfo.h
index c764c246..6b451275 100644
--- a/src/NimBLEConnInfo.h
+++ b/src/NimBLEConnInfo.h
@@ -13,44 +13,44 @@ friend class NimBLECharacteristic;
friend class NimBLEDescriptor;
ble_gap_conn_desc m_desc;
- NimBLEConnInfo() { m_desc = {}; }
- NimBLEConnInfo(ble_gap_conn_desc desc) { m_desc = desc; }
+ NimBLEConnInfo() { m_desc = {}; }
+ NimBLEConnInfo(ble_gap_conn_desc desc) { m_desc = desc; }
public:
/** @brief Gets the over-the-air address of the connected peer */
- NimBLEAddress getAddress() { return NimBLEAddress(m_desc.peer_ota_addr); }
+ NimBLEAddress getAddress() const { return NimBLEAddress(m_desc.peer_ota_addr); }
/** @brief Gets the ID address of the connected peer */
- NimBLEAddress getIdAddress() { return NimBLEAddress(m_desc.peer_id_addr); }
+ NimBLEAddress getIdAddress() const { return NimBLEAddress(m_desc.peer_id_addr); }
/** @brief Gets the connection handle of the connected peer */
- uint16_t getConnHandle() { return m_desc.conn_handle; }
+ uint16_t getConnHandle() const { return m_desc.conn_handle; }
/** @brief Gets the connection interval for this connection (in 1.25ms units) */
- uint16_t getConnInterval() { return m_desc.conn_itvl; }
+ uint16_t getConnInterval() const { return m_desc.conn_itvl; }
/** @brief Gets the supervision timeout for this connection (in 10ms units) */
- uint16_t getConnTimeout() { return m_desc.supervision_timeout; }
+ uint16_t getConnTimeout() const { return m_desc.supervision_timeout; }
/** @brief Gets the allowable latency for this connection (unit = number of intervals) */
- uint16_t getConnLatency() { return m_desc.conn_latency; }
+ uint16_t getConnLatency() const { return m_desc.conn_latency; }
/** @brief Gets the maximum transmission unit size for this connection (in bytes) */
- uint16_t getMTU() { return ble_att_mtu(m_desc.conn_handle); }
+ uint16_t getMTU() const { return ble_att_mtu(m_desc.conn_handle); }
/** @brief Check if we are in the master role in this connection */
- bool isMaster() { return (m_desc.role == BLE_GAP_ROLE_MASTER); }
+ bool isMaster() const { return (m_desc.role == BLE_GAP_ROLE_MASTER); }
/** @brief Check if we are in the slave role in this connection */
- bool isSlave() { return (m_desc.role == BLE_GAP_ROLE_SLAVE); }
+ bool isSlave() const { return (m_desc.role == BLE_GAP_ROLE_SLAVE); }
/** @brief Check if we are connected to a bonded peer */
- bool isBonded() { return (m_desc.sec_state.bonded == 1); }
+ bool isBonded() const { return (m_desc.sec_state.bonded == 1); }
/** @brief Check if the connection in encrypted */
- bool isEncrypted() { return (m_desc.sec_state.encrypted == 1); }
+ bool isEncrypted() const { return (m_desc.sec_state.encrypted == 1); }
/** @brief Check if the the connection has been authenticated */
- bool isAuthenticated() { return (m_desc.sec_state.authenticated == 1); }
+ bool isAuthenticated() const { return (m_desc.sec_state.authenticated == 1); }
/** @brief Gets the key size used to encrypt the connection */
uint8_t getSecKeySize() { return m_desc.sec_state.key_size; }
diff --git a/src/NimBLEDevice.cpp b/src/NimBLEDevice.cpp
index 3e260cf0..42449530 100644
--- a/src/NimBLEDevice.cpp
+++ b/src/NimBLEDevice.cpp
@@ -23,7 +23,9 @@
# include "esp_bt.h"
# include "nvs_flash.h"
# if defined(CONFIG_NIMBLE_CPP_IDF)
-# include "esp_nimble_hci.h"
+# if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) || CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE)
+# include "esp_nimble_hci.h"
+# endif
# include "nimble/nimble_port.h"
# include "nimble/nimble_port_freertos.h"
# include "host/ble_hs.h"
@@ -1154,6 +1156,43 @@ int NimBLEDevice::startSecurity(uint16_t conn_id) {
} // startSecurity
+/**
+ * @brief Inject the provided passkey into the Security Manager
+ * @param [in] peerInfo Connection information for the peer
+ * @param [in] pin The 6-digit pin to inject
+ * @return true if the passkey was injected successfully.
+ */
+bool NimBLEDevice::injectPassKey(const NimBLEConnInfo& peerInfo, uint32_t pin) {
+ int rc = 0;
+ struct ble_sm_io pkey = {0,0};
+
+ pkey.action = BLE_SM_IOACT_INPUT;
+ pkey.passkey = pin;
+
+ rc = ble_sm_inject_io(peerInfo.getConnHandle(), &pkey);
+ NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_INPUT; ble_sm_inject_io result: %d", rc);
+ return rc == 0;
+}
+
+
+/**
+ * @brief Inject the provided numeric comparison response into the Security Manager
+ * @param [in] peerInfo Connection information for the peer
+ * @param [in] accept Whether the user confirmed or declined the comparison
+ */
+bool NimBLEDevice::injectConfirmPIN(const NimBLEConnInfo& peerInfo, bool accept) {
+ int rc = 0;
+ struct ble_sm_io pkey = {0,0};
+
+ pkey.action = BLE_SM_IOACT_NUMCMP;
+ pkey.numcmp_accept = accept;
+
+ rc = ble_sm_inject_io(peerInfo.getConnHandle(), &pkey);
+ NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_NUMCMP; ble_sm_inject_io result: %d", rc);
+ return rc == 0;
+}
+
+
/**
* @brief Check if the device address is on our ignore list.
* @param [in] address The address to look for.
diff --git a/src/NimBLEDevice.h b/src/NimBLEDevice.h
index 4fdb25de..64bd4ed3 100644
--- a/src/NimBLEDevice.h
+++ b/src/NimBLEDevice.h
@@ -136,6 +136,8 @@ class NimBLEDevice {
static void setSecurityPasskey(uint32_t pin);
static uint32_t getSecurityPasskey();
static int startSecurity(uint16_t conn_id);
+ static bool injectConfirmPIN(const NimBLEConnInfo& peerInfo, bool accept);
+ static bool injectPassKey(const NimBLEConnInfo& peerInfo, uint32_t pin);
static int setMTU(uint16_t mtu);
static uint16_t getMTU();
static bool isIgnored(const NimBLEAddress &address);
diff --git a/src/NimBLEServer.cpp b/src/NimBLEServer.cpp
index daa5f235..243ac246 100644
--- a/src/NimBLEServer.cpp
+++ b/src/NimBLEServer.cpp
@@ -263,6 +263,7 @@ void NimBLEServer::advertiseOnDisconnect(bool aod) {
} // advertiseOnDisconnect
#endif
+
/**
* @brief Return the number of connected clients.
* @return The number of connected clients.
@@ -528,19 +529,20 @@ int NimBLEServer::handleGapEvent(struct ble_gap_event *event, void *arg) {
// if the (static)passkey is the default, check the callback for custom value
// both values default to the same.
if(pkey.passkey == 123456) {
- pkey.passkey = pServer->m_pServerCallbacks->onPassKeyRequest();
+ pkey.passkey = pServer->m_pServerCallbacks->onPassKeyDisplay();
}
rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_DISP; ble_sm_inject_io result: %d", rc);
} else if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) {
NIMBLE_LOGD(LOG_TAG, "Passkey on device's display: %" PRIu32, event->passkey.params.numcmp);
- pkey.action = event->passkey.params.action;
- pkey.numcmp_accept = pServer->m_pServerCallbacks->onConfirmPIN(event->passkey.params.numcmp);
- rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
- NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_NUMCMP; ble_sm_inject_io result: %d", rc);
+ rc = ble_gap_conn_find(event->passkey.conn_handle, &peerInfo.m_desc);
+ if(rc != 0) {
+ return BLE_ATT_ERR_INVALID_HANDLE;
+ }
+ pServer->m_pServerCallbacks->onConfirmPIN(peerInfo, event->passkey.params.numcmp);
//TODO: Handle out of band pairing
} else if (event->passkey.params.action == BLE_SM_IOACT_OOB) {
static uint8_t tem_oob[16] = {0};
@@ -551,14 +553,6 @@ int NimBLEServer::handleGapEvent(struct ble_gap_event *event, void *arg) {
rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_OOB; ble_sm_inject_io result: %d", rc);
//////////////////////////////////
- } else if (event->passkey.params.action == BLE_SM_IOACT_INPUT) {
- NIMBLE_LOGD(LOG_TAG, "Enter the passkey");
- pkey.action = event->passkey.params.action;
- pkey.passkey = pServer->m_pServerCallbacks->onPassKeyRequest();
-
- rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
- NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_INPUT; ble_sm_inject_io result: %d", rc);
-
} else if (event->passkey.params.action == BLE_SM_IOACT_NONE) {
NIMBLE_LOGD(LOG_TAG, "No passkey action required");
}
@@ -851,18 +845,18 @@ void NimBLEServerCallbacks::onMTUChange(uint16_t MTU, NimBLEConnInfo& connInfo)
NIMBLE_LOGD("NimBLEServerCallbacks", "onMTUChange(): Default");
} // onMTUChange
-uint32_t NimBLEServerCallbacks::onPassKeyRequest(){
- NIMBLE_LOGD("NimBLEServerCallbacks", "onPassKeyRequest: default: 123456");
+uint32_t NimBLEServerCallbacks::onPassKeyDisplay(){
+ NIMBLE_LOGD("NimBLEServerCallbacks", "onPassKeyDisplay: default: 123456");
return 123456;
-} //onPassKeyRequest
+} //onPassKeyDisplay
-void NimBLEServerCallbacks::onAuthenticationComplete(NimBLEConnInfo& connInfo){
- NIMBLE_LOGD("NimBLEServerCallbacks", "onAuthenticationComplete: default");
-} // onAuthenticationComplete
-
-bool NimBLEServerCallbacks::onConfirmPIN(uint32_t pin){
+void NimBLEServerCallbacks::onConfirmPIN(const NimBLEConnInfo& connInfo, uint32_t pin){
NIMBLE_LOGD("NimBLEServerCallbacks", "onConfirmPIN: default: true");
- return true;
+ NimBLEDevice::injectConfirmPIN(connInfo, true);
} // onConfirmPIN
+void NimBLEServerCallbacks::onAuthenticationComplete(const NimBLEConnInfo& connInfo){
+ NIMBLE_LOGD("NimBLEServerCallbacks", "onAuthenticationComplete: default");
+} // onAuthenticationComplete
+
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */
diff --git a/src/NimBLEServer.h b/src/NimBLEServer.h
index ea56ed73..5e635df7 100644
--- a/src/NimBLEServer.h
+++ b/src/NimBLEServer.h
@@ -152,24 +152,25 @@ class NimBLEServerCallbacks {
virtual void onMTUChange(uint16_t MTU, NimBLEConnInfo& connInfo);
/**
- * @brief Called when a client requests a passkey for pairing.
+ * @brief Called when a client requests a passkey for pairing (display).
* @return The passkey to be sent to the client.
*/
- virtual uint32_t onPassKeyRequest();
+ virtual uint32_t onPassKeyDisplay();
/**
- * @brief Called when the pairing procedure is complete.
+ * @brief Called when using numeric comparision for pairing.
* @param [in] connInfo A reference to a NimBLEConnInfo instance with information
- * about the peer connection parameters.
+ * Should be passed back to NimBLEDevice::injectConfirmPIN
+ * @param [in] pin The pin to compare with the client.
*/
- virtual void onAuthenticationComplete(NimBLEConnInfo& connInfo);
+ virtual void onConfirmPIN(const NimBLEConnInfo& connInfo, uint32_t pin);
/**
- * @brief Called when using numeric comparision for pairing.
- * @param [in] pin The pin to compare with the client.
- * @return True to accept the pin.
+ * @brief Called when the pairing procedure is complete.
+ * @param [in] connInfo A reference to a NimBLEConnInfo instance with information
+ * about the peer connection parameters.
*/
- virtual bool onConfirmPIN(uint32_t pin);
+ virtual void onAuthenticationComplete(const NimBLEConnInfo& connInfo);
}; // NimBLEServerCallbacks
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */