diff options
author | Sven Gothel <[email protected]> | 2020-05-24 01:57:40 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2020-05-24 01:57:40 +0200 |
commit | c760eac8addfda8e63ae213827840d251ecadfa0 (patch) | |
tree | be881d530020295d1e903b62a4388f6ba05d1361 | |
parent | faffa313cc31c184e861d7bee5f932013e2d9d00 (diff) |
Add Whitelist to DBTManager/DBTAdapter and test (Result: No auto-connection)
To avoid the hassle with HCI connect/disconnect while scanning,
we should test the whitelist supposed to be stored on the adapter to auto-connect.
Initial testing didn't show any connection.
-rw-r--r-- | api/direct_bt/DBTAdapter.hpp | 8 | ||||
-rw-r--r-- | api/direct_bt/DBTManager.hpp | 5 | ||||
-rw-r--r-- | api/direct_bt/MgmtTypes.hpp | 34 | ||||
-rw-r--r-- | examples/direct_bt_scanner10/dbt_scanner10.cpp | 95 | ||||
-rw-r--r-- | java/direct_bt/tinyb/DBTAdapter.java | 7 | ||||
-rw-r--r-- | java/jni/direct_bt/DBTAdapter.cxx | 4 | ||||
-rw-r--r-- | src/direct_bt/DBTAdapter.cpp | 13 | ||||
-rw-r--r-- | src/direct_bt/DBTManager.cpp | 40 | ||||
-rw-r--r-- | src/direct_bt/MgmtTypes.cpp | 4 |
9 files changed, 166 insertions, 44 deletions
diff --git a/api/direct_bt/DBTAdapter.hpp b/api/direct_bt/DBTAdapter.hpp index 06c21de2..08614bfc 100644 --- a/api/direct_bt/DBTAdapter.hpp +++ b/api/direct_bt/DBTAdapter.hpp @@ -264,6 +264,12 @@ namespace direct_bt { */ bool closeHCI(); + /** Add the given device to the adapter's autoconnect whitelist. */ + bool addDeviceToWhitelist(const EUI48 &address, const BDAddressType address_type); + + /** Remove the given device from the adapter's autoconnect whitelist. */ + bool removeDeviceFromWhitelist(const EUI48 &address, const BDAddressType address_type); + // device discovery aka device scanning /** @@ -317,7 +323,7 @@ namespace direct_bt { * Also clears previous discovered devices via removeDiscoveredDevices(). * </p> */ - bool startDiscovery(HCIAddressType own_mac_type=HCIAddressType::HCIADDR_LE_PUBLIC, + bool startDiscovery(bool keepAlive=true, HCIAddressType own_mac_type=HCIAddressType::HCIADDR_LE_PUBLIC, uint16_t interval=0x0004, uint16_t window=0x0004); /** diff --git a/api/direct_bt/DBTManager.hpp b/api/direct_bt/DBTManager.hpp index 3900eeb6..6e36736e 100644 --- a/api/direct_bt/DBTManager.hpp +++ b/api/direct_bt/DBTManager.hpp @@ -233,6 +233,11 @@ namespace direct_bt { /** Stop discovery on given adapter dev_id. */ bool stopDiscovery(const int dev_id, const ScanType type); + /** Add the given device to the adapter's autoconnect whitelist. */ + bool addDeviceToWhitelist(const int dev_id, const EUI48 &address, const BDAddressType address_type); + /** Remove the given device from the adapter's autoconnect whitelist. */ + bool removeDeviceFromWhitelist(const int dev_id, const EUI48 &address, const BDAddressType address_type); + uint16_t create_connection(const int dev_id, const EUI48 &peer_bdaddr, const BDAddressType peer_mac_type, diff --git a/api/direct_bt/MgmtTypes.hpp b/api/direct_bt/MgmtTypes.hpp index d722b6a4..a5583a51 100644 --- a/api/direct_bt/MgmtTypes.hpp +++ b/api/direct_bt/MgmtTypes.hpp @@ -146,8 +146,8 @@ namespace direct_bt { LOAD_IRKS = 0x0030, GET_CONN_INFO = 0x0031, GET_CLOCK_INFO = 0x0032, - ADD_DEVICE = 0x0033, - REMOVE_DEVICE = 0x0034, + ADD_DEVICE_WHITELIST = 0x0033, + REMOVE_DEVICE_WHITELIST = 0x0034, LOAD_CONN_PARAM = 0x0035, READ_UNCONF_INDEX_LIST = 0x0036, READ_CONFIG_INFO = 0x0037, @@ -313,6 +313,36 @@ namespace direct_bt { }; /** + * mgmt_addr_info { EUI48, uint8_t type }, + * uint8_t action + */ + class MgmtAddDeviceToWhitelistCmd : public MgmtCommand + { + public: + MgmtAddDeviceToWhitelistCmd(const uint16_t dev_id, const EUI48 &address, const BDAddressType addressType, const uint8_t action) + : MgmtCommand(MgmtOpcode::ADD_DEVICE_WHITELIST, dev_id, 6+1+1) + { + pdu.put_eui48(MGMT_HEADER_SIZE, address); + pdu.put_uint8(MGMT_HEADER_SIZE+6, addressType); + pdu.put_uint8(MGMT_HEADER_SIZE+6+1, action); + } + }; + + /** + * mgmt_addr_info { EUI48, uint8_t type }, + */ + class MgmtRemoveDeviceFromWhitelistCmd : public MgmtCommand + { + public: + MgmtRemoveDeviceFromWhitelistCmd(const uint16_t dev_id, const EUI48 &address, const BDAddressType addressType) + : MgmtCommand(MgmtOpcode::REMOVE_DEVICE_WHITELIST, dev_id, 6+1) + { + pdu.put_eui48(MGMT_HEADER_SIZE, address); + pdu.put_uint8(MGMT_HEADER_SIZE+6, addressType); + } + }; + + /** * uint8_t name[MGMT_MAX_NAME_LENGTH]; * uint8_t short_name[MGMT_MAX_SHORT_NAME_LENGTH]; */ diff --git a/examples/direct_bt_scanner10/dbt_scanner10.cpp b/examples/direct_bt_scanner10/dbt_scanner10.cpp index 264654b4..e5457795 100644 --- a/examples/direct_bt_scanner10/dbt_scanner10.cpp +++ b/examples/direct_bt_scanner10/dbt_scanner10.cpp @@ -40,6 +40,10 @@ using namespace direct_bt; static int64_t timestamp_t0; +static bool USE_WHITELIST = false; + +static bool BLOCK_DISCOVERY = true; + static EUI48 waitForDevice = EUI48_ANY_DEVICE; static void deviceConnectTask(std::shared_ptr<DBTDevice> device); @@ -229,21 +233,24 @@ class MyGATTEventListener : public SpecificGATTCharacteristicListener { } }; -// #define BLOCK_DISCOVERY 1 - static void deviceConnectTask(std::shared_ptr<DBTDevice> device) { fprintf(stderr, "****** Device Connector: Start %s\n", device->toString().c_str()); device->getAdapter().stopDiscovery(); - bool res = device->connectHCIDefault(); + bool res = false; + if( !USE_WHITELIST ) { + res = device->connectHCIDefault(); + } fprintf(stderr, "****** Device Connector: End result %d of %s\n", res, device->toString().c_str()); -#ifndef BLOCK_DISCOVERY - device->getAdapter().startDiscovery(); -#else - if( !res && 0 == getDeviceTaskCount() ) { - fprintf(stderr, "****** Device Connector: startDiscovery()\n"); - device->getAdapter().startDiscovery(); + if( !USE_WHITELIST ) { + if( BLOCK_DISCOVERY ) { + if( !res && 0 == getDeviceTaskCount() ) { + fprintf(stderr, "****** Device Connector: startDiscovery()\n"); + device->getAdapter().startDiscovery(true); + } + } else { + device->getAdapter().startDiscovery(false); + } } -#endif } static void deviceProcessTask(std::shared_ptr<DBTDevice> device) { @@ -300,22 +307,22 @@ static void deviceProcessTask(std::shared_ptr<DBTDevice> device) { // FIXME sleep 1s for potential callbacks .. sleep(1); } -#ifdef BLOCK_DISCOVERY - device->disconnect(); -#else - device->getAdapter().stopDiscovery(); - device->disconnect(); - device->getAdapter().startDiscovery(); -#endif + if( BLOCK_DISCOVERY ) { + device->disconnect(); + } else { + device->getAdapter().stopDiscovery(); + device->disconnect(); + device->getAdapter().startDiscovery(false); + } out: addDevicesProcessed(device->getAddress()); -#ifdef BLOCK_DISCOVERY - if( 1 >= getDeviceTaskCount() ) { - fprintf(stderr, "****** Device Process: startDiscovery()\n"); - device->getAdapter().startDiscovery(); + if( !USE_WHITELIST && BLOCK_DISCOVERY ) { + if( 1 >= getDeviceTaskCount() ) { + fprintf(stderr, "****** Device Process: startDiscovery()\n"); + device->getAdapter().startDiscovery(true); + } } -#endif removeDeviceTask(device); fprintf(stderr, "****** Device Process: End\n"); } @@ -326,17 +333,29 @@ int main(int argc, char *argv[]) int dev_id = 0; // default bool waitForEnter=false; bool done = false; + std::vector<std::shared_ptr<EUI48>> whitelist; for(int i=1; i<argc; i++) { if( !strcmp("-wait", argv[i]) ) { waitForEnter = true; + } else if( !strcmp("-keepDiscovery", argv[i]) ) { + BLOCK_DISCOVERY = false; } else if( !strcmp("-dev_id", argv[i]) && argc > (i+1) ) { dev_id = atoi(argv[++i]); } else if( !strcmp("-mac", argv[i]) && argc > (i+1) ) { std::string macstr = std::string(argv[++i]); waitForDevice = EUI48(macstr); + } else if( !strcmp("-wl", argv[i]) && argc > (i+1) ) { + std::string macstr = std::string(argv[++i]); + std::shared_ptr<EUI48> wlmac( new EUI48(macstr) ); + fprintf(stderr, "Whitelist + %s\n", wlmac->toString().c_str()); + whitelist.push_back( wlmac ); + BLOCK_DISCOVERY = true; + USE_WHITELIST = true; } } + fprintf(stderr, "USE_WHITELIST %d\n", USE_WHITELIST); + fprintf(stderr, "BLOCK_DISCOVERY %d\n", BLOCK_DISCOVERY); fprintf(stderr, "dev_id %d\n", dev_id); fprintf(stderr, "waitForDevice: %s\n", waitForDevice.toString().c_str()); @@ -361,23 +380,37 @@ int main(int argc, char *argv[]) adapter.addStatusListener(std::shared_ptr<AdapterStatusListener>(new MyAdapterStatusListener())); - 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); + if( USE_WHITELIST ) { + for (auto it = whitelist.begin(); it != whitelist.end(); ++it) { + std::shared_ptr<EUI48> wlmac = *it; + bool res = adapter.addDeviceToWhitelist(*wlmac, BDAddressType::BDADDR_LE_PUBLIC); + fprintf(stderr, "Added to whitelist: res %d, address %s\n", res, wlmac->toString().c_str()); + } + } else { + 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); + } } - if( !adapter.startDiscovery() ) { - perror("Adapter start discovery failed"); - goto out; - } + // if( !USE_WHITELIST ) { + if( !adapter.startDiscovery(BLOCK_DISCOVERY) ) { + perror("Adapter start discovery failed"); + goto out; + } + // } do { if( waitForDevice != EUI48_ANY_DEVICE && isDeviceProcessed(waitForDevice) ) { fprintf(stderr, "****** WaitForDevice processed %s", waitForDevice.toString().c_str()); done = true; + } else { + if( !BLOCK_DISCOVERY && 0 >= getDeviceTaskCount() ) { + adapter.startDiscovery(false); + } } - sleep(3); + sleep(5); } while( !done ); out: diff --git a/java/direct_bt/tinyb/DBTAdapter.java b/java/direct_bt/tinyb/DBTAdapter.java index 9b60d27b..727503c7 100644 --- a/java/direct_bt/tinyb/DBTAdapter.java +++ b/java/direct_bt/tinyb/DBTAdapter.java @@ -240,12 +240,15 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter @Override public synchronized boolean startDiscovery() throws BluetoothException { + return startDiscovery(true); + } + public synchronized boolean startDiscovery(final boolean keepAlive) throws BluetoothException { removeDevices(); - final boolean res = startDiscoveryImpl(); + final boolean res = startDiscoveryImpl(keepAlive); isDiscovering = res; return res; } - private native boolean startDiscoveryImpl() throws BluetoothException; + private native boolean startDiscoveryImpl(boolean keepAlive) throws BluetoothException; @Override public synchronized boolean stopDiscovery() throws BluetoothException { diff --git a/java/jni/direct_bt/DBTAdapter.cxx b/java/jni/direct_bt/DBTAdapter.cxx index 1e32ade8..030e193b 100644 --- a/java/jni/direct_bt/DBTAdapter.cxx +++ b/java/jni/direct_bt/DBTAdapter.cxx @@ -403,11 +403,11 @@ void Java_direct_1bt_tinyb_DBTAdapter_deleteImpl(JNIEnv *env, jobject obj) } } -jboolean Java_direct_1bt_tinyb_DBTAdapter_startDiscoveryImpl(JNIEnv *env, jobject obj) +jboolean Java_direct_1bt_tinyb_DBTAdapter_startDiscoveryImpl(JNIEnv *env, jobject obj, jboolean keepAlive) { try { DBTAdapter *adapter = getInstance<DBTAdapter>(env, obj); - return adapter->startDiscovery(); + return adapter->startDiscovery(keepAlive); } catch(...) { rethrow_and_raise_java_exception(env); } diff --git a/src/direct_bt/DBTAdapter.cpp b/src/direct_bt/DBTAdapter.cpp index 0ff9a3b6..f92133bf 100644 --- a/src/direct_bt/DBTAdapter.cpp +++ b/src/direct_bt/DBTAdapter.cpp @@ -218,6 +218,14 @@ bool DBTAdapter::closeHCI() return true; } +bool DBTAdapter::addDeviceToWhitelist(const EUI48 &address, const BDAddressType address_type) { + return mgmt.addDeviceToWhitelist(dev_id, address, address_type); +} + +bool DBTAdapter::removeDeviceFromWhitelist(const EUI48 &address, const BDAddressType address_type) { + return mgmt.removeDeviceFromWhitelist(dev_id, address, address_type); +} + bool DBTAdapter::addStatusListener(std::shared_ptr<AdapterStatusListener> l) { if( nullptr == l ) { throw IllegalArgumentException("DBTAdapterStatusListener ref is null", E_FILE_LINE); @@ -273,15 +281,16 @@ int DBTAdapter::removeAllStatusListener() { return count; } -bool DBTAdapter::startDiscovery(HCIAddressType own_mac_type, +bool DBTAdapter::startDiscovery(bool keepAlive, HCIAddressType own_mac_type, uint16_t interval, uint16_t window) { (void)own_mac_type; (void)interval; (void)window; + DBG_PRINT("DBTAdapter::startDiscovery: keepAlive %d ...", keepAlive); removeDiscoveredDevices(); - keepDiscoveringAlive = true; + keepDiscoveringAlive = keepAlive; currentScanType = mgmt.startDiscovery(dev_id); return ScanType::SCAN_TYPE_NONE != currentScanType; } diff --git a/src/direct_bt/DBTManager.cpp b/src/direct_bt/DBTManager.cpp index 4bf9cd03..9bbd6b81 100644 --- a/src/direct_bt/DBTManager.cpp +++ b/src/direct_bt/DBTManager.cpp @@ -504,6 +504,42 @@ bool DBTManager::stopDiscovery(const int dev_id, const ScanType type) { } } +bool DBTManager::addDeviceToWhitelist(const int dev_id, const EUI48 &address, const BDAddressType address_type) { + MgmtAddDeviceToWhitelistCmd req(dev_id, address, address_type, 0x01); + DBG_PRINT("DBTManager::addDeviceToWhitelist: %s", req.toString().c_str()); + std::shared_ptr<MgmtEvent> res = sendWithReply(req); + if( nullptr == res ) { + DBG_PRINT("DBTManager::addDeviceToWhitelist res: NULL"); + return false; + } + DBG_PRINT("DBTManager::addDeviceToWhitelist res: %s", res->toString().c_str()); + if( res->getOpcode() == MgmtEvent::Opcode::CMD_COMPLETE ) { + const MgmtEvtCmdComplete &res1 = *static_cast<const MgmtEvtCmdComplete *>(res.get()); + if( MgmtStatus::SUCCESS == res1.getStatus() ) { + return true; + } + } + return false; +} + +bool DBTManager::removeDeviceFromWhitelist(const int dev_id, const EUI48 &address, const BDAddressType address_type) { + MgmtRemoveDeviceFromWhitelistCmd req(dev_id, address, address_type); + DBG_PRINT("DBTManager::removeDeviceFromWhitelist: %s", req.toString().c_str()); + std::shared_ptr<MgmtEvent> res = sendWithReply(req); + if( nullptr == res ) { + DBG_PRINT("DBTManager::removeDeviceFromWhitelist res: NULL"); + return false; + } + DBG_PRINT("DBTManager::removeDeviceFromWhitelist res: %s", res->toString().c_str()); + if( res->getOpcode() == MgmtEvent::Opcode::CMD_COMPLETE ) { + const MgmtEvtCmdComplete &res1 = *static_cast<const MgmtEvtCmdComplete *>(res.get()); + if( MgmtStatus::SUCCESS == res1.getStatus() ) { + return true; + } + } + return false; +} + uint16_t DBTManager::create_connection(const int dev_id, const EUI48 &peer_bdaddr, const BDAddressType peer_mac_type, @@ -709,13 +745,13 @@ bool DBTManager::mgmtEvNewConnectionParamCB(std::shared_ptr<MgmtEvent> e) { return true; } bool DBTManager::mgmtEvDeviceWhitelistAddedCB(std::shared_ptr<MgmtEvent> e) { - DBG_PRINT("DBTManager::EventCB:DeviceAdded: %s", e->toString().c_str()); + DBG_PRINT("DBTManager::EventCB:DeviceWhitelistAdded: %s", e->toString().c_str()); const MgmtEvtDeviceWhitelistAdded &event = *static_cast<const MgmtEvtDeviceWhitelistAdded *>(e.get()); (void)event; return true; } bool DBTManager::mgmtEvDeviceWhilelistRemovedCB(std::shared_ptr<MgmtEvent> e) { - DBG_PRINT("DBTManager::EventCB:DeviceRemoved: %s", e->toString().c_str()); + DBG_PRINT("DBTManager::EventCB:DeviceWhitelistRemoved: %s", e->toString().c_str()); const MgmtEvtDeviceWhitelistRemoved &event = *static_cast<const MgmtEvtDeviceWhitelistRemoved *>(e.get()); (void)event; return true; diff --git a/src/direct_bt/MgmtTypes.cpp b/src/direct_bt/MgmtTypes.cpp index 509f403c..6595e19c 100644 --- a/src/direct_bt/MgmtTypes.cpp +++ b/src/direct_bt/MgmtTypes.cpp @@ -143,8 +143,8 @@ std::string direct_bt::getMgmtStatusString(const MgmtStatus opc) { X(LOAD_IRKS) \ X(GET_CONN_INFO) \ X(GET_CLOCK_INFO) \ - X(ADD_DEVICE) \ - X(REMOVE_DEVICE) \ + X(ADD_DEVICE_WHITELIST) \ + X(REMOVE_DEVICE_WHITELIST) \ X(LOAD_CONN_PARAM) \ X(READ_UNCONF_INDEX_LIST) \ X(READ_CONFIG_INFO) \ |