aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2020-05-26 00:30:21 +0200
committerSven Gothel <[email protected]>2020-05-26 00:30:21 +0200
commit1f4513bf346f9914e8ed271a6af3dba508a807ee (patch)
treece46f23698fe8d057fd15cb08f93beded5c40311
parent5ab2e4016cb8dd4831494b823d088b18c02afbda (diff)
GATTHandler l2capReaderThread robustness (I/O error) and fail connect on exchangeMTU(..) failure.
In case of an l2cap I/O error while connecting to a device, the l2capReaderThread will end. For this case we need to detach it right away, otherwise the whole application will terminate and abort with a 'terminate called without an active exception' message. Further, if exchangeMTU(..) negotiation via l2cap fails within our connect implementation, connect itself shall fail. Here a full disconnect shall cleanup this GATTHandler.
-rw-r--r--src/direct_bt/GATTHandler.cpp28
1 files changed, 13 insertions, 15 deletions
diff --git a/src/direct_bt/GATTHandler.cpp b/src/direct_bt/GATTHandler.cpp
index 16bf3339..2de4cae1 100644
--- a/src/direct_bt/GATTHandler.cpp
+++ b/src/direct_bt/GATTHandler.cpp
@@ -266,15 +266,17 @@ bool GATTHandler::connect() {
* as we only can install one handler.
*/
l2capReaderThread = std::thread(&GATTHandler::l2capReaderThreadImpl, this);
+ // Avoid 'terminate called without an active exception'
+ // as l2capReaderThread may end due to I/O errors.
+ l2capReaderThread.detach();
- const uint16_t mtu = exchangeMTU(ClientMaxMTU);;
- if( 0 < mtu ) {
- serverMTU = mtu;
- } else {
- WARN_PRINT("Ignoring zero serverMTU.");
- }
+ serverMTU = exchangeMTU(ClientMaxMTU);;
usedMTU = std::min((int)ClientMaxMTU, (int)serverMTU);
-
+ if( 0 == serverMTU ) {
+ ERR_PRINT("GATTHandler::connect: Zero serverMTU -> disconnect: %s", device->toString().c_str());
+ disconnect();
+ return false;
+ }
return true;
}
@@ -287,8 +289,8 @@ bool GATTHandler::disconnect() {
const pthread_t tid_self = pthread_self();
const pthread_t tid_l2capReader = l2capReaderThread.native_handle();
const bool is_l2capReader = tid_l2capReader == tid_self;
- DBG_PRINT("GATTHandler.disconnect Start (is_l2capReader %d)", is_l2capReader);
- if( l2capReaderRunning && l2capReaderThread.joinable() ) {
+ DBG_PRINT("GATTHandler.disconnect: Start (is_l2capReader %d)", is_l2capReader);
+ if( l2capReaderRunning ) {
l2capReaderShallStop = true;
if( !is_l2capReader ) {
pthread_kill(tid_l2capReader, SIGINT);
@@ -299,14 +301,10 @@ bool GATTHandler::disconnect() {
state = Disconnected;
if( !is_l2capReader ) {
- if( l2capReaderRunning && l2capReaderThread.joinable() ) {
+ if( l2capReaderRunning ) {
// still running ..
- DBG_PRINT("GATTHandler.disconnect join l2capReaderThread");
- l2capReaderThread.join();
+ WARN_PRINT("GATTHandler.disconnect: l2capReaderThread still running!");
}
- } else {
- DBG_PRINT("GATTHandler.disconnect l2capReaderThread detaching self");
- l2capReaderThread.detach();
}
l2capReaderThread = std::thread(); // empty
DBG_PRINT("GATTHandler.disconnect End");