mirror of
https://github.com/h2zero/esp-nimble-cpp.git
synced 2024-11-24 22:20:55 +01:00
Add asynchronous client connection secure
* Adds parameter `rcPtr` to `NimBLEDevice::startSecurity`, default value works as the original method. * * `rcPtr`: if not nullptr, will allow caller to obtain the internal return code. * Adds parameter `async` to `NimBLEClient::secureConnection`, default value works as the original method. * * `async`; if true, will send the secure command and return immediately with a true value for successfully sending the command, else false.
This commit is contained in:
parent
5f2730de02
commit
c57ca6ffdc
4 changed files with 32 additions and 7 deletions
|
@ -63,6 +63,7 @@ NimBLEClient::NimBLEClient(const NimBLEAddress& peerAddress)
|
||||||
m_pClientCallbacks{&defaultCallbacks},
|
m_pClientCallbacks{&defaultCallbacks},
|
||||||
m_connHandle{BLE_HS_CONN_HANDLE_NONE},
|
m_connHandle{BLE_HS_CONN_HANDLE_NONE},
|
||||||
m_terminateFailCount{0},
|
m_terminateFailCount{0},
|
||||||
|
m_asyncSecureAttempt{0},
|
||||||
m_config{},
|
m_config{},
|
||||||
# if CONFIG_BT_NIMBLE_EXT_ADV
|
# if CONFIG_BT_NIMBLE_EXT_ADV
|
||||||
m_phyMask{BLE_GAP_LE_PHY_1M_MASK | BLE_GAP_LE_PHY_2M_MASK | BLE_GAP_LE_PHY_CODED_MASK},
|
m_phyMask{BLE_GAP_LE_PHY_1M_MASK | BLE_GAP_LE_PHY_2M_MASK | BLE_GAP_LE_PHY_CODED_MASK},
|
||||||
|
@ -293,12 +294,26 @@ bool NimBLEClient::connect(const NimBLEAddress& address, bool deleteAttributes,
|
||||||
/**
|
/**
|
||||||
* @brief Initiate a secure connection (pair/bond) with the server.\n
|
* @brief Initiate a secure connection (pair/bond) with the server.\n
|
||||||
* Called automatically when a characteristic or descriptor requires encryption or authentication to access it.
|
* Called automatically when a characteristic or descriptor requires encryption or authentication to access it.
|
||||||
|
* @param [in] async If true, the connection will be secured asynchronously and this function will return immediately.\n
|
||||||
|
* If false, this function will block until the connection is secured or the client disconnects.
|
||||||
* @return True on success.
|
* @return True on success.
|
||||||
* @details This is a blocking function and should not be used in a callback.
|
* @details If async=false, this function will block and should not be used in a callback.
|
||||||
*/
|
*/
|
||||||
bool NimBLEClient::secureConnection() const {
|
bool NimBLEClient::secureConnection(bool async) const {
|
||||||
NIMBLE_LOGD(LOG_TAG, ">> secureConnection()");
|
NIMBLE_LOGD(LOG_TAG, ">> secureConnection()");
|
||||||
|
|
||||||
|
int rc = 0;
|
||||||
|
if (async && !NimBLEDevice::startSecurity(m_connHandle, &rc)) {
|
||||||
|
m_lastErr = rc;
|
||||||
|
m_asyncSecureAttempt = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (async) {
|
||||||
|
m_asyncSecureAttempt++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
NimBLETaskData taskData(const_cast<NimBLEClient*>(this), BLE_HS_ENOTCONN);
|
NimBLETaskData taskData(const_cast<NimBLEClient*>(this), BLE_HS_ENOTCONN);
|
||||||
m_pTaskData = &taskData;
|
m_pTaskData = &taskData;
|
||||||
int retryCount = 1;
|
int retryCount = 1;
|
||||||
|
@ -946,6 +961,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
|
||||||
NIMBLE_LOGD(LOG_TAG, "disconnect; reason=%d, %s", rc, NimBLEUtils::returnCodeToString(rc));
|
NIMBLE_LOGD(LOG_TAG, "disconnect; reason=%d, %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||||
|
|
||||||
pClient->m_terminateFailCount = 0;
|
pClient->m_terminateFailCount = 0;
|
||||||
|
pClient->m_asyncSecureAttempt = 0;
|
||||||
NimBLEDevice::removeIgnored(pClient->m_peerAddress);
|
NimBLEDevice::removeIgnored(pClient->m_peerAddress);
|
||||||
|
|
||||||
// Don't call the disconnect callback if we are waiting for a connection to complete and it fails
|
// Don't call the disconnect callback if we are waiting for a connection to complete and it fails
|
||||||
|
@ -1114,7 +1130,12 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
|
||||||
if (event->enc_change.status == (BLE_HS_ERR_HCI_BASE + BLE_ERR_PINKEY_MISSING)) {
|
if (event->enc_change.status == (BLE_HS_ERR_HCI_BASE + BLE_ERR_PINKEY_MISSING)) {
|
||||||
// Key is missing, try deleting.
|
// Key is missing, try deleting.
|
||||||
ble_store_util_delete_peer(&peerInfo.m_desc.peer_id_addr);
|
ble_store_util_delete_peer(&peerInfo.m_desc.peer_id_addr);
|
||||||
|
// Attempt a retry if async secure failed.
|
||||||
|
if (pClient->m_asyncSecureAttempt == 1) {
|
||||||
|
pClient->secureConnection(true);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
pClient->m_asyncSecureAttempt = 0;
|
||||||
pClient->m_pClientCallbacks->onAuthenticationComplete(peerInfo);
|
pClient->m_pClientCallbacks->onAuthenticationComplete(peerInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ class NimBLEClient {
|
||||||
bool setConnection(uint16_t connHandle);
|
bool setConnection(uint16_t connHandle);
|
||||||
uint16_t getMTU() const;
|
uint16_t getMTU() const;
|
||||||
bool exchangeMTU();
|
bool exchangeMTU();
|
||||||
bool secureConnection() const;
|
bool secureConnection(bool async = false) const;
|
||||||
void setConnectTimeout(uint32_t timeout);
|
void setConnectTimeout(uint32_t timeout);
|
||||||
bool setDataLen(uint16_t txOctets);
|
bool setDataLen(uint16_t txOctets);
|
||||||
bool discoverAttributes();
|
bool discoverAttributes();
|
||||||
|
@ -129,6 +129,7 @@ class NimBLEClient {
|
||||||
NimBLEClientCallbacks* m_pClientCallbacks;
|
NimBLEClientCallbacks* m_pClientCallbacks;
|
||||||
uint16_t m_connHandle;
|
uint16_t m_connHandle;
|
||||||
uint8_t m_terminateFailCount;
|
uint8_t m_terminateFailCount;
|
||||||
|
mutable uint8_t m_asyncSecureAttempt;
|
||||||
Config m_config;
|
Config m_config;
|
||||||
|
|
||||||
# if CONFIG_BT_NIMBLE_EXT_ADV
|
# if CONFIG_BT_NIMBLE_EXT_ADV
|
||||||
|
|
|
@ -1121,14 +1121,17 @@ uint32_t NimBLEDevice::getSecurityPasskey() {
|
||||||
/**
|
/**
|
||||||
* @brief Start the connection securing and authorization for this connection.
|
* @brief Start the connection securing and authorization for this connection.
|
||||||
* @param connHandle The connection handle of the peer device.
|
* @param connHandle The connection handle of the peer device.
|
||||||
* @returns NimBLE stack return code, 0 = success.
|
* @param rcPtr Optional pointer to pass the return code to the caller.
|
||||||
|
* @returns True if successfully started, success = 0 or BLE_HS_EALREADY.
|
||||||
*/
|
*/
|
||||||
bool NimBLEDevice::startSecurity(uint16_t connHandle) {
|
bool NimBLEDevice::startSecurity(uint16_t connHandle, int* rcPtr) {
|
||||||
int rc = ble_gap_security_initiate(connHandle);
|
int rc = ble_gap_security_initiate(connHandle);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
NIMBLE_LOGE(LOG_TAG, "ble_gap_security_initiate: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
NIMBLE_LOGE(LOG_TAG, "ble_gap_security_initiate: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||||
}
|
}
|
||||||
|
if (rcPtr) {
|
||||||
|
*rcPtr = rc;
|
||||||
|
}
|
||||||
return rc == 0 || rc == BLE_HS_EALREADY;
|
return rc == 0 || rc == BLE_HS_EALREADY;
|
||||||
} // startSecurity
|
} // startSecurity
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,7 @@ class NimBLEDevice {
|
||||||
static void setSecurityRespKey(uint8_t respKey);
|
static void setSecurityRespKey(uint8_t respKey);
|
||||||
static void setSecurityPasskey(uint32_t passKey);
|
static void setSecurityPasskey(uint32_t passKey);
|
||||||
static uint32_t getSecurityPasskey();
|
static uint32_t getSecurityPasskey();
|
||||||
static bool startSecurity(uint16_t connHandle);
|
static bool startSecurity(uint16_t connHandle, int* rcPtr = nullptr);
|
||||||
static bool setMTU(uint16_t mtu);
|
static bool setMTU(uint16_t mtu);
|
||||||
static uint16_t getMTU();
|
static uint16_t getMTU();
|
||||||
static bool isIgnored(const NimBLEAddress& address);
|
static bool isIgnored(const NimBLEAddress& address);
|
||||||
|
|
Loading…
Reference in a new issue