diff options
Diffstat (limited to 'src/direct_bt')
-rw-r--r-- | src/direct_bt/BTAdapter.cpp | 24 | ||||
-rw-r--r-- | src/direct_bt/BTDevice.cpp | 13 | ||||
-rw-r--r-- | src/direct_bt/BTGattCmd.cpp | 8 | ||||
-rw-r--r-- | src/direct_bt/BTGattHandler.cpp | 20 | ||||
-rw-r--r-- | src/direct_bt/BTManager.cpp | 21 | ||||
-rw-r--r-- | src/direct_bt/HCIComm.cpp | 5 | ||||
-rw-r--r-- | src/direct_bt/HCIHandler.cpp | 53 | ||||
-rw-r--r-- | src/direct_bt/SMPHandler.cpp | 7 |
8 files changed, 77 insertions, 74 deletions
diff --git a/src/direct_bt/BTAdapter.cpp b/src/direct_bt/BTAdapter.cpp index 86839904..5c4f3fd6 100644 --- a/src/direct_bt/BTAdapter.cpp +++ b/src/direct_bt/BTAdapter.cpp @@ -50,6 +50,7 @@ extern "C" { } using namespace direct_bt; +using namespace jau::fractions_i64_literals; constexpr static const bool _print_device_lists = false; @@ -641,7 +642,7 @@ void BTAdapter::setServerConnSecurity(const BTSecurityLevel sec_level, const SMP } void BTAdapter::setSMPKeyPath(const std::string path) noexcept { - jau::sc_atomic_critical sync(sync_data); // redundant due to mutex-lock cache-load operation, leaving it for doc + jau::sc_atomic_critical sync(sync_data); key_path = path; std::vector<SMPKeyBin> keys = SMPKeyBin::readAllForLocalAdapter(getAddressAndType(), key_path, jau::environment::get().debug /* verbose_ */); @@ -726,7 +727,7 @@ HCIStatusCode BTAdapter::initialize(const BTMode btMode) noexcept { bool BTAdapter::lockConnect(const BTDevice & device, const bool wait, const SMPIOCapability io_cap) noexcept { std::unique_lock<std::mutex> lock(mtx_single_conn_device); // RAII-style acquire and relinquish via destructor - const uint32_t timeout_ms = 10000; // FIXME: Configurable? + const jau::fraction_i64 timeout = 10_s; // FIXME: Configurable? if( nullptr != single_conn_device_ptr ) { if( device == *single_conn_device_ptr ) { @@ -734,9 +735,9 @@ bool BTAdapter::lockConnect(const BTDevice & device, const bool wait, const SMPI return true; // already set, same device: OK, locked } if( wait ) { + const jau::fraction_timespec timeout_time = jau::getMonotonicTime() + jau::fraction_timespec(timeout); while( nullptr != single_conn_device_ptr ) { - std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now(); - std::cv_status s = cv_single_conn_device.wait_until(lock, t0 + std::chrono::milliseconds(timeout_ms)); + std::cv_status s = wait_until(cv_single_conn_device, lock, timeout_time); if( std::cv_status::timeout == s && nullptr != single_conn_device_ptr ) { if( debug_lock ) { jau::PLAIN_PRINT(true, "BTAdapter::lockConnect: Failed: Locked (waited)"); @@ -1408,12 +1409,10 @@ bool BTAdapter::removeSMPKeyBin(key_list_t & keys, BDAddressAndType const & remo } BTAdapter::SMPKeyBinRef BTAdapter::findSMPKeyBin(BDAddressAndType const & remoteAddress) noexcept { const std::lock_guard<std::mutex> lock(mtx_keys); // RAII-style acquire and relinquish via destructor - jau::sc_atomic_critical sync(sync_data); // redundant due to mutex-lock cache-load operation, leaving it for doc return findSMPKeyBin(key_list, remoteAddress); } bool BTAdapter::addSMPKeyBin(const SMPKeyBinRef& key, const bool write_file) noexcept { const std::lock_guard<std::mutex> lock(mtx_keys); // RAII-style acquire and relinquish via destructor - jau::sc_atomic_critical sync(sync_data); // redundant due to mutex-lock cache-load operation, leaving it for doc removeSMPKeyBin(key_list, key->getRemoteAddrAndType(), write_file /* remove_file */, key_path); if( jau::environment::get().debug ) { key->setVerbose(true); @@ -1429,7 +1428,6 @@ bool BTAdapter::addSMPKeyBin(const SMPKeyBinRef& key, const bool write_file) noe } bool BTAdapter::removeSMPKeyBin(BDAddressAndType const & remoteAddress, const bool remove_file) noexcept { const std::lock_guard<std::mutex> lock(mtx_keys); // RAII-style acquire and relinquish via destructor - jau::sc_atomic_critical sync(sync_data); // redundant due to mutex-lock cache-load operation, leaving it for doc return removeSMPKeyBin(key_list, remoteAddress, remove_file, key_path); } @@ -1830,12 +1828,12 @@ void BTAdapter::l2capServerWork(jau::service_runner& sr) { std::unique_ptr<L2CAPClient> BTAdapter::get_l2cap_connection(std::shared_ptr<BTDevice> device) { if( BTRole::Slave == getRole() ) { const BDAddressAndType& clientAddrAndType = device->getAddressAndType(); - const jau::nsize_t timeout_ms = L2CAP_CLIENT_CONNECT_TIMEOUT_MS; + const jau::fraction_i64 timeout = L2CAP_CLIENT_CONNECT_TIMEOUT_MS; std::unique_lock<std::mutex> lock(mtx_l2cap_att); // RAII-style acquire and relinquish via destructor + const jau::fraction_timespec timeout_time = jau::getMonotonicTime() + jau::fraction_timespec(timeout); while( device->getConnected() && ( nullptr == l2cap_att || l2cap_att->getRemoteAddressAndType() != clientAddrAndType ) ) { - std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now(); - std::cv_status s = cv_l2cap_att.wait_until(lock, t0 + std::chrono::milliseconds(timeout_ms)); + std::cv_status s = wait_until(cv_l2cap_att, lock, timeout_time); if( std::cv_status::timeout == s && ( nullptr == l2cap_att || l2cap_att->getRemoteAddressAndType() != clientAddrAndType ) ) { DBG_PRINT("L2CAP-ACCEPT: BTAdapter:get_l2cap_connection(dev_id %d): l2cap_att TIMEOUT", dev_id); return nullptr; @@ -1855,9 +1853,9 @@ std::unique_ptr<L2CAPClient> BTAdapter::get_l2cap_connection(std::shared_ptr<BTD } } -jau::nsize_t BTAdapter::smp_timeoutfunc(jau::simple_timer& timer) { +jau::fraction_i64 BTAdapter::smp_timeoutfunc(jau::simple_timer& timer) { if( timer.shall_stop() ) { - return 0; + return 0_s; } device_list_t failed_devices; { @@ -1895,7 +1893,7 @@ jau::nsize_t BTAdapter::smp_timeoutfunc(jau::simple_timer& timer) { device->hciSMPMsgCallback(device, msg, source); DBG_PRINT("BTAdapter::smp_timeoutfunc(dev_id %d): SMP Timeout: Done: smp_auto %d, %s", dev_id, smp_auto, device->toString().c_str()); }); - return timer.shall_stop() ? 0 : SMP_NEXT_EVENT_TIMEOUT_MS; // keep going until BTAdapter closes + return timer.shall_stop() ? 0_s : SMP_NEXT_EVENT_TIMEOUT_MS; // keep going until BTAdapter closes } bool BTAdapter::mgmtEvDeviceConnectedHCI(const MgmtEvent& e) noexcept { diff --git a/src/direct_bt/BTDevice.cpp b/src/direct_bt/BTDevice.cpp index 68ca0e65..b4a4a1c2 100644 --- a/src/direct_bt/BTDevice.cpp +++ b/src/direct_bt/BTDevice.cpp @@ -43,6 +43,7 @@ #include "BTGattService.hpp" using namespace direct_bt; +using namespace jau::fractions_i64_literals; BTDevice::BTDevice(const ctor_cookie& cc, BTAdapter & a, EInfoReport const & r) : adapter(a), btRole(!a.getRole()), @@ -424,10 +425,9 @@ HCIStatusCode BTDevice::connectLE(const uint16_t le_scan_interval, const uint16_ bool pairing_timeout = false; { std::unique_lock<std::recursive_mutex> lock_pairing(mtx_pairing); // RAII-style acquire and relinquish via destructor - + const std::chrono::steady_clock::time_point timeout_time = std::chrono::steady_clock::now() + hci.env.HCI_COMMAND_COMPLETE_REPLY_TIMEOUT.to_duration(std::chrono::milliseconds::zero()); while( !hasSMPPairingFinished( pairing_data.state ) ) { - std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now(); - std::cv_status s = cv_pairing_state_changed.wait_until(lock_pairing, t0 + std::chrono::milliseconds(hci.env.HCI_COMMAND_COMPLETE_REPLY_TIMEOUT)); + std::cv_status s = cv_pairing_state_changed.wait_until(lock_pairing, timeout_time); DBG_PRINT("BTDevice::connectLE: SEC AUTO.%d.2c Wait for SMPPairing: state %s, %s", smp_auto_count, to_string(pairing_data.state).c_str(), toString().c_str()); if( std::cv_status::timeout == s && !hasSMPPairingFinished( pairing_data.state ) ) { @@ -456,20 +456,20 @@ HCIStatusCode BTDevice::connectLE(const uint16_t le_scan_interval, const uint16_ } else if( SMPPairingState::FAILED == pstate ) { if( !smp_auto_done ) { // not last one // disconnect for next smp_auto mode test - int32_t td_disconnect = 0; + jau::fraction_i64 td_disconnect = 0_s; DBG_PRINT("BTDevice::connectLE: SEC AUTO.%d.3 Failed SMPPairing -> Disconnect: %s", smp_auto_count, toString().c_str()); HCIStatusCode dres = disconnect(HCIStatusCode::AUTHENTICATION_FAILURE); if( HCIStatusCode::SUCCESS == dres ) { while( isConnected && hci.env.HCI_COMMAND_COMPLETE_REPLY_TIMEOUT > td_disconnect ) { jau::sc_atomic_critical sync2(sync_data); td_disconnect += hci.env.HCI_COMMAND_POLL_PERIOD; - std::this_thread::sleep_for(std::chrono::milliseconds(hci.env.HCI_COMMAND_POLL_PERIOD)); + sleep_for(hci.env.HCI_COMMAND_POLL_PERIOD); } } if( hci.env.HCI_COMMAND_COMPLETE_REPLY_TIMEOUT <= td_disconnect ) { // timeout ERR_PRINT("SEC AUTO.%d.4 Timeout Disconnect td_pairing %d ms: %s", - smp_auto_count, td_disconnect, toString().c_str()); + smp_auto_count, td_disconnect.to_ms(), toString().c_str()); pairing_data.ioCap_auto = SMPIOCapability::UNSET; statusConnect = HCIStatusCode::INTERNAL_TIMEOUT; adapter.unlockConnect(*this); @@ -1971,6 +1971,7 @@ jau::darray<BTGattServiceRef> BTDevice::getGattServices() noexcept { if( gatt_already_init ) { return gattServices; // copy previous discovery result } + // FIXME: GATTHandler::sendWithReply() == nullptr but gattServices.size() > 0 !!! if( gattServices.size() == 0 ) { // nothing discovered ERR_PRINT2("BTDevice::getGattServices: No primary services discovered"); return gattServices; diff --git a/src/direct_bt/BTGattCmd.cpp b/src/direct_bt/BTGattCmd.cpp index f68504c1..a4f20d0a 100644 --- a/src/direct_bt/BTGattCmd.cpp +++ b/src/direct_bt/BTGattCmd.cpp @@ -166,7 +166,7 @@ bool BTGattCmd::isResolved() noexcept { } } -HCIStatusCode BTGattCmd::send(const bool prefNoAck, const jau::TROOctets& cmd_data, const int timeoutMS) noexcept { +HCIStatusCode BTGattCmd::send(const bool prefNoAck, const jau::TROOctets& cmd_data, const jau::fraction_i64& timeout) noexcept { std::unique_lock<std::mutex> lockCmd(mtxCommand); // RAII-style acquire and relinquish via destructor HCIStatusCode res = HCIStatusCode::SUCCESS; @@ -220,12 +220,12 @@ HCIStatusCode BTGattCmd::send(const bool prefNoAck, const jau::TROOctets& cmd_da } if( nullptr != rspCharRef ) { + const jau::fraction_timespec timeout_time = jau::getMonotonicTime() + jau::fraction_timespec(timeout); while( HCIStatusCode::SUCCESS == res && 0 == rsp_data.size() ) { - if( 0 == timeoutMS ) { + if( jau::fractions_i64::zero == timeout ) { cvRspReceived.wait(lockRsp); } else { - std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now(); - std::cv_status s = cvRspReceived.wait_until(lockRsp, t0 + std::chrono::milliseconds(timeoutMS)); + std::cv_status s = wait_until(cvRspReceived, lockRsp, timeout_time); if( std::cv_status::timeout == s && 0 == rsp_data.size() ) { ERR_PRINT("BTGattCmd::sendBlocking: Timeout: Cmd %s, args[%s]", cmdCharRef->toString().c_str(), cmd_data.toString().c_str()); diff --git a/src/direct_bt/BTGattHandler.cpp b/src/direct_bt/BTGattHandler.cpp index 1534a8ad..2ff53048 100644 --- a/src/direct_bt/BTGattHandler.cpp +++ b/src/direct_bt/BTGattHandler.cpp @@ -67,9 +67,9 @@ using namespace direct_bt; BTGattEnv::BTGattEnv() noexcept : exploding( jau::environment::getExplodingProperties("direct_bt.gatt") ), - GATT_READ_COMMAND_REPLY_TIMEOUT( jau::environment::getInt32Property("direct_bt.gatt.cmd.read.timeout", 550, 550 /* min */, INT32_MAX /* max */) ), - GATT_WRITE_COMMAND_REPLY_TIMEOUT( jau::environment::getInt32Property("direct_bt.gatt.cmd.write.timeout", 550, 550 /* min */, INT32_MAX /* max */) ), - GATT_INITIAL_COMMAND_REPLY_TIMEOUT( jau::environment::getInt32Property("direct_bt.gatt.cmd.init.timeout", 2500, 2000 /* min */, INT32_MAX /* max */) ), + GATT_READ_COMMAND_REPLY_TIMEOUT( jau::environment::getFractionProperty("direct_bt.gatt.cmd.read.timeout", 550_ms, 550_ms /* min */, 365_d /* max */) ), + GATT_WRITE_COMMAND_REPLY_TIMEOUT( jau::environment::getFractionProperty("direct_bt.gatt.cmd.write.timeout", 550_ms, 550_ms /* min */, 365_d /* max */) ), + GATT_INITIAL_COMMAND_REPLY_TIMEOUT( jau::environment::getFractionProperty("direct_bt.gatt.cmd.init.timeout", 2500_ms, 2000_ms /* min */, 365_d /* max */) ), ATTPDU_RING_CAPACITY( jau::environment::getInt32Property("direct_bt.gatt.ringsize", 128, 64 /* min */, 1024 /* max */) ), DEBUG_DATA( jau::environment::getBooleanProperty("direct_bt.debug.gatt.data", false) ) { @@ -507,7 +507,7 @@ void BTGattHandler::l2capReaderWork(jau::service_runner& sr) noexcept { } } else if( AttPDUMsg::OpcodeType::RESPONSE == opc_type ) { COND_PRINT(env.DEBUG_DATA, "GATTHandler::reader: Ring: %s", attPDU->toString().c_str()); - attPDURing.putBlocking( std::move(attPDU) ); + attPDURing.putBlocking( std::move(attPDU), 0_s ); } else if( AttPDUMsg::OpcodeType::REQUEST == opc_type ) { if( !replyAttPDUReq( std::move( attPDU ) ) ) { ERR_PRINT2("ATT Reply: %s", toString().c_str()); @@ -571,8 +571,8 @@ bool BTGattHandler::l2capReaderInterrupted(int dummy) /* const */ noexcept { BTGattHandler::BTGattHandler(const BTDeviceRef &device, L2CAPClient& l2cap_att, const int32_t supervision_timeout_) noexcept : supervision_timeout(supervision_timeout_), env(BTGattEnv::get()), - read_cmd_reply_timeout(std::max<int32_t>(env.GATT_READ_COMMAND_REPLY_TIMEOUT, supervision_timeout+50)), - write_cmd_reply_timeout(std::max<int32_t>(env.GATT_WRITE_COMMAND_REPLY_TIMEOUT, supervision_timeout+50)), + read_cmd_reply_timeout(jau::max(env.GATT_READ_COMMAND_REPLY_TIMEOUT, 1_ms*(supervision_timeout+50_i64))), + write_cmd_reply_timeout(jau::max(env.GATT_WRITE_COMMAND_REPLY_TIMEOUT, 1_ms*(supervision_timeout+50_i64))), wbr_device(device), role(device->getLocalGATTRole()), l2cap(l2cap_att), @@ -741,7 +741,7 @@ bool BTGattHandler::send(const AttPDUMsg & msg) noexcept { } } -std::unique_ptr<const AttPDUMsg> BTGattHandler::sendWithReply(const AttPDUMsg & msg, const int timeout) noexcept { +std::unique_ptr<const AttPDUMsg> BTGattHandler::sendWithReply(const AttPDUMsg & msg, const jau::fraction_i64& timeout) noexcept { if( !send( msg ) ) { return nullptr; } @@ -750,7 +750,7 @@ std::unique_ptr<const AttPDUMsg> BTGattHandler::sendWithReply(const AttPDUMsg & std::unique_ptr<const AttPDUMsg> res; if( !attPDURing.getBlocking(res, timeout) || nullptr == res ) { errno = ETIMEDOUT; - ERR_PRINT("GATTHandler::sendWithReply: nullptr result (timeout %d): req %s to %s", timeout, msg.toString().c_str(), toString().c_str()); + ERR_PRINT("GATTHandler::sendWithReply: nullptr result (timeout %d): req %s to %s", timeout.to_ms(), msg.toString().c_str(), toString().c_str()); has_ioerror = true; disconnect(true /* disconnect_device */, true /* ioerr_cause */); return nullptr; @@ -758,7 +758,7 @@ std::unique_ptr<const AttPDUMsg> BTGattHandler::sendWithReply(const AttPDUMsg & return res; } -uint16_t BTGattHandler::clientMTUExchange(const int32_t timeout) noexcept { +uint16_t BTGattHandler::clientMTUExchange(const jau::fraction_i64& timeout) noexcept { if( GATTRole::Client != getRole() ) { ERR_PRINT("GATT MTU exchange only allowed in client mode"); return usedMTU; @@ -896,7 +896,7 @@ bool BTGattHandler::initClientGatt(std::shared_ptr<BTGattHandler> shared_this, b } if( !clientMTUExchanged) { // First point of failure if remote device exposes no GATT functionality. Allow a longer timeout! - const int32_t initial_command_reply_timeout = std::min<int32_t>(10000, std::max<int32_t>(env.GATT_INITIAL_COMMAND_REPLY_TIMEOUT, 2*supervision_timeout)); + const jau::fraction_i64 initial_command_reply_timeout = jau::min(10_s, jau::max(env.GATT_INITIAL_COMMAND_REPLY_TIMEOUT, 1_ms*(2_i64*supervision_timeout))); DBG_PRINT("GATTHandler::initClientGatt: Local GATT Client: MTU Exchange Start: %s", toString().c_str()); uint16_t mtu = clientMTUExchange(initial_command_reply_timeout); if( 0 == mtu ) { diff --git a/src/direct_bt/BTManager.cpp b/src/direct_bt/BTManager.cpp index 69fd9be4..d10d356d 100644 --- a/src/direct_bt/BTManager.cpp +++ b/src/direct_bt/BTManager.cpp @@ -57,15 +57,16 @@ extern "C" { } using namespace direct_bt; +using namespace jau::fractions_i64_literals; MgmtEnv::MgmtEnv() noexcept : DEBUG_GLOBAL( jau::environment::get("direct_bt").debug ), exploding( jau::environment::getExplodingProperties("direct_bt.mgmt") ), - MGMT_READER_THREAD_POLL_TIMEOUT( jau::environment::getInt32Property("direct_bt.mgmt.reader.timeout", 10000, 1500 /* min */, INT32_MAX /* max */) ), - MGMT_COMMAND_REPLY_TIMEOUT( jau::environment::getInt32Property("direct_bt.mgmt.cmd.timeout", 3000, 1500 /* min */, INT32_MAX /* max */) ), - MGMT_SET_POWER_COMMAND_TIMEOUT( jau::environment::getInt32Property("direct_bt.mgmt.setpower.timeout", - std::max(MGMT_COMMAND_REPLY_TIMEOUT, 6000) /* default */, - MGMT_COMMAND_REPLY_TIMEOUT /* min */, INT32_MAX /* max */) ), + MGMT_READER_THREAD_POLL_TIMEOUT( jau::environment::getFractionProperty("direct_bt.mgmt.reader.timeout", 10_s, 1500_ms /* min */, 365_d /* max */) ), + MGMT_COMMAND_REPLY_TIMEOUT( jau::environment::getFractionProperty("direct_bt.mgmt.cmd.timeout", 3_s, 1500_ms /* min */, 365_d /* max */) ), + MGMT_SET_POWER_COMMAND_TIMEOUT( jau::environment::getFractionProperty("direct_bt.mgmt.setpower.timeout", + jau::max(MGMT_COMMAND_REPLY_TIMEOUT, 6_s) /* default */, + MGMT_COMMAND_REPLY_TIMEOUT /* min */, 365_d /* max */) ), MGMT_EVT_RING_CAPACITY( jau::environment::getInt32Property("direct_bt.mgmt.ringsize", 64, 64 /* min */, 1024 /* max */) ), DEBUG_EVENT( jau::environment::getBooleanProperty("direct_bt.debug.mgmt.event", false) ), MGMT_READ_PACKET_MAX_RETRY( MGMT_EVT_RING_CAPACITY ) @@ -103,7 +104,7 @@ void BTManager::mgmtReaderWork(jau::service_runner& sr) noexcept { mgmtEventRing.drop(dropCount); WARN_PRINT("BTManager-IO RECV Drop (%u oldest elements of %u capacity, ring full)", dropCount, mgmtEventRing.capacity()); } - mgmtEventRing.putBlocking( std::move( event ) ); + mgmtEventRing.putBlocking( std::move( event ), 0_s ); } else if( MgmtEvent::Opcode::INDEX_ADDED == opc ) { COND_PRINT(env.DEBUG_EVENT, "BTManager-IO RECV (ADD) %s", event->toString().c_str()); std::thread adapterAddedThread(&BTManager::processAdapterAdded, this, std::move( event) ); // @suppress("Invalid arguments") @@ -164,7 +165,7 @@ bool BTManager::send(MgmtCommand &req) noexcept { return true; } -std::unique_ptr<MgmtEvent> BTManager::sendWithReply(MgmtCommand &req, const int timeoutMS) noexcept { +std::unique_ptr<MgmtEvent> BTManager::sendWithReply(MgmtCommand &req, const jau::fraction_i64& timeout) noexcept { const std::lock_guard<std::recursive_mutex> lock(mtx_sendReply); // RAII-style acquire and relinquish via destructor if( !send(req) ) { return nullptr; @@ -175,7 +176,7 @@ std::unique_ptr<MgmtEvent> BTManager::sendWithReply(MgmtCommand &req, const int while( retryCount < env.MGMT_READ_PACKET_MAX_RETRY ) { /* timeoutMS default: env.MGMT_COMMAND_REPLY_TIMEOUT */ std::unique_ptr<MgmtEvent> res; - if( !mgmtEventRing.getBlocking(res, timeoutMS) || nullptr == res ) { + if( !mgmtEventRing.getBlocking(res, timeout) || nullptr == res ) { errno = ETIMEDOUT; ERR_PRINT("BTManager::sendWithReply.X: nullptr result (timeout -> abort): req %s", req.toString().c_str()); return nullptr; @@ -660,9 +661,9 @@ SMPIOCapability BTManager::getIOCapability(const uint16_t dev_id) const noexcept } bool BTManager::setMode(const uint16_t dev_id, const MgmtCommand::Opcode opc, const uint8_t mode, AdapterSetting& current_settings) noexcept { - const int timeoutMS = MgmtCommand::Opcode::SET_POWERED == opc ? env.MGMT_SET_POWER_COMMAND_TIMEOUT : env.MGMT_COMMAND_REPLY_TIMEOUT; + const jau::fraction_i64& timeout = MgmtCommand::Opcode::SET_POWERED == opc ? env.MGMT_SET_POWER_COMMAND_TIMEOUT : env.MGMT_COMMAND_REPLY_TIMEOUT; MgmtUint8Cmd req(opc, dev_id, mode); - std::unique_ptr<MgmtEvent> reply = sendWithReply(req, timeoutMS); + std::unique_ptr<MgmtEvent> reply = sendWithReply(req, timeout); MgmtStatus res; if( nullptr != reply ) { if( reply->getOpcode() == MgmtEvent::Opcode::CMD_COMPLETE ) { diff --git a/src/direct_bt/HCIComm.cpp b/src/direct_bt/HCIComm.cpp index 09e2c008..277508e1 100644 --- a/src/direct_bt/HCIComm.cpp +++ b/src/direct_bt/HCIComm.cpp @@ -141,7 +141,7 @@ void HCIComm::close() noexcept { DBG_PRINT("HCIComm::close: End: dd %d", socket_descriptor.load()); } -jau::snsize_t HCIComm::read(uint8_t* buffer, const jau::nsize_t capacity, const int32_t timeoutMS) noexcept { +jau::snsize_t HCIComm::read(uint8_t* buffer, const jau::nsize_t capacity, const jau::fraction_i64& timeout) noexcept { jau::snsize_t len = 0; if( 0 > socket_descriptor ) { goto errout; @@ -150,9 +150,10 @@ jau::snsize_t HCIComm::read(uint8_t* buffer, const jau::nsize_t capacity, const goto done; } - if( timeoutMS ) { + if( !timeout.is_zero() ) { struct pollfd p; int n; + const int32_t timeoutMS = timeout.to_num_of(jau::fractions_i64::milli); p.fd = socket_descriptor; p.events = POLLIN; while ( !interrupted() && (n = ::poll(&p, 1, timeoutMS)) < 0 ) { diff --git a/src/direct_bt/HCIHandler.cpp b/src/direct_bt/HCIHandler.cpp index 9e6a0ffc..9e1aca74 100644 --- a/src/direct_bt/HCIHandler.cpp +++ b/src/direct_bt/HCIHandler.cpp @@ -58,13 +58,14 @@ extern "C" { } using namespace direct_bt; +using namespace jau::fractions_i64_literals; HCIEnv::HCIEnv() noexcept : exploding( jau::environment::getExplodingProperties("direct_bt.hci") ), - HCI_READER_THREAD_POLL_TIMEOUT( jau::environment::getInt32Property("direct_bt.hci.reader.timeout", 10000, 1500 /* min */, INT32_MAX /* max */) ), - HCI_COMMAND_STATUS_REPLY_TIMEOUT( jau::environment::getInt32Property("direct_bt.hci.cmd.status.timeout", 3000, 1500 /* min */, INT32_MAX /* max */) ), - HCI_COMMAND_COMPLETE_REPLY_TIMEOUT( jau::environment::getInt32Property("direct_bt.hci.cmd.complete.timeout", 10000, 1500 /* min */, INT32_MAX /* max */) ), - HCI_COMMAND_POLL_PERIOD( jau::environment::getInt32Property("direct_bt.hci.cmd.poll.period", 125, 50 /* min */, INT32_MAX /* max */) ), + HCI_READER_THREAD_POLL_TIMEOUT( jau::environment::getFractionProperty("direct_bt.hci.reader.timeout", 10_s, 1500_ms /* min */, 365_d /* max */) ), + HCI_COMMAND_STATUS_REPLY_TIMEOUT( jau::environment::getFractionProperty("direct_bt.hci.cmd.status.timeout", 3_s, 1500_ms /* min */, 365_d /* max */) ), + HCI_COMMAND_COMPLETE_REPLY_TIMEOUT( jau::environment::getFractionProperty("direct_bt.hci.cmd.complete.timeout", 10_s, 1500_ms /* min */, 365_d /* max */) ), + HCI_COMMAND_POLL_PERIOD( jau::environment::getFractionProperty("direct_bt.hci.cmd.poll.period", 125_ms, 50_ms, 365_d) ), HCI_EVT_RING_CAPACITY( jau::environment::getInt32Property("direct_bt.hci.ringsize", 64, 64 /* min */, 1024 /* max */) ), DEBUG_EVENT( jau::environment::getBooleanProperty("direct_bt.debug.hci.event", false) ), DEBUG_SCAN_AD_EIR( jau::environment::getBooleanProperty("direct_bt.debug.hci.scan_ad_eir", false) ), @@ -521,7 +522,7 @@ void HCIHandler::hciReaderWork(jau::service_runner& sr) noexcept { WARN_PRINT("HCIHandler<%u>-IO RECV Drop (%u oldest elements of %u capacity, ring full) - %s", dev_id, dropCount, hciEventRing.capacity(), toString().c_str()); } - hciEventRing.putBlocking( std::move( event ) ); + hciEventRing.putBlocking( std::move( event ), jau::fractions_i64::zero ); } else if( event->isMetaEvent(HCIMetaEventType::LE_ADVERTISING_REPORT) ) { // issue callbacks for the translated AD events jau::darray<std::unique_ptr<EInfoReport>> eirlist = EInfoReport::read_ad_reports(event->getParam(), event->getParamSize()); @@ -599,15 +600,15 @@ bool HCIHandler::sendCommand(HCICommand &req, const bool quiet) noexcept { return true; } -std::unique_ptr<HCIEvent> HCIHandler::getNextReply(HCICommand &req, int32_t & retryCount, const int32_t replyTimeoutMS) noexcept +std::unique_ptr<HCIEvent> HCIHandler::getNextReply(HCICommand &req, int32_t & retryCount, const jau::fraction_i64& replyTimeout) noexcept { // Ringbuffer read is thread safe while( retryCount < env.HCI_READ_PACKET_MAX_RETRY ) { std::unique_ptr<HCIEvent> ev; - if( !hciEventRing.getBlocking(ev, replyTimeoutMS) || nullptr == ev ) { + if( !hciEventRing.getBlocking(ev, replyTimeout) || nullptr == ev ) { errno = ETIMEDOUT; - ERR_PRINT("HCIHandler<%u>::getNextReply: nullptr result (timeout %d ms -> abort): req %s - %s", - dev_id, replyTimeoutMS, req.toString().c_str(), toString().c_str()); + ERR_PRINT("HCIHandler<%u>::getNextReply: nullptr result (timeout %s -> abort): req %s - %s", + dev_id, replyTimeout.to_string(), req.toString().c_str(), toString().c_str()); return nullptr; } else if( !ev->validate(req) ) { // This could occur due to an earlier timeout w/ a nullptr == res (see above), @@ -1251,16 +1252,16 @@ HCIStatusCode HCIHandler::le_create_conn(const EUI48 &peer_bdaddr, int pendingConnections = countPendingTrackerConnections(); if( 0 < pendingConnections ) { DBG_PRINT("HCIHandler::le_create_conn: %d connections pending - %s", pendingConnections, toString().c_str()); - int32_t td = 0; + jau::fraction_i64 td = 0_s; while( env.HCI_COMMAND_COMPLETE_REPLY_TIMEOUT > td && 0 < pendingConnections ) { - std::this_thread::sleep_for(std::chrono::milliseconds(env.HCI_COMMAND_POLL_PERIOD)); + sleep_for(env.HCI_COMMAND_POLL_PERIOD); td += env.HCI_COMMAND_POLL_PERIOD; pendingConnections = countPendingTrackerConnections(); } if( 0 < pendingConnections ) { - WARN_PRINT("HCIHandler::le_create_conn: %d connections pending after %d ms - %s", pendingConnections, td, toString().c_str()); + WARN_PRINT("HCIHandler::le_create_conn: %d connections pending after %d ms - %s", pendingConnections, td.to_ms(), toString().c_str()); } else { - DBG_PRINT("HCIHandler::le_create_conn: pending connections resolved after %d ms - %s", td, toString().c_str()); + DBG_PRINT("HCIHandler::le_create_conn: pending connections resolved after %d ms - %s", td.to_ms(), toString().c_str()); } } const BDAddressAndType addressAndType(peer_bdaddr, to_BDAddressType(peer_mac_type)); @@ -1268,17 +1269,17 @@ HCIStatusCode HCIHandler::le_create_conn(const EUI48 &peer_bdaddr, if( nullptr != disconn ) { DBG_PRINT("HCIHandler::le_create_conn: disconnect pending %s - %s", disconn->toString().c_str(), toString().c_str()); - int32_t td = 0; + jau::fraction_i64 td = 0_s; while( env.HCI_COMMAND_COMPLETE_REPLY_TIMEOUT > td && nullptr != disconn ) { - std::this_thread::sleep_for(std::chrono::milliseconds(env.HCI_COMMAND_POLL_PERIOD)); + sleep_for(env.HCI_COMMAND_POLL_PERIOD); td += env.HCI_COMMAND_POLL_PERIOD; disconn = findDisconnectCmd(addressAndType); } if( nullptr != disconn ) { WARN_PRINT("HCIHandler::le_create_conn: disconnect persisting after %d ms: %s - %s", - td, disconn->toString().c_str(), toString().c_str()); + td.to_ms(), disconn->toString().c_str(), toString().c_str()); } else { - DBG_PRINT("HCIHandler::le_create_conn: disconnect resolved after %d ms - %s", td, toString().c_str()); + DBG_PRINT("HCIHandler::le_create_conn: disconnect resolved after %d ms - %s", td.to_ms(), toString().c_str()); } } HCIConnectionRef conn = addOrUpdateTrackerConnection(addressAndType, 0); @@ -1380,16 +1381,16 @@ HCIStatusCode HCIHandler::create_conn(const EUI48 &bdaddr, int pendingConnections = countPendingTrackerConnections(); if( 0 < pendingConnections ) { DBG_PRINT("HCIHandler::create_conn: %d connections pending - %s", pendingConnections, toString().c_str()); - int32_t td = 0; + jau::fraction_i64 td = 0_s; while( env.HCI_COMMAND_COMPLETE_REPLY_TIMEOUT > td && 0 < pendingConnections ) { - std::this_thread::sleep_for(std::chrono::milliseconds(env.HCI_COMMAND_POLL_PERIOD)); + sleep_for(env.HCI_COMMAND_POLL_PERIOD); td += env.HCI_COMMAND_POLL_PERIOD; pendingConnections = countPendingTrackerConnections(); } if( 0 < pendingConnections ) { - WARN_PRINT("HCIHandler::create_conn: %d connections pending after %d ms - %s", pendingConnections, td, toString().c_str()); + WARN_PRINT("HCIHandler::create_conn: %d connections pending after %d ms - %s", pendingConnections, td.to_ms(), toString().c_str()); } else { - DBG_PRINT("HCIHandler::create_conn: pending connections resolved after %d ms - %s", td, toString().c_str()); + DBG_PRINT("HCIHandler::create_conn: pending connections resolved after %d ms - %s", td.to_ms(), toString().c_str()); } } const BDAddressAndType addressAndType(bdaddr, BDAddressType::BDADDR_BREDR); @@ -1397,17 +1398,17 @@ HCIStatusCode HCIHandler::create_conn(const EUI48 &bdaddr, if( nullptr != disconn ) { DBG_PRINT("HCIHandler::create_conn: disconnect pending %s - %s", disconn->toString().c_str(), toString().c_str()); - int32_t td = 0; + jau::fraction_i64 td = 0_s; while( env.HCI_COMMAND_COMPLETE_REPLY_TIMEOUT > td && nullptr != disconn ) { - std::this_thread::sleep_for(std::chrono::milliseconds(env.HCI_COMMAND_POLL_PERIOD)); + sleep_for(env.HCI_COMMAND_POLL_PERIOD); td += env.HCI_COMMAND_POLL_PERIOD; disconn = findDisconnectCmd(addressAndType); } if( nullptr != disconn ) { - WARN_PRINT("HCIHandler::create_conn: disconnect persisting after %d ms: %s - %s", - td, disconn->toString().c_str(), toString().c_str()); + WARN_PRINT("HCIHandler::create_conn: disconnect persisting after %s ms: %s - %s", + td.to_ms(), disconn->toString().c_str(), toString().c_str()); } else { - DBG_PRINT("HCIHandler::create_conn: disconnect resolved after %d ms - %s", td, toString().c_str()); + DBG_PRINT("HCIHandler::create_conn: disconnect resolved after %d ms - %s", td.to_ms(), toString().c_str()); } } HCIConnectionRef conn = addOrUpdateTrackerConnection(addressAndType, 0); diff --git a/src/direct_bt/SMPHandler.cpp b/src/direct_bt/SMPHandler.cpp index 255bf24b..32db2be1 100644 --- a/src/direct_bt/SMPHandler.cpp +++ b/src/direct_bt/SMPHandler.cpp @@ -57,6 +57,7 @@ extern "C" { #include "DBTConst.hpp" using namespace direct_bt; +using namespace jau::fractions_i64_literals; SMPEnv::SMPEnv() noexcept : exploding( jau::environment::getExplodingProperties("direct_bt.smp") ), @@ -121,7 +122,7 @@ void SMPHandler::smpReaderWork(jau::service_runner& sr) noexcept { smpPDURing.drop(dropCount); WARN_PRINT("SMPHandler-IO RECV Drop (%u oldest elements of %u capacity, ring full)", dropCount, smpPDURing.capacity()); } - smpPDURing.putBlocking( std::move(smpPDU) ); + smpPDURing.putBlocking( std::move(smpPDU), 0_s ); } } else if( len == L2CAPClient::number(L2CAPClient::RWExitCode::INTERRUPTED) ) { WORDY_PRINT("SMPHandler::reader: l2cap read: IRQed res %d (%s); %s", @@ -280,7 +281,7 @@ void SMPHandler::send(const SMPPDUMsg & msg) { } } -std::unique_ptr<const SMPPDUMsg> SMPHandler::sendWithReply(const SMPPDUMsg & msg, const int timeout) { +std::unique_ptr<const SMPPDUMsg> SMPHandler::sendWithReply(const SMPPDUMsg & msg, const jau::fraction_i64& timeout) { send( msg ); // Ringbuffer read is thread safe @@ -290,7 +291,7 @@ std::unique_ptr<const SMPPDUMsg> SMPHandler::sendWithReply(const SMPPDUMsg & msg IRQ_PRINT("SMPHandler::sendWithReply: nullptr result (timeout %d): req %s to %s", timeout, msg.toString().c_str(), deviceString.c_str()); has_ioerror = true; disconnect(true /* disconnectDevice */, true /* ioErrorCause */); - throw BTException("SMPHandler::sendWithReply: nullptr result (timeout "+std::to_string(timeout)+"): req "+msg.toString()+" to "+deviceString, E_FILE_LINE); + throw BTException("SMPHandler::sendWithReply: nullptr result (timeout "+timeout.to_string()+"): req "+msg.toString()+" to "+deviceString, E_FILE_LINE); } return res; } |