diff options
author | Sven Gothel <[email protected]> | 2022-09-15 16:13:57 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2022-09-15 16:13:57 +0200 |
commit | 116822ec8bd597127157c0837b12218fff18a2e2 (patch) | |
tree | 5418aeb4713a2737904e735e2e72438d81a7c9fe /src/direct_bt | |
parent | 8dfa27ad2841aecb85200a15c834a8c770cc5dc6 (diff) |
HCIHandler::resetAdapter(): Add optional HCIHandler::PostShutdownFunc argument, allowing BTAdapter::reset() to wait until all devices are disconnected before powering-up again
Waiting for all disconnections within reset after shutdown phase determines the state of all devices
before powering up.
Diffstat (limited to 'src/direct_bt')
-rw-r--r-- | src/direct_bt/BTAdapter.cpp | 43 | ||||
-rw-r--r-- | src/direct_bt/HCIHandler.cpp | 17 |
2 files changed, 38 insertions, 22 deletions
diff --git a/src/direct_bt/BTAdapter.cpp b/src/direct_bt/BTAdapter.cpp index f7905045..b76ff2dd 100644 --- a/src/direct_bt/BTAdapter.cpp +++ b/src/direct_bt/BTAdapter.cpp @@ -480,7 +480,7 @@ void BTAdapter::poweredOff(bool active, const std::string& msg) noexcept { ERR_PRINT("BTAdapter invalid: dev_id %d, %p", dev_id, this); return; } - DBG_PRINT("BTAdapter::poweredOff(active %d, %s): ... %p, %s", active, msg.c_str(), this, toString().c_str()); + DBG_PRINT("BTAdapter::poweredOff(active %d, %s).0: ... %p, %s", active, msg.c_str(), this, toString().c_str()); if( jau::environment::get().debug ) { if( !active ) { jau::print_backtrace(true /* skip_anon_frames */, 4 /* max_frames */, 2 /* skip_frames: print_b*() + get_b*() */); @@ -511,7 +511,7 @@ void BTAdapter::poweredOff(bool active, const std::string& msg) noexcept { unlockConnectAny(); - DBG_PRINT("BTAdapter::poweredOff(active %d, %s): XXX %s", active, msg.c_str(), toString().c_str()); + DBG_PRINT("BTAdapter::poweredOff(active %d, %s).X: %s", active, msg.c_str(), toString().c_str()); } void BTAdapter::printDeviceList(const std::string& prefix, const BTAdapter::device_list_t& list) noexcept { @@ -850,24 +850,29 @@ HCIStatusCode BTAdapter::reset() noexcept { ERR_PRINT("HCI closed: %s, %s", jau::to_hexstring(this).c_str(), toString().c_str()); return HCIStatusCode::UNSPECIFIED_ERROR; } -#if 0 - const bool wasPowered = isPowered(); - // Adapter will be reset, close connections and cleanup off-thread. - preReset(); - - HCIStatusCode status = hci->reset(); - if( HCIStatusCode::SUCCESS != status ) { - ERR_PRINT("reset failed: %s", to_string(status).c_str()); - } else if( wasPowered ) { - if( !setPowered(true) ) { - ERR_PRINT("setPowered(true) failed"); - status = HCIStatusCode::UNSPECIFIED_ERROR; + DBG_PRINT("BTAdapter::reset.0: %s", toString().c_str()); + HCIStatusCode res = hci.resetAdapter( [&]() noexcept -> HCIStatusCode { + jau::nsize_t connCount = getConnectedDeviceCount(); + if( 0 < connCount ) { + const jau::fraction_i64 timeout = hci.env.HCI_COMMAND_COMPLETE_REPLY_TIMEOUT; + const jau::fraction_i64 poll_period = hci.env.HCI_COMMAND_POLL_PERIOD; + DBG_PRINT("BTAdapter::reset: %d connections pending - %s", connCount, toString().c_str()); + jau::fraction_i64 td = 0_s; + while( timeout > td && 0 < connCount ) { + sleep_for( poll_period ); + td += poll_period; + connCount = getConnectedDeviceCount(); + } + if( 0 < connCount ) { + WARN_PRINT("%d connections pending after %" PRIi64 " ms - %s", connCount, td.to_ms(), toString().c_str()); + } else { + DBG_PRINT("BTAdapter::reset: pending connections resolved after %" PRIi64 " ms - %s", td.to_ms(), toString().c_str()); + } } - } - return status; -#else - return hci.resetAdapter(); -#endif + return HCIStatusCode::SUCCESS; // keep going + }); + DBG_PRINT("BTAdapter::reset.X: %s - %s", to_string(res).c_str(), toString().c_str()); + return res; } diff --git a/src/direct_bt/HCIHandler.cpp b/src/direct_bt/HCIHandler.cpp index 2e7c00d3..37a4b04f 100644 --- a/src/direct_bt/HCIHandler.cpp +++ b/src/direct_bt/HCIHandler.cpp @@ -1032,12 +1032,14 @@ HCIStatusCode HCIHandler::stopAdapter() { return res; } -HCIStatusCode HCIHandler::resetAdapter() { +HCIStatusCode HCIHandler::resetAdapter(HCIHandler::PostShutdownFunc user_post_shutdown) { if( !isOpen() ) { ERR_PRINT("Not connected %s", toString().c_str()); return HCIStatusCode::DISCONNECTED; } HCIStatusCode res = HCIStatusCode::INTERNAL_FAILURE; + bool user_called = false; + bool user_abort = false; const std::lock_guard<std::recursive_mutex> lock(mtx_sendReply); // RAII-style acquire and relinquish via destructor DBG_PRINT("HCIHandler<%u>::resetAdapter.0: %s", dev_id, toString().c_str()); @@ -1045,16 +1047,25 @@ HCIStatusCode HCIHandler::resetAdapter() { #if defined(__linux__) res = stopAdapter(); if( HCIStatusCode::SUCCESS == res ) { - res = startAdapter(); + if( nullptr != user_post_shutdown ) { + user_called = true; + res = user_post_shutdown(); + user_abort = HCIStatusCode::SUCCESS != res; + } + if( !user_abort ) { + res = startAdapter(); + } } #elif defined(__FreeBSD__) // #warning add implementation + (void)user_post_shutdown; ABORT("add implementation for FreeBSD"); #else #warning add implementation + (void)user_post_shutdown; ABORT("add implementation"); #endif - DBG_PRINT("HCIHandler<%u>::resetAdapter.X: %s - %s", dev_id, to_string(res).c_str(), toString().c_str()); + DBG_PRINT("HCIHandler<%u>::resetAdapter.X: %s user[called %d, abort %d] - %s", dev_id, to_string(res).c_str(), user_called, user_abort, toString().c_str()); return res; } |