Skip to content

Commit 814842e

Browse files
committed
[Bugfix] Incorrect Client connection state tracking and self delete
This adds better client state tracking so that functions like NimBLEDevice::getDisconnectedClient get a more accurate state and will not return a connecting client. This also fixes the client self delete on connection error where function call errors did not delete the client
1 parent 9abb7dd commit 814842e

2 files changed

Lines changed: 34 additions & 25 deletions

File tree

src/NimBLEClient.cpp

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ NimBLEClient::NimBLEClient(const NimBLEAddress& peerAddress)
6868
m_terminateFailCount{0},
6969
m_asyncSecureAttempt{0},
7070
m_config{},
71+
m_connStatus{DISCONNECTED},
7172
# if MYNEWT_VAL(BLE_EXT_ADV)
7273
m_phyMask{BLE_GAP_LE_PHY_1M_MASK | BLE_GAP_LE_PHY_2M_MASK | BLE_GAP_LE_PHY_CODED_MASK},
7374
# endif
@@ -171,35 +172,30 @@ bool NimBLEClient::connect(bool deleteAttributes, bool asyncConnect, bool exchan
171172
*/
172173
bool NimBLEClient::connect(const NimBLEAddress& address, bool deleteAttributes, bool asyncConnect, bool exchangeMTU) {
173174
NIMBLE_LOGD(LOG_TAG, ">> connect(%s)", address.toString().c_str());
175+
NimBLETaskData taskData(this);
176+
const ble_addr_t* peerAddr = address.getBase();
177+
int rc = 0;
174178

175179
if (!NimBLEDevice::m_synced) {
176180
NIMBLE_LOGE(LOG_TAG, "Host reset, wait for sync.");
177-
return false;
181+
rc = BLE_HS_ECONTROLLER;
182+
goto error;
178183
}
179184

180185
if (isConnected()) {
181186
NIMBLE_LOGE(LOG_TAG, "Client already connected");
182-
return false;
183-
}
184-
185-
const ble_addr_t* peerAddr = address.getBase();
186-
if (ble_gap_conn_find_by_addr(peerAddr, NULL) == 0) {
187-
NIMBLE_LOGE(LOG_TAG, "A connection to %s already exists", address.toString().c_str());
188-
return false;
187+
rc = BLE_HS_EREJECT;
188+
goto error;
189189
}
190190

191191
if (address.isNull()) {
192192
NIMBLE_LOGE(LOG_TAG, "Invalid peer address; (NULL)");
193-
return false;
194-
} else {
195-
m_peerAddress = address;
196-
}
197-
198-
if (deleteAttributes) {
199-
deleteServices();
193+
rc = BLE_HS_EINVAL;
194+
goto error;
200195
}
201196

202-
int rc = 0;
197+
m_connStatus = CONNECTING;
198+
m_peerAddress = address;
203199
m_config.asyncConnect = asyncConnect;
204200
m_config.exchangeMTU = exchangeMTU;
205201

@@ -259,16 +255,18 @@ bool NimBLEClient::connect(const NimBLEAddress& address, bool deleteAttributes,
259255

260256
} while (rc == BLE_HS_EBUSY);
261257

258+
if (deleteAttributes) {
259+
deleteServices();
260+
}
261+
262262
if (rc != 0) {
263-
m_lastErr = rc;
264-
return false;
263+
goto error;
265264
}
266265

267266
if (m_config.asyncConnect) {
268267
return true;
269268
}
270269

271-
NimBLETaskData taskData(this);
272270
m_pTaskData = &taskData;
273271

274272
// Wait for the connect timeout time +1 second for the connection to complete
@@ -288,17 +286,21 @@ bool NimBLEClient::connect(const NimBLEAddress& address, bool deleteAttributes,
288286
rc = taskData.m_flags;
289287
if (rc != 0) {
290288
NIMBLE_LOGE(LOG_TAG, "Connection failed; status=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
291-
m_lastErr = rc;
292-
if (m_config.deleteOnConnectFail) {
293-
NimBLEDevice::deleteClient(this);
294-
}
295-
return false;
289+
goto error;
296290
}
297291

298292
m_pClientCallbacks->onConnect(this);
299293
NIMBLE_LOGD(LOG_TAG, "<< connect()");
300294
// Check if still connected before returning
301295
return isConnected();
296+
297+
error:
298+
m_connStatus = DISCONNECTED;
299+
m_lastErr = rc;
300+
if (m_config.deleteOnConnectFail) {
301+
NimBLEDevice::deleteClient(this);
302+
}
303+
return false;
302304
} // connect
303305

304306
/**
@@ -358,6 +360,7 @@ bool NimBLEClient::disconnect(uint8_t reason) {
358360
return false;
359361
}
360362

363+
m_connStatus = DISCONNECTING;
361364
return true;
362365
} // disconnect
363366

@@ -976,6 +979,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
976979
pClient->m_pClientCallbacks->onDisconnect(pClient, rc);
977980
}
978981

982+
pClient->m_connStatus = DISCONNECTED;
979983
pClient->m_connHandle = BLE_HS_CONN_HANDLE_NONE;
980984

981985
if (pClient->m_config.deleteOnDisconnect) {
@@ -1005,6 +1009,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
10051009
}
10061010

10071011
if (rc == 0) {
1012+
pClient->m_connStatus = CONNECTED;
10081013
pClient->m_connHandle = event->connect.conn_handle;
10091014

10101015
if (pClient->m_config.asyncConnect) {
@@ -1020,6 +1025,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
10201025
return 0; // return as we may have a task waiting for the MTU before releasing it.
10211026
}
10221027
} else {
1028+
pClient->m_connStatus = DISCONNECTED;
10231029
pClient->m_connHandle = BLE_HS_CONN_HANDLE_NONE;
10241030

10251031
if (pClient->m_config.asyncConnect) {
@@ -1258,7 +1264,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
12581264
* @return True if we are connected and false if we are not connected.
12591265
*/
12601266
bool NimBLEClient::isConnected() const {
1261-
return m_connHandle != BLE_HS_CONN_HANDLE_NONE;
1267+
return m_connStatus != DISCONNECTED;
12621268
} // isConnected
12631269

12641270
/**

src/NimBLEClient.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ class NimBLEClient {
113113
void setConfig(Config config);
114114

115115
private:
116+
enum ConnStatus : uint8_t { CONNECTED, DISCONNECTED, CONNECTING, DISCONNECTING };
117+
116118
NimBLEClient(const NimBLEAddress& peerAddress);
117119
~NimBLEClient();
118120
NimBLEClient(const NimBLEClient&) = delete;
@@ -136,6 +138,7 @@ class NimBLEClient {
136138
uint8_t m_terminateFailCount;
137139
mutable uint8_t m_asyncSecureAttempt;
138140
Config m_config;
141+
ConnStatus m_connStatus;
139142

140143
# if MYNEWT_VAL(BLE_EXT_ADV)
141144
uint8_t m_phyMask;

0 commit comments

Comments
 (0)