summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2020-11-16 22:45:00 +0100
committerSven Gothel <[email protected]>2020-11-16 22:45:00 +0100
commit5a8f3859c924feef243dada15cf8186104ed7d09 (patch)
tree1e4bae592fc0ba1968accc8e7b7f867cd92dce7b /src
parentf012474492ed581d0c497babfe4bcb21a3f042c7 (diff)
DBTDevice.cpp: Just move notifyDisconnect(), disconnect() and remove() to EOF, more lifecycle/reading-order aligned.
Diffstat (limited to 'src')
-rw-r--r--src/direct_bt/DBTDevice.cpp176
1 files changed, 88 insertions, 88 deletions
diff --git a/src/direct_bt/DBTDevice.cpp b/src/direct_bt/DBTDevice.cpp
index 5435e9bf..cefb9a3b 100644
--- a/src/direct_bt/DBTDevice.cpp
+++ b/src/direct_bt/DBTDevice.cpp
@@ -449,90 +449,6 @@ void DBTDevice::processDeviceReady(std::shared_ptr<DBTDevice> sthis, const uint6
}
}
-void DBTDevice::notifyDisconnected() noexcept {
- // coming from disconnect callback, ensure cleaning up!
- DBG_PRINT("DBTDevice::notifyDisconnected: handle %s -> zero, %s",
- jau::uint16HexString(hciConnHandle).c_str(), toString().c_str());
- clearSMPStates();
- allowDisconnect = false;
- isConnected = false;
- hciConnHandle = 0;
- disconnectGATT(1);
- disconnectSMP(1);
- l2cap_att.close();
-}
-
-HCIStatusCode DBTDevice::disconnect(const HCIStatusCode reason) noexcept {
- // Avoid disconnect re-entry lock-free
- bool expConn = true; // C++11, exp as value since C++20
- if( !allowDisconnect.compare_exchange_strong(expConn, false) ) {
- // Not connected or disconnect already in process.
- DBG_PRINT("DBTDevice::disconnect: Not connected: isConnected %d/%d, reason 0x%X (%s), gattHandler %d, hciConnHandle %s",
- allowDisconnect.load(), isConnected.load(),
- static_cast<uint8_t>(reason), getHCIStatusCodeString(reason).c_str(),
- (nullptr != gattHandler), jau::uint16HexString(hciConnHandle).c_str());
- return HCIStatusCode::CONNECTION_TERMINATED_BY_LOCAL_HOST;
- }
- if( !isConnected ) { // should not happen
- WARN_PRINT("DBTDevice::disconnect: allowConnect true -> false, but !isConnected on %s", toString(false).c_str());
- return HCIStatusCode::SUCCESS;
- }
-
- // Disconnect GATT and SMP before device, keeping reversed initialization order intact if possible.
- // This outside mtx_connect, keeping same mutex lock order intact as well
- disconnectGATT(0);
- disconnectSMP(0);
-
- // Lock to avoid other threads connecting while disconnecting
- const std::lock_guard<std::recursive_mutex> lock_conn(mtx_connect); // RAII-style acquire and relinquish via destructor
-
- WORDY_PRINT("DBTDevice::disconnect: Start: isConnected %d/%d, reason 0x%X (%s), gattHandler %d, hciConnHandle %s",
- allowDisconnect.load(), isConnected.load(),
- static_cast<uint8_t>(reason), getHCIStatusCodeString(reason).c_str(),
- (nullptr != gattHandler), jau::uint16HexString(hciConnHandle).c_str());
-
- HCIHandler &hci = adapter.getHCI();
- HCIStatusCode res = HCIStatusCode::SUCCESS;
-
- if( 0 == hciConnHandle ) {
- res = HCIStatusCode::UNSPECIFIED_ERROR;
- goto exit;
- }
-
- if( !adapter.isPowered() ) {
- WARN_PRINT("DBTDevice::disconnect: Adapter not powered: %s", toString().c_str());
- res = HCIStatusCode::UNSPECIFIED_ERROR; // powered-off
- goto exit;
- }
-
- res = hci.disconnect(hciConnHandle.load(), address, addressType, reason);
- if( HCIStatusCode::SUCCESS != res ) {
- ERR_PRINT("DBTDevice::disconnect: status %s, handle 0x%X, isConnected %d/%d: errno %d %s on %s",
- getHCIStatusCodeString(res).c_str(), hciConnHandle.load(),
- allowDisconnect.load(), isConnected.load(),
- errno, strerror(errno),
- toString(false).c_str());
- }
-
-exit:
- if( HCIStatusCode::SUCCESS != res ) {
- // In case of an already pulled or disconnected HCIHandler (e.g. power-off)
- // or in case the hci->disconnect() itself fails,
- // send the DISCONN_COMPLETE event directly.
- // SEND_EVENT: Perform off-thread to avoid potential deadlock w/ application callbacks (similar when sent from HCIHandler's reader-thread)
- std::thread bg(&DBTAdapter::mgmtEvDeviceDisconnectedHCI, &adapter, std::shared_ptr<MgmtEvent>( // @suppress("Invalid arguments")
- new MgmtEvtDeviceDisconnected(adapter.dev_id, address, addressType, reason, hciConnHandle.load()) ) );
- bg.detach();
- // adapter.mgmtEvDeviceDisconnectedHCI( std::shared_ptr<MgmtEvent>( new MgmtEvtDeviceDisconnected(adapter.dev_id, address, addressType, reason, hciConnHandle.load()) ) );
- }
- WORDY_PRINT("DBTDevice::disconnect: End: status %s, handle 0x%X, isConnected %d/%d on %s",
- getHCIStatusCodeString(res).c_str(), hciConnHandle.load(),
- allowDisconnect.load(), isConnected.load(),
- toString(false).c_str());
-
- return res;
-}
-
bool DBTDevice::updatePairingState_locked(SMPPairingState state, PairingMode& current_mode) noexcept {
const std::lock_guard<std::mutex> lock(mtx_pairing); // RAII-style acquire and relinquish via destructor
current_mode = pairing_data.mode;
@@ -720,10 +636,6 @@ HCIStatusCode DBTDevice::setPairingNumericComparison(const bool positive) noexce
}
}
-void DBTDevice::remove() noexcept {
- adapter.removeDevice(*this);
-}
-
void DBTDevice::clearSMPStates() noexcept {
const std::lock_guard<std::mutex> lock(mtx_pairing); // RAII-style acquire and relinquish via destructor
@@ -953,3 +865,91 @@ int DBTDevice::removeAllCharacteristicListener() noexcept {
}
return gatt->removeAllCharacteristicListener();
}
+
+void DBTDevice::notifyDisconnected() noexcept {
+ // coming from disconnect callback, ensure cleaning up!
+ DBG_PRINT("DBTDevice::notifyDisconnected: handle %s -> zero, %s",
+ jau::uint16HexString(hciConnHandle).c_str(), toString().c_str());
+ clearSMPStates();
+ allowDisconnect = false;
+ isConnected = false;
+ hciConnHandle = 0;
+ disconnectGATT(1);
+ disconnectSMP(1);
+ l2cap_att.close();
+}
+
+HCIStatusCode DBTDevice::disconnect(const HCIStatusCode reason) noexcept {
+ // Avoid disconnect re-entry lock-free
+ bool expConn = true; // C++11, exp as value since C++20
+ if( !allowDisconnect.compare_exchange_strong(expConn, false) ) {
+ // Not connected or disconnect already in process.
+ DBG_PRINT("DBTDevice::disconnect: Not connected: isConnected %d/%d, reason 0x%X (%s), gattHandler %d, hciConnHandle %s",
+ allowDisconnect.load(), isConnected.load(),
+ static_cast<uint8_t>(reason), getHCIStatusCodeString(reason).c_str(),
+ (nullptr != gattHandler), jau::uint16HexString(hciConnHandle).c_str());
+ return HCIStatusCode::CONNECTION_TERMINATED_BY_LOCAL_HOST;
+ }
+ if( !isConnected ) { // should not happen
+ WARN_PRINT("DBTDevice::disconnect: allowConnect true -> false, but !isConnected on %s", toString(false).c_str());
+ return HCIStatusCode::SUCCESS;
+ }
+
+ // Disconnect GATT and SMP before device, keeping reversed initialization order intact if possible.
+ // This outside mtx_connect, keeping same mutex lock order intact as well
+ disconnectGATT(0);
+ disconnectSMP(0);
+
+ // Lock to avoid other threads connecting while disconnecting
+ const std::lock_guard<std::recursive_mutex> lock_conn(mtx_connect); // RAII-style acquire and relinquish via destructor
+
+ WORDY_PRINT("DBTDevice::disconnect: Start: isConnected %d/%d, reason 0x%X (%s), gattHandler %d, hciConnHandle %s",
+ allowDisconnect.load(), isConnected.load(),
+ static_cast<uint8_t>(reason), getHCIStatusCodeString(reason).c_str(),
+ (nullptr != gattHandler), jau::uint16HexString(hciConnHandle).c_str());
+
+ HCIHandler &hci = adapter.getHCI();
+ HCIStatusCode res = HCIStatusCode::SUCCESS;
+
+ if( 0 == hciConnHandle ) {
+ res = HCIStatusCode::UNSPECIFIED_ERROR;
+ goto exit;
+ }
+
+ if( !adapter.isPowered() ) {
+ WARN_PRINT("DBTDevice::disconnect: Adapter not powered: %s", toString().c_str());
+ res = HCIStatusCode::UNSPECIFIED_ERROR; // powered-off
+ goto exit;
+ }
+
+ res = hci.disconnect(hciConnHandle.load(), address, addressType, reason);
+ if( HCIStatusCode::SUCCESS != res ) {
+ ERR_PRINT("DBTDevice::disconnect: status %s, handle 0x%X, isConnected %d/%d: errno %d %s on %s",
+ getHCIStatusCodeString(res).c_str(), hciConnHandle.load(),
+ allowDisconnect.load(), isConnected.load(),
+ errno, strerror(errno),
+ toString(false).c_str());
+ }
+
+exit:
+ if( HCIStatusCode::SUCCESS != res ) {
+ // In case of an already pulled or disconnected HCIHandler (e.g. power-off)
+ // or in case the hci->disconnect() itself fails,
+ // send the DISCONN_COMPLETE event directly.
+ // SEND_EVENT: Perform off-thread to avoid potential deadlock w/ application callbacks (similar when sent from HCIHandler's reader-thread)
+ std::thread bg(&DBTAdapter::mgmtEvDeviceDisconnectedHCI, &adapter, std::shared_ptr<MgmtEvent>( // @suppress("Invalid arguments")
+ new MgmtEvtDeviceDisconnected(adapter.dev_id, address, addressType, reason, hciConnHandle.load()) ) );
+ bg.detach();
+ // adapter.mgmtEvDeviceDisconnectedHCI( std::shared_ptr<MgmtEvent>( new MgmtEvtDeviceDisconnected(adapter.dev_id, address, addressType, reason, hciConnHandle.load()) ) );
+ }
+ WORDY_PRINT("DBTDevice::disconnect: End: status %s, handle 0x%X, isConnected %d/%d on %s",
+ getHCIStatusCodeString(res).c_str(), hciConnHandle.load(),
+ allowDisconnect.load(), isConnected.load(),
+ toString(false).c_str());
+
+ return res;
+}
+
+void DBTDevice::remove() noexcept {
+ adapter.removeDevice(*this);
+}