diff options
-rw-r--r-- | api/direct_bt/DBTAdapter.hpp | 128 | ||||
-rw-r--r-- | api/direct_bt/DBTDevice.hpp | 8 | ||||
-rw-r--r-- | examples/CMakeLists.txt | 8 | ||||
-rw-r--r-- | examples/direct_bt_scanner00/dbt_scanner00.cpp | 12 | ||||
-rw-r--r-- | examples/direct_bt_scanner01/dbt_scanner01.cpp | 12 | ||||
-rw-r--r-- | examples/java/CMakeLists.txt | 7 | ||||
-rw-r--r-- | java/jni/direct_bt/DBTAdapter.cxx | 4 | ||||
-rw-r--r-- | src/direct_bt/DBTAdapter.cpp | 135 | ||||
-rw-r--r-- | src/direct_bt/DBTDevice.cpp | 75 | ||||
-rw-r--r-- | src/direct_bt/DBTManager.cpp | 2 | ||||
-rw-r--r-- | src/direct_bt/HCIComm.cpp | 26 |
11 files changed, 146 insertions, 271 deletions
diff --git a/api/direct_bt/DBTAdapter.hpp b/api/direct_bt/DBTAdapter.hpp index 5b787a7d..ec66a74a 100644 --- a/api/direct_bt/DBTAdapter.hpp +++ b/api/direct_bt/DBTAdapter.hpp @@ -47,98 +47,6 @@ namespace direct_bt { class DBTAdapter; // forward /** - * A HCI session, using an underlying {@link HCIComm} instance, - * tracking all open connections. - * <p> - * At destruction, all remaining connections will be closed. - * </p> - */ - class HCISession - { - friend class DBTAdapter; // top manager: adapter open/close - friend class DBTDevice; // local device manager: device connect/disconnect - - private: - static std::atomic_int name_counter; - DBTAdapter * adapter; - HCIComm hciComm; - std::vector<std::shared_ptr<DBTDevice>> connectedDevices; - std::recursive_mutex mtx_connectedDevices; - - /** Opens a new HCI session on the given BT dev_id and HCI channel. */ - HCISession(DBTAdapter &a, const uint16_t channel, const int timeoutMS=HCI_TO_SEND_REQ_POLL_MS); - - /** - * Add the new {@link DBTDevice} to the list of connected devices. - * <p> - * Throws an InternalError if the given device was already added to the list of connected devices. - * Comparison is done by DBTDevice equality of address. - * This ensures runtime consistency regarding overall DBTDevice reference tracking. - * </p> - */ - void connected(const std::shared_ptr<DBTDevice> & device); - - /** - * Remove the {@link DBTDevice} from the list of connected devices. - */ - void disconnected(const DBTDevice & device); - - /** - * Issues {@link #disconnectAllDevices()} and closes the underlying HCI session. - * <p> - * This shutdown hook is solely intended for adapter's destructor. - * </p> - */ - void shutdown(); - - public: - const int name; - - /** - * Releases this instance after {@link #close()}. - */ - ~HCISession(); - - /** Return connected {@link DBTDevice}s. */ - std::vector<std::shared_ptr<DBTDevice>> getConnectedDevices() { return connectedDevices; } - - /** Disconnect all connected devices. Returns number of removed discovered devices. */ - int disconnectAllDevices(const uint8_t reason=0); - - /** Returns connected DBTDevice if found, otherwise nullptr */ - std::shared_ptr<DBTDevice> findConnectedDevice (EUI48 const & mac) const; - - /** - * Closes this instance by {@link #disconnectAllLEDevices()} - * and closing the underlying HCI session. - */ - bool close(); - - bool isOpen() const { return hciComm.isOpen(); } - - /** Return this HCI device descriptor, for multithreading access use {@link #dd()}. */ - int dd() const { return hciComm.dd(); } - /** Return the recursive mutex for multithreading access of {@link #mutex()}. */ - std::recursive_mutex & mutex() { return hciComm.mutex(); } - - std::string toString() const; - }; - - inline bool operator<(const HCISession& lhs, const HCISession& rhs) - { return lhs.name < rhs.name; } - - inline bool operator==(const HCISession& lhs, const HCISession& rhs) - { return lhs.name == rhs.name; } - - inline bool operator!=(const HCISession& lhs, const HCISession& rhs) - { return !(lhs == rhs); } - - - // ************************************************* - // ************************************************* - // ************************************************* - - /** * {@link DBTAdapter} status listener for {@link DBTDevice} discovery events: Added, updated and removed; * as well as for certain {@link DBTAdapter} events. * <p> @@ -207,24 +115,37 @@ namespace direct_bt { std::shared_ptr<AdapterInfo> adapterInfo; NameAndShortName localName; ScanType currentScanType = ScanType::SCAN_TYPE_NONE; - volatile bool keepDiscoveringAlive = false; - std::shared_ptr<HCISession> session; + std::shared_ptr<HCIComm> hciComm; + std::vector<std::shared_ptr<DBTDevice>> connectedDevices; + std::recursive_mutex mtx_connectedDevices; + std::vector<std::shared_ptr<DBTDevice>> discoveredDevices; // all discovered devices std::vector<std::shared_ptr<DBTDevice>> sharedDevices; // all active shared devices std::vector<std::shared_ptr<AdapterStatusListener>> statusListenerList; std::recursive_mutex mtx_discoveredDevices; std::recursive_mutex mtx_sharedDevices; std::recursive_mutex mtx_statusListenerList; + volatile bool keepDiscoveringAlive = false; bool validateDevInfo(); - friend bool HCISession::close(); - void sessionClosing(); - friend std::shared_ptr<DBTDevice> DBTDevice::getSharedInstance() const; friend void DBTDevice::releaseSharedInstance() const; friend std::shared_ptr<ConnectionInfo> DBTDevice::getConnectionInfo(); + friend void DBTDevice::disconnect(const uint8_t reason); + friend uint16_t DBTDevice::le_connectHCI(HCIAddressType peer_mac_type, HCIAddressType own_mac_type, + uint16_t interval, uint16_t window, + uint16_t min_interval, uint16_t max_interval, + uint16_t latency, uint16_t supervision_timeout, + uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t initiator_filter ); + friend uint16_t DBTDevice::connectHCI(const uint16_t pkt_type, const uint16_t clock_offset, const uint8_t role_switch); + + void addConnectedDevice(const std::shared_ptr<DBTDevice> & device); + void removeConnectedDevice(const DBTDevice & device); + int disconnectAllDevices(const uint8_t reason=0); + std::shared_ptr<DBTDevice> findConnectedDevice (EUI48 const & mac) const; bool addDiscoveredDevice(std::shared_ptr<DBTDevice> const &device); @@ -328,15 +249,20 @@ namespace direct_bt { DBTManager& getManager() const { return mgmt; } /** - * Returns a reference to the newly opened HCI session + * Returns a reference to the newly opened HCIComm instance * if successful, otherwise nullptr is returned. */ - std::shared_ptr<HCISession> open(); + std::shared_ptr<HCIComm> openHCI(); + + /** + * Returns the {@link #openHCI()} session or {@code nullptr} if closed. + */ + std::shared_ptr<HCIComm> getOpenHCIComm() const { return hciComm; } /** - * Returns the {@link #open()} session or {@code nullptr} if closed. + * Closes the HCIComm instance */ - std::shared_ptr<HCISession> getOpenSession() const { return session; } + bool closeHCI(); // device discovery aka device scanning diff --git a/api/direct_bt/DBTDevice.hpp b/api/direct_bt/DBTDevice.hpp index aaea86da..9edf1c6d 100644 --- a/api/direct_bt/DBTDevice.hpp +++ b/api/direct_bt/DBTDevice.hpp @@ -74,6 +74,9 @@ namespace direct_bt { EIRDataType update(EInfoReport const & data); + /** Returns the shared pointer of this instance managed by the adapter. */ + std::shared_ptr<DBTDevice> getSharedInstance() const; + void releaseSharedInstance() const; public: @@ -94,11 +97,8 @@ namespace direct_bt { return std::string(JAVA_DBT_PACKAGE "DBTDevice"); } - /** Returns the shared pointer of this instance managed by the adapter. */ - std::shared_ptr<DBTDevice> getSharedInstance() const; - /** Returns the managing adapter */ - DBTAdapter const & getAdapter() const { return adapter; } + DBTAdapter & getAdapter() const { return adapter; } uint64_t getCreationTimestamp() const { return ts_creation; } uint64_t getUpdateTimestamp() const { return ts_update; } diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 836eed73..6cadf26f 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -54,6 +54,11 @@ set_target_properties(list_mfg PROPERTIES CXX_STANDARD 11) +add_executable (dbt_scanner10 direct_bt_scanner10/dbt_scanner10.cpp) +set_target_properties(list_mfg + PROPERTIES + CXX_STANDARD 11) + target_link_libraries (hellotinyb tinyb) target_link_libraries (checkinit tinyb) target_link_libraries (asynctinyb tinyb) @@ -63,6 +68,7 @@ target_link_libraries (uuid tinyb) target_link_libraries (list_mfg tinyb) target_link_libraries (dbt_scanner00 direct_bt) target_link_libraries (dbt_scanner01 direct_bt) +target_link_libraries (dbt_scanner10 direct_bt) -install(TARGETS dbt_scanner00 dbt_scanner01 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS dbt_scanner00 dbt_scanner01 dbt_scanner10 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/examples/direct_bt_scanner00/dbt_scanner00.cpp b/examples/direct_bt_scanner00/dbt_scanner00.cpp index 5ddef516..ba7ba732 100644 --- a/examples/direct_bt_scanner00/dbt_scanner00.cpp +++ b/examples/direct_bt_scanner00/dbt_scanner00.cpp @@ -185,9 +185,13 @@ int main(int argc, char *argv[]) const int64_t t0 = getCurrentMilliseconds(); - std::shared_ptr<HCISession> session = adapter.open(); + std::shared_ptr<HCIComm> hci = adapter.openHCI(); + if( nullptr == hci || !hci->isOpen() ) { + fprintf(stderr, "Couldn't open HCI from %s\n", adapter.toString().c_str()); + exit(1); + } - while( ok && ( forever || !foundDevice ) && nullptr != session ) { + while( ok && ( forever || !foundDevice ) ) { ok = adapter.startDiscovery(); if( !ok) { perror("Adapter start discovery failed"); @@ -261,9 +265,7 @@ int main(int argc, char *argv[]) } out: - if( nullptr != session ) { - session->close(); - } + adapter.closeHCI(); return 0; } diff --git a/examples/direct_bt_scanner01/dbt_scanner01.cpp b/examples/direct_bt_scanner01/dbt_scanner01.cpp index 5a6c79fe..9844ee30 100644 --- a/examples/direct_bt_scanner01/dbt_scanner01.cpp +++ b/examples/direct_bt_scanner01/dbt_scanner01.cpp @@ -183,9 +183,13 @@ int main(int argc, char *argv[]) const int64_t t0 = getCurrentMilliseconds(); - std::shared_ptr<HCISession> session = adapter.open(); + std::shared_ptr<HCIComm> hci = adapter.openHCI(); + if( nullptr == hci || !hci->isOpen() ) { + fprintf(stderr, "Couldn't open HCI from %s\n", adapter.toString().c_str()); + exit(1); + } - while( ok && ( forever || !foundDevice ) && nullptr != session ) { + while( ok && ( forever || !foundDevice ) ) { ok = adapter.startDiscovery(); if( !ok) { perror("Adapter start discovery failed"); @@ -322,9 +326,7 @@ int main(int argc, char *argv[]) #endif /* SHOW_STATIC_SERVICE_CHARACTERISTIC_COMPOSITION */ out: - if( nullptr != session ) { - session->close(); - } + adapter.closeHCI(); return 0; } diff --git a/examples/java/CMakeLists.txt b/examples/java/CMakeLists.txt index d8945755..17f3045e 100644 --- a/examples/java/CMakeLists.txt +++ b/examples/java/CMakeLists.txt @@ -35,3 +35,10 @@ add_custom_command(TARGET ScannerTinyB01 POST_BUILD COMMAND cp "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/ScannerTinyB01.dir/ScannerTinyB01.class" "${CMAKE_CURRENT_BINARY_DIR}" ) + +add_jar(ScannerTinyB10 SOURCES ScannerTinyB10.java INCLUDE_JARS "${CMAKE_CURRENT_BINARY_DIR}/../../java/tinyb2.jar" ENTRY_POINT Notification) + +add_custom_command(TARGET ScannerTinyB10 + POST_BUILD + COMMAND cp "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/ScannerTinyB10.dir/ScannerTinyB10.class" "${CMAKE_CURRENT_BINARY_DIR}" +) diff --git a/java/jni/direct_bt/DBTAdapter.cxx b/java/jni/direct_bt/DBTAdapter.cxx index 168a407e..360084b1 100644 --- a/java/jni/direct_bt/DBTAdapter.cxx +++ b/java/jni/direct_bt/DBTAdapter.cxx @@ -396,8 +396,8 @@ jboolean Java_direct_1bt_tinyb_DBTAdapter_openImpl(JNIEnv *env, jobject obj) { try { DBTAdapter *adapter = getInstance<DBTAdapter>(env, obj); DBG_PRINT("Java_direct_1bt_tinyb_DBTAdapter_deleteImpl %s", adapter->toString().c_str()); - std::shared_ptr<direct_bt::HCISession> session = adapter->open(); - if( nullptr == session ) { + std::shared_ptr<direct_bt::HCIComm> hciSession = adapter->openHCI(); + if( nullptr == hciSession ) { throw BluetoothException("Couldn't open adapter "+adapter->toString(), E_FILE_LINE); } return JNI_TRUE; diff --git a/src/direct_bt/DBTAdapter.cpp b/src/direct_bt/DBTAdapter.cpp index 98a002cd..ec6775ee 100644 --- a/src/direct_bt/DBTAdapter.cpp +++ b/src/direct_bt/DBTAdapter.cpp @@ -32,7 +32,7 @@ #include <algorithm> -#define VERBOSE_ON 1 +// #define VERBOSE_ON 1 #include <dbt_debug.hpp> #include "BasicAlgos.hpp" @@ -51,53 +51,42 @@ extern "C" { using namespace direct_bt; -// ************************************************* -// ************************************************* -// ************************************************* - -std::atomic_int HCISession::name_counter(0); - -HCISession::HCISession(DBTAdapter &a, const uint16_t channel, const int timeoutMS) -: adapter(&a), hciComm(a.dev_id, channel, timeoutMS), - name(name_counter.fetch_add(1)) -{} - -void HCISession::connected(const std::shared_ptr<DBTDevice> & device) { +void DBTAdapter::addConnectedDevice(const std::shared_ptr<DBTDevice> & device) { const std::lock_guard<std::recursive_mutex> lock(mtx_connectedDevices); // RAII-style acquire and relinquish via destructor for (auto it = connectedDevices.begin(); it != connectedDevices.end(); ++it) { if ( *device == **it ) { - throw InternalError("Device already connected: "+device->toString(), E_FILE_LINE); + ERR_PRINT("DBTAdapter::addConnectedDevice: Device already connected: %s", device->toString().c_str()); + return; } } connectedDevices.push_back(device); - DBG_PRINT("HCISession::connected: Device connected: %s", device->toString().c_str()); + DBG_PRINT("DBTAdapter::addConnectedDevice: Device connected: %s", device->toString().c_str()); } -void HCISession::disconnected(const DBTDevice & device) { +void DBTAdapter::removeConnectedDevice(const DBTDevice & device) { const std::lock_guard<std::recursive_mutex> lock(mtx_connectedDevices); // RAII-style acquire and relinquish via destructor for (auto it = connectedDevices.begin(); it != connectedDevices.end(); ) { if ( &device == (*it).get() ) { // compare actual device address it = connectedDevices.erase(it); - DBG_PRINT("HCISession::disconnected: Device disconnected: %s", device.toString().c_str()); + DBG_PRINT("DBTAdapter::removeConnectedDevice: Device disconnected: %s", device.toString().c_str()); return; } else { ++it; } } - DBG_PRINT("HCISession::disconnected: Device not connected: %s", device.toString().c_str()); + DBG_PRINT("DBTAdapter::removeConnectedDevice: Device not connected: %s", device.toString().c_str()); } -int HCISession::disconnectAllDevices(const uint8_t reason) { - int count = 0; +int DBTAdapter::disconnectAllDevices(const uint8_t reason) { std::vector<std::shared_ptr<DBTDevice>> devices(connectedDevices); // copy! + const int count = devices.size(); for (auto it = devices.begin(); it != devices.end(); ++it) { - (*it)->disconnect(reason); // will erase device from list via disconnected above - ++count; + (*it)->disconnect(reason); // will erase device from list via removeConnectedDevice(..) above } return count; } -std::shared_ptr<DBTDevice> HCISession::findConnectedDevice (EUI48 const & mac) const { +std::shared_ptr<DBTDevice> DBTAdapter::findConnectedDevice (EUI48 const & mac) const { std::vector<std::shared_ptr<DBTDevice>> devices(connectedDevices); // copy! for (auto it = devices.begin(); it != devices.end(); ) { if ( mac == (*it)->getAddress() ) { @@ -109,52 +98,6 @@ std::shared_ptr<DBTDevice> HCISession::findConnectedDevice (EUI48 const & mac) c return nullptr; } -bool HCISession::close() -{ - DBG_PRINT("HCISession::close: ..."); - if( nullptr == adapter ) { - throw InternalError("HCISession::close(): Adapter reference is null: "+toString(), E_FILE_LINE); - } - if( !hciComm.isOpen() ) { - DBG_PRINT("HCISession::close: Not open"); - return false; - } - disconnectAllDevices(); - adapter->sessionClosing(); - hciComm.close(); - DBG_PRINT("HCISession::close: XXX"); - return true; -} - -void HCISession::shutdown() { - DBG_PRINT("HCISession::shutdown(has-adapter %d): ...", nullptr!=adapter); - - // close() - if( !hciComm.isOpen() ) { - DBG_PRINT("HCISession::shutdown: Not open"); - } else { - disconnectAllDevices(); - hciComm.close(); - } - - DBG_PRINT("HCISession::shutdown(has-adapter %d): XXX", nullptr!=adapter); - adapter=nullptr; -} - -HCISession::~HCISession() { - DBG_PRINT("HCISession::dtor ..."); - if( nullptr != adapter ) { - close(); - adapter = nullptr; - } - DBG_PRINT("HCISession::dtor XXX"); -} - -std::string HCISession::toString() const { - return "HCISession[name "+std::to_string(name)+ - ", open "+std::to_string(isOpen())+ - ", "+std::to_string(this->connectedDevices.size())+" connected LE devices]"; -} // ************************************************* // ************************************************* @@ -176,16 +119,6 @@ bool DBTAdapter::validateDevInfo() { return true; } -void DBTAdapter::sessionClosing() -{ - DBG_PRINT("DBTAdapter::sessionClosing(own-session %d): ...", nullptr!=session); - if( nullptr != session ) { - // FIXME: stopDiscovery(); - session = nullptr; - } - DBG_PRINT("DBTAdapter::sessionClosing(own-session %d): XXX", nullptr!=session); -} - DBTAdapter::DBTAdapter() : mgmt(DBTManager::get(BTMode::BT_MODE_LE)), dev_id(nullptr != mgmt.getDefaultAdapterInfo() ? 0 : -1) { @@ -215,11 +148,9 @@ DBTAdapter::~DBTAdapter() { } statusListenerList.clear(); - if( nullptr != session ) { - stopDiscovery(); - session->shutdown(); // force shutdown, not only via dtor as adapter EOL has been reached! - session = nullptr; - } + stopDiscovery(); + disconnectAllDevices(); + closeHCI(); removeDiscoveredDevices(); sharedDevices.clear(); @@ -242,19 +173,33 @@ void DBTAdapter::setBondable(bool value) { mgmt.setMode(dev_id, MgmtOpcode::SET_BONDABLE, value ? 1 : 0); } -std::shared_ptr<HCISession> DBTAdapter::open() +std::shared_ptr<HCIComm> DBTAdapter::openHCI() { if( !valid ) { return nullptr; } - HCISession * s = new HCISession( *this, HCI_CHANNEL_RAW, HCIDefaults::HCI_TO_SEND_REQ_POLL_MS); + HCIComm *s = new HCIComm(dev_id, HCI_CHANNEL_RAW, HCIDefaults::HCI_TO_SEND_REQ_POLL_MS); if( !s->isOpen() ) { delete s; - ERR_PRINT("Could not open device"); + ERR_PRINT("Could not open HCIComm"); return nullptr; } - session = std::shared_ptr<HCISession>( s ); - return session; + hciComm = std::shared_ptr<HCIComm>( s ); + return hciComm; +} + +bool DBTAdapter::closeHCI() +{ + DBG_PRINT("DBTAdapter::closeHCI: ..."); + if( nullptr == hciComm || !hciComm->isOpen() ) { + DBG_PRINT("DBTAdapter::closeHCI: Not open"); + return false; + } + disconnectAllDevices(); // FIXME ???? + hciComm->close(); + hciComm = nullptr; + DBG_PRINT("DBTAdapter::closeHCI: XXX"); + return true; } bool DBTAdapter::addStatusListener(std::shared_ptr<AdapterStatusListener> l) { @@ -507,9 +452,6 @@ void DBTAdapter::sendDeviceUpdated(std::shared_ptr<DBTDevice> device, uint64_t t bool DBTAdapter::mgmtEvDeviceConnectedCB(std::shared_ptr<MgmtEvent> e) { const MgmtEvtDeviceConnected &event = *static_cast<const MgmtEvtDeviceConnected *>(e.get()); - if( nullptr == session ) { - throw InternalError("NULL session @ receiving "+event.toString(), E_FILE_LINE); - } EInfoReport ad_report; { ad_report.setSource(EInfoReport::Source::EIR); @@ -519,7 +461,7 @@ bool DBTAdapter::mgmtEvDeviceConnectedCB(std::shared_ptr<MgmtEvent> e) { ad_report.read_data(event.getData(), event.getDataSize()); } int new_connect = 0; - std::shared_ptr<DBTDevice> device = session->findConnectedDevice(event.getAddress()); + std::shared_ptr<DBTDevice> device = findConnectedDevice(event.getAddress()); if( nullptr == device ) { device = findDiscoveredDevice(event.getAddress()); new_connect = nullptr != device ? 1 : 0; @@ -536,7 +478,7 @@ bool DBTAdapter::mgmtEvDeviceConnectedCB(std::shared_ptr<MgmtEvent> e) { DBG_PRINT("DBTAdapter::EventCB:DeviceConnected(dev_id %d, new_connect %d, updated %s): %s,\n %s\n -> %s", dev_id, new_connect, eirDataMaskToString(updateMask).c_str(), event.toString().c_str(), ad_report.toString().c_str(), device->toString().c_str()); if( 0 < new_connect ) { - session->connected(device); // track it + addConnectedDevice(device); // track it } for_each_idx_mtx(mtx_statusListenerList, statusListenerList, [&](std::shared_ptr<AdapterStatusListener> &l) { if( l->matchDevice(*device) ) { @@ -554,10 +496,7 @@ bool DBTAdapter::mgmtEvDeviceConnectedCB(std::shared_ptr<MgmtEvent> e) { } bool DBTAdapter::mgmtEvDeviceDisconnectedCB(std::shared_ptr<MgmtEvent> e) { const MgmtEvtDeviceDisconnected &event = *static_cast<const MgmtEvtDeviceDisconnected *>(e.get()); - if( nullptr == session ) { - throw InternalError("NULL session @ receiving "+event.toString(), E_FILE_LINE); - } - std::shared_ptr<DBTDevice> device = session->findConnectedDevice(event.getAddress()); + std::shared_ptr<DBTDevice> device = findConnectedDevice(event.getAddress()); if( nullptr != device ) { DBG_PRINT("DBTAdapter::EventCB:DeviceDisconnected(dev_id %d): %s\n -> %s", dev_id, event.toString().c_str(), device->toString().c_str()); diff --git a/src/direct_bt/DBTDevice.cpp b/src/direct_bt/DBTDevice.cpp index 2dde9f3b..75ac8f09 100644 --- a/src/direct_bt/DBTDevice.cpp +++ b/src/direct_bt/DBTDevice.cpp @@ -32,7 +32,7 @@ #include <algorithm> -#define VERBOSE_ON 1 +// #define VERBOSE_ON 1 #include <dbt_debug.hpp> #include "HCIComm.hpp" @@ -208,20 +208,19 @@ uint16_t DBTDevice::le_connectHCI(HCIAddressType peer_mac_type, HCIAddressType o uint16_t min_ce_length, uint16_t max_ce_length, uint8_t initiator_filter ) { + if( 0 < hciConnHandle ) { + ERR_PRINT("DBTDevice::le_connect: Already connected"); + return 0; + } std::shared_ptr<DBTDevice> sharedInstance = getSharedInstance(); if( nullptr == sharedInstance ) { - ERR_PRINT("DBTDevice::le_connect: Device unknown to adapter and not tracked: %s", toString().c_str()); - return 0; + throw InternalError("DBTDevice::connectGATT: Device unknown to adapter and not tracked: "+toString(), E_FILE_LINE); } - std::shared_ptr<HCISession> session = adapter.getOpenSession(); - if( nullptr == session || !session->isOpen() ) { + std::shared_ptr<HCIComm> hciComm = adapter.getOpenHCIComm(); + if( nullptr == hciComm || !hciComm->isOpen() ) { ERR_PRINT("DBTDevice::le_connect: Adapter session not opened"); return 0; } - if( 0 < hciConnHandle ) { - ERR_PRINT("DBTDevice::le_connect: Already connected"); - return 0; - } if( !isLEAddressType() ) { ERR_PRINT("DBTDevice::le_connect: Not a BDADDR_LE_PUBLIC or BDADDR_LE_RANDOM address: %s", toString().c_str()); return 0; @@ -233,7 +232,7 @@ uint16_t DBTDevice::le_connectHCI(HCIAddressType peer_mac_type, HCIAddressType o mngr.create_connection(adapter.dev_id, address, addressType); } - hciConnHandle = session->hciComm.le_create_conn( + hciConnHandle = hciComm->le_create_conn( address, peer_mac_type, own_mac_type, interval, window, min_interval, max_interval, latency, supervision_timeout, min_ce_length, max_ce_length, initiator_filter); @@ -242,25 +241,24 @@ uint16_t DBTDevice::le_connectHCI(HCIAddressType peer_mac_type, HCIAddressType o ERR_PRINT("DBTDevice::le_connect: Could not create connection"); return 0; } - session->connected(sharedInstance); + adapter.addConnectedDevice(sharedInstance); return hciConnHandle; } uint16_t DBTDevice::connectHCI(const uint16_t pkt_type, const uint16_t clock_offset, const uint8_t role_switch) { - std::shared_ptr<DBTDevice> sharedInstance = getSharedInstance(); - if( nullptr == sharedInstance ) { - ERR_PRINT("DBTDevice::connect: Device unknown to adapter and not tracked: %s", toString().c_str()); + if( 0 < hciConnHandle ) { + ERR_PRINT("DBTDevice::connect: Already connected"); return 0; } - std::shared_ptr<HCISession> session = adapter.getOpenSession(); - if( nullptr == session || !session->isOpen() ) { - ERR_PRINT("DBTDevice::connect: Adapter session Not opened"); - return 0; + std::shared_ptr<DBTDevice> sharedInstance = getSharedInstance(); + if( nullptr == sharedInstance ) { + throw InternalError("DBTDevice::connectGATT: Device unknown to adapter and not tracked: "+toString(), E_FILE_LINE); } - if( 0 < hciConnHandle ) { - ERR_PRINT("DBTDevice::connect: Already connected"); + std::shared_ptr<HCIComm> hciComm = adapter.getOpenHCIComm(); + if( nullptr == hciComm || !hciComm->isOpen() ) { + ERR_PRINT("DBTDevice::le_connect: Adapter session not opened"); return 0; } if( !isBREDRAddressType() ) { @@ -274,13 +272,13 @@ uint16_t DBTDevice::connectHCI(const uint16_t pkt_type, const uint16_t clock_off mngr.create_connection(adapter.dev_id, address, addressType); } - hciConnHandle = session->hciComm.create_conn(address, pkt_type, clock_offset, role_switch); + hciConnHandle = hciComm->create_conn(address, pkt_type, clock_offset, role_switch); if ( 0 == hciConnHandle ) { ERR_PRINT("DBTDevice::connect: Could not create connection (yet)"); return 0; } - session->connected(sharedInstance); + adapter.addConnectedDevice(sharedInstance); return hciConnHandle; } @@ -303,14 +301,14 @@ uint16_t DBTDevice::connectHCIDefault() void DBTDevice::disconnect(const uint8_t reason) { disconnectGATT(); - std::shared_ptr<HCISession> session = adapter.getOpenSession(); + std::shared_ptr<HCIComm> hciComm = adapter.getOpenHCIComm(); if( 0 == hciConnHandle ) { DBG_PRINT("DBTDevice::disconnect: Not connected"); goto errout; } - if( nullptr == session || !session->isOpen() ) { + if( nullptr == hciComm || !hciComm->isOpen() ) { DBG_PRINT("DBTDevice::disconnect: Session not opened"); goto errout; } @@ -318,7 +316,7 @@ void DBTDevice::disconnect(const uint8_t reason) { { const uint16_t _connHandle = hciConnHandle; hciConnHandle = 0; - if( !session->hciComm.disconnect(_connHandle, reason) ) { + if( !hciComm->disconnect(_connHandle, reason) ) { DBG_PRINT("DBTDevice::disconnect: handle 0x%X, errno %d %s", _connHandle, errno, strerror(errno)); } } @@ -328,13 +326,9 @@ void DBTDevice::disconnect(const uint8_t reason) { DBTManager & mngr = adapter.getManager(); mngr.disconnect(adapter.dev_id, address, addressType, reason); } - session->disconnected(*this); - return; errout: - if( nullptr != session ) { - session->disconnected(*this); - } + adapter.removeConnectedDevice(*this); } void DBTDevice::remove() { @@ -347,15 +341,6 @@ std::shared_ptr<GATTHandler> DBTDevice::connectGATT(int timeoutMS) { if( nullptr == sharedInstance ) { throw InternalError("DBTDevice::connectGATT: Device unknown to adapter and not tracked: "+toString(), E_FILE_LINE); } - std::shared_ptr<HCISession> session = adapter.getOpenSession(); - if( nullptr == session || !session->isOpen() ) { - DBG_PRINT("DBTDevice::connectGATT: Adapter session not opened"); - return nullptr; - } - if( 0 == hciConnHandle ) { - DBG_PRINT("DBTDevice::connectGATT: Device not connected"); - return nullptr; - } const std::lock_guard<std::recursive_mutex> lock(mtx_gatt); // RAII-style acquire and relinquish via destructor if( nullptr != gattHandler ) { @@ -383,18 +368,6 @@ std::vector<std::shared_ptr<GATTService>> DBTDevice::getServices() { ERR_PRINT("DBTDevice::getServices: Device unknown to adapter and not tracked: %s", toString().c_str()); return std::vector<std::shared_ptr<GATTService>>(); } - std::shared_ptr<HCISession> session = adapter.getOpenSession(); - if( nullptr == session || !session->isOpen() ) { - DBG_PRINT("DBTDevice::getServices: Adapter session not opened"); - return std::vector<std::shared_ptr<GATTService>>(); - } - if( 0 == hciConnHandle ) { - connectHCIDefault(); - if( 0 == hciConnHandle ) { - ERR_PRINT("DBTDevice::getServices: defaultConnect failed"); - return std::vector<std::shared_ptr<GATTService>>(); - } - } if( nullptr == gattHandler ) { connectGATT(); if( nullptr == gattHandler ) { diff --git a/src/direct_bt/DBTManager.cpp b/src/direct_bt/DBTManager.cpp index 72c3a522..4bf9cd03 100644 --- a/src/direct_bt/DBTManager.cpp +++ b/src/direct_bt/DBTManager.cpp @@ -32,7 +32,7 @@ #include <algorithm> -#define PERF_PRINT_ON 1 +// #define PERF_PRINT_ON 1 // #define VERBOSE_ON 1 #include <dbt_debug.hpp> diff --git a/src/direct_bt/HCIComm.cpp b/src/direct_bt/HCIComm.cpp index bbbc8b7d..4945e4d8 100644 --- a/src/direct_bt/HCIComm.cpp +++ b/src/direct_bt/HCIComm.cpp @@ -32,7 +32,7 @@ #include <algorithm> -// #define VERBOSE_ON 1 +#define VERBOSE_ON 1 #include <dbt_debug.hpp> #include "HCIComm.hpp" @@ -121,7 +121,17 @@ int HCIComm::read(uint8_t* buffer, const int capacity, const int timeoutMS) { int n; p.fd = _dd; p.events = POLLIN; +#if 0 + sigset_t sigmask; + sigemptyset(&sigmask); + // sigaddset(&sigmask, SIGINT); + struct timespec timeout_ts; + timeout_ts.tv_sec=0; + timeout_ts.tv_nsec=(long)timeoutMS*1000000L; + while ((n = ppoll(&p, 1, &timeout_ts, &sigmask)) < 0) { +#else while ((n = poll(&p, 1, timeoutMS)) < 0) { +#endif if (errno == EAGAIN || errno == EINTR ) { // cont temp unavail or interruption continue; @@ -270,8 +280,18 @@ bool HCIComm::send_req(const uint16_t opcode, const void *command, const uint8_t struct pollfd p; int n; - p.fd = _dd; p.events = POLLIN; - while ((n = poll(&p, 1, _timeoutMS)) < 0) { + p.fd = _dd; p.events = POLLIN; +#if 0 + sigset_t sigmask; + sigemptyset(&sigmask); + sigaddset(&sigmask, SIGINT); + struct timespec timeout_ts; + timeout_ts.tv_sec=0; + timeout_ts.tv_nsec=(long)_timeoutMS*1000000L; + while ((n = ppoll(&p, 1, &timeout_ts, &sigmask)) < 0) { +#else + while ((n = poll(&p, 1, _timeoutMS)) < 0) { +#endif ERR_PRINT("hci_send_req: poll"); if (errno == EAGAIN || errno == EINTR) { continue; |