38 #include "BTIoctl.hpp"
39 #include "HCIIoctl.hpp"
55 std::shared_ptr<BTDevice> BTAdapter::findDevice(device_list_t & devices,
const EUI48 & address,
const BDAddressType addressType) noexcept {
58 std::shared_ptr<BTDevice> & e = devices[i];
66 std::shared_ptr<BTDevice> BTAdapter::findDevice(device_list_t & devices,
BTDevice const & device) noexcept {
69 std::shared_ptr<BTDevice> & e = devices[i];
70 if (
nullptr != e && device == *e ) {
77 bool BTAdapter::addConnectedDevice(
const std::shared_ptr<BTDevice> & device) noexcept {
78 const std::lock_guard<std::mutex> lock(mtx_connectedDevices);
80 if(
nullptr != findDevice(connectedDevices, *device) ) {
83 connectedDevices.push_back(device);
87 bool BTAdapter::removeConnectedDevice(
const BTDevice & device) noexcept {
88 const std::lock_guard<std::mutex> lock(mtx_connectedDevices);
90 auto end = connectedDevices.end();
91 for (
auto it = connectedDevices.begin(); it != end; ++it) {
92 if (
nullptr != *it && device == **it ) {
93 connectedDevices.erase(it);
100 int BTAdapter::disconnectAllDevices(
const HCIStatusCode reason) noexcept {
101 device_list_t devices;
104 devices = connectedDevices;
106 const int count = devices.size();
107 auto end = devices.end();
108 for (
auto it = devices.begin(); it != end; ++it) {
109 if(
nullptr != *it ) {
110 (*it)->disconnect(reason);
116 std::shared_ptr<BTDevice> BTAdapter::findConnectedDevice (
const EUI48 & address,
const BDAddressType & addressType) noexcept {
117 const std::lock_guard<std::mutex> lock(mtx_connectedDevices);
119 return findDevice(connectedDevices, address, addressType);
126 bool BTAdapter::updateDataFromHCI() noexcept {
130 ERR_PRINT(
"BTAdapter::validateDevInfo: Adapter[%d]: POWERED, LocalVersion failed %s - %s",
136 ERR_PRINT(
"BTAdapter::validateDevInfo: Adapter[%d]: le_read_local_features failed %s - %s",
140 le_features = le_ll_feats;
144 WORDY_PRINT(
"BTAdapter::updateDataFromHCI: Adapter[%d]: POWERED, %s - %s, hci_ext[scan %d, conn %d], features: %s",
146 hci_uses_ext_scan, hci_uses_ext_conn,
151 bool BTAdapter::validateDevInfo() noexcept {
154 keep_le_scan_alive =
false;
157 ERR_PRINT(
"BTAdapter::validateDevInfo: Adapter[%d]: Manager not open",
dev_id);
161 ERR_PRINT(
"BTAdapter::validateDevInfo: Adapter[%d]: HCIHandler closed",
dev_id);
169 ERR_PRINT(
"BTAdapter::validateDevInfo: Adapter[%d]: BTMode invalid, BREDR nor LE set: %s",
dev_id, adapterInfo.
toString().c_str());
175 if( !updateDataFromHCI() ) {
195 ERR_PRINT(
"Could not add all required MgmtEventCallbacks to DBTManager: %s",
toString().c_str());
213 ERR_PRINT(
"Could not add all required MgmtEventCallbacks to HCIHandler: %s of %s", hci.
toString().c_str(),
toString().c_str());
228 adapterInfo( adapterInfo_ ),
230 visibleAddressAndType( adapterInfo_.addressAndType ),
231 dev_id( adapterInfo.dev_id ),
235 valid = validateDevInfo();
241 mgmt.removeAdapter(
this);
247 mgmt.removeAdapter(
this);
259 keep_le_scan_alive =
false;
264 DBG_PRINT(
"BTAdapter::close removeMgmtEventCallback: %d callbacks", count);
266 statusListenerList.
clear();
270 DBG_PRINT(
"BTAdapter::close: closeHCI: ...");
272 DBG_PRINT(
"BTAdapter::close: closeHCI: XXX");
275 const std::lock_guard<std::mutex> lock(mtx_discoveredDevices);
276 discoveredDevices.
clear();
279 const std::lock_guard<std::mutex> lock(mtx_connectedDevices);
280 connectedDevices.
clear();;
283 const std::lock_guard<std::mutex> lock(mtx_sharedDevices);
284 sharedDevices.
clear();
290 void BTAdapter::poweredOff() noexcept {
292 DBG_PRINT(
"BTAdapter::poweredOff: dev_id %d, invalid, %p",
dev_id,
this);
296 keep_le_scan_alive =
false;
301 disconnectAllDevices();
316 const size_t sz = list.size();
317 jau::PLAIN_PRINT(
true,
"- BTAdapter::%s: %zu elements", prefix.c_str(), sz);
319 for (
auto it = list.begin(); it != list.end(); ++idx, ++it) {
321 (*it)->getAddressAndType().toString().c_str(),
322 (*it)->getName().c_str() );
326 device_list_t _sharedDevices, _discoveredDevices, _connectedDevices;
330 _sharedDevices = sharedDevices;
331 _discoveredDevices = discoveredDevices;
332 _connectedDevices = connectedDevices;
334 printDeviceList(
"SharedDevices ", _sharedDevices);
335 printDeviceList(
"ConnectedDevices ", _connectedDevices);
336 printDeviceList(
"DiscoveredDevices ", _discoveredDevices);
341 auto begin = statusListenerList.
begin();
342 jau::PLAIN_PRINT(
true,
"- BTAdapter::StatusListener : %zu elements", (
size_t)begin.size());
343 for(
int ii=0; !begin.is_end(); ++ii, ++begin ) {
344 jau::PLAIN_PRINT(
true,
" - %d / %zu: %s", (ii+1), (
size_t)begin.size(), begin->listener->toString().c_str());
349 return mgmt.setLocalName(dev_id, name, short_name);
354 return MgmtStatus::SUCCESS == mgmt.setDiscoverable(dev_id, value ? 0x01 : 0x00, 10 , current_settings);
368 std::unique_lock<std::mutex> lock(mtx_single_conn_device);
369 const uint32_t timeout_ms = 10000;
371 if(
nullptr != single_conn_device_ptr ) {
372 if( device == *single_conn_device_ptr ) {
373 COND_PRINT(debug_lock,
"BTAdapter::lockConnect: Success: Already locked, same device: %s", device.toString().c_str());
377 while(
nullptr != single_conn_device_ptr ) {
378 std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
379 std::cv_status s = cv_single_conn_device.wait_until(lock, t0 + std::chrono::milliseconds(timeout_ms));
380 if( std::cv_status::timeout == s &&
nullptr != single_conn_device_ptr ) {
383 jau::PLAIN_PRINT(
true,
" - locked-by-other-device %s", single_conn_device_ptr->toString().c_str());
393 jau::PLAIN_PRINT(
true,
" - locked-by-other-device %s", single_conn_device_ptr->toString().c_str());
399 single_conn_device_ptr = &device;
402 #if USE_LINUX_BT_SECURITY
404 const bool res_iocap = mgmt.setIOCapability(dev_id, io_cap, pre_io_cap);
406 iocap_defaultval = pre_io_cap;
407 COND_PRINT(debug_lock,
"BTAdapter::lockConnect: Success: New lock, setIOCapability[%s -> %s], %s",
409 device.toString().c_str());
413 COND_PRINT(debug_lock,
"BTAdapter::lockConnect: Failed: setIOCapability[%s], %s",
414 to_string(io_cap).c_str(), device.toString().c_str());
415 single_conn_device_ptr =
nullptr;
416 cv_single_conn_device.notify_all();
420 COND_PRINT(debug_lock,
"BTAdapter::lockConnect: Success: New lock, ignored io-cap: %s, %s",
422 device.toString().c_str());
426 COND_PRINT(debug_lock,
"BTAdapter::lockConnect: Success: New lock, no io-cap: %s", device.toString().c_str());
431 bool BTAdapter::unlockConnect(
const BTDevice & device) noexcept {
432 std::unique_lock<std::mutex> lock(mtx_single_conn_device);
434 if(
nullptr != single_conn_device_ptr && device == *single_conn_device_ptr ) {
440 const bool res = mgmt.setIOCapability(dev_id, v, o);
441 COND_PRINT(debug_lock,
"BTAdapter::unlockConnect: Success: setIOCapability[res %d: %s -> %s], %s",
443 single_conn_device_ptr->toString().c_str());
445 COND_PRINT(debug_lock,
"BTAdapter::unlockConnect: Success: %s",
446 single_conn_device_ptr->toString().c_str());
448 single_conn_device_ptr =
nullptr;
449 cv_single_conn_device.notify_all();
453 const std::string other_device_str =
nullptr != single_conn_device_ptr ? single_conn_device_ptr->toString() :
"null";
455 jau::PLAIN_PRINT(
true,
" - locked-by-other-device %s", other_device_str.c_str());
456 jau::PLAIN_PRINT(
true,
" - unlock-failed-for %s", device.toString().c_str());
462 bool BTAdapter::unlockConnectAny() noexcept {
463 std::unique_lock<std::mutex> lock(mtx_single_conn_device);
465 if(
nullptr != single_conn_device_ptr ) {
472 COND_PRINT(debug_lock,
"BTAdapter::unlockConnectAny: Success: setIOCapability[res %d: %s -> %s]; %s",
474 single_conn_device_ptr->
toString().c_str());
476 COND_PRINT(debug_lock,
"BTAdapter::unlockConnectAny: Success: %s",
477 single_conn_device_ptr->
toString().c_str());
479 single_conn_device_ptr =
nullptr;
480 cv_single_conn_device.notify_all();
484 COND_PRINT(debug_lock,
"BTAdapter::unlockConnectAny: Not locked");
506 }
else if( wasPowered ) {
508 ERR_PRINT(
"BTAdapter::reset: setPowered(true) failed");
519 return mgmt.isDeviceWhitelisted(dev_id, addressAndType);
523 const uint16_t conn_interval_min,
const uint16_t conn_interval_max,
524 const uint16_t conn_latency,
const uint16_t timeout) {
526 ERR_PRINT(
"BTAdapter::startDiscovery: Adapter not powered: %s",
toString().c_str());
530 ERR_PRINT(
"BTAdapter::addDeviceToWhitelist: device already listed: dev_id %d, address%s",
dev_id, addressAndType.
toString().c_str());
534 if( !mgmt.
uploadConnParam(
dev_id, addressAndType, conn_interval_min, conn_interval_max, conn_latency, timeout) ) {
535 ERR_PRINT(
"BTAdapter::addDeviceToWhitelist: uploadConnParam(dev_id %d, address%s, interval[%u..%u], latency %u, timeout %u): Failed",
536 dev_id, addressAndType.
toString().c_str(), conn_interval_min, conn_interval_max, conn_latency, timeout);
569 std::shared_ptr<BTDevice> sd = getSharedDevice(d);
570 if(
nullptr == sd ) {
605 auto begin = statusListenerList.
begin();
606 while ( !begin.is_end() ) {
607 if ( *begin->listener == *l ) {
629 int res = statusListenerList.
size();
631 auto begin = statusListenerList.
begin();
632 auto it = begin.
end();
635 std::shared_ptr<BTDevice> sda = it->wbr_device.lock();
636 if (
nullptr != sda && *sda == d ) {
640 }
while( it != begin );
650 int count = statusListenerList.
size();
651 statusListenerList.
clear();
655 void BTAdapter::checkDiscoveryState() noexcept {
658 if( keep_le_scan_alive ==
false ) {
660 std::string msg(
"Invalid DiscoveryState: keepAlive "+
std::to_string(keep_le_scan_alive.load())+
661 ", currentScanType*[native "+
662 to_string(currentNativeScanType)+
" != meta "+
669 std::string msg(
"Invalid DiscoveryState: keepAlive "+
std::to_string(keep_le_scan_alive.load())+
670 ", currentScanType*[native "+
671 to_string(currentNativeScanType)+
", meta "+
688 WARN_PRINT(
"BTAdapter::startDiscovery: Adapter not powered: %s",
toString(
true).c_str());
691 const std::lock_guard<std::mutex> lock(mtx_discovery);
697 if( keep_le_scan_alive == keepAlive ) {
698 DBG_PRINT(
"BTAdapter::startDiscovery: Already discovering, unchanged keepAlive %d -> %d, currentScanType[native %s, meta %s] ...\n- %s",
699 keep_le_scan_alive.load(), keepAlive,
702 DBG_PRINT(
"BTAdapter::startDiscovery: Already discovering, changed keepAlive %d -> %d, currentScanType[native %s, meta %s] ...\n- %s",
703 keep_le_scan_alive.load(), keepAlive,
705 keep_le_scan_alive = keepAlive;
707 checkDiscoveryState();
712 jau::PLAIN_PRINT(
true,
"BTAdapter::startDiscovery: Start: keepAlive %d -> %d, currentScanType[native %s, meta %s] ...\n- %s",
713 keep_le_scan_alive.load(), keepAlive,
718 keep_le_scan_alive = keepAlive;
728 jau::PLAIN_PRINT(
true,
"BTAdapter::startDiscovery: End: Result %s, keepAlive %d -> %d, currentScanType[native %s, meta %s] ...\n- %s",
729 to_string(status).c_str(), keep_le_scan_alive.load(), keepAlive,
734 checkDiscoveryState();
739 void BTAdapter::startDiscoveryBackground() noexcept {
742 WARN_PRINT(
"BTAdapter::startDiscoveryBackground: Adapter not powered: %s",
toString(
true).c_str());
745 const std::lock_guard<std::mutex> lock(mtx_discovery);
750 ERR_PRINT(
"BTAdapter::startDiscoveryBackground: le_enable_scan failed: %s",
to_string(status).c_str());
752 checkDiscoveryState();
759 const std::lock_guard<std::mutex> lock(mtx_discovery);
780 DBG_PRINT(
"BTAdapter::stopDiscovery: Start: keepAlive %d, currentScanType[native %s, meta %s], le_scan_temp_disabled %d ...",
781 keep_le_scan_alive.load(),
783 le_scan_temp_disabled);
785 keep_le_scan_alive =
false;
787 DBG_PRINT(
"BTAdapter::stopDiscovery: Already disabled, keepAlive %d, currentScanType[native %s, meta %s] ...",
788 keep_le_scan_alive.load(),
790 checkDiscoveryState();
808 if( le_scan_temp_disabled ) {
817 ERR_PRINT(
"BTAdapter::stopDiscovery: le_enable_scan failed: %s",
to_string(status).c_str());
826 mgmtEvDeviceDiscoveringHCI( e );
829 jau::PLAIN_PRINT(
true,
"BTAdapter::stopDiscovery: End: Result %s, keepAlive %d, currentScanType[native %s, meta %s], le_scan_temp_disabled %d ...\n- %s",
830 to_string(status).c_str(), keep_le_scan_alive.load(),
836 checkDiscoveryState();
844 const std::lock_guard<std::mutex> lock(mtx_discoveredDevices);
846 return findDevice(discoveredDevices, address, addressType);
849 bool BTAdapter::addDiscoveredDevice(std::shared_ptr<BTDevice>
const &device) noexcept {
850 const std::lock_guard<std::mutex> lock(mtx_discoveredDevices);
852 if(
nullptr != findDevice(discoveredDevices, *device) ) {
856 discoveredDevices.push_back(device);
861 const std::lock_guard<std::mutex> lock(mtx_discoveredDevices);
863 for (
auto it = discoveredDevices.begin(); it != discoveredDevices.end(); ++it) {
865 if (
nullptr != *it && addressAndType == device.
addressAndType ) {
866 if(
nullptr == getSharedDevice( device ) ) {
867 removeAllStatusListener( device );
869 discoveredDevices.erase(it);
878 const std::lock_guard<std::mutex> lock(mtx_discoveredDevices);
881 int res = discoveredDevices.
size();
883 auto it = discoveredDevices.
end();
887 if(
nullptr == getSharedDevice( device ) ) {
890 discoveredDevices.
erase(it);
891 }
while( it != discoveredDevices.
begin() );
907 bool BTAdapter::addSharedDevice(std::shared_ptr<BTDevice>
const &device) noexcept {
908 const std::lock_guard<std::mutex> lock(mtx_sharedDevices);
909 if(
nullptr != findDevice(sharedDevices, *device) ) {
913 sharedDevices.push_back(device);
917 std::shared_ptr<BTDevice> BTAdapter::getSharedDevice(
const BTDevice & device) noexcept {
918 const std::lock_guard<std::mutex> lock(mtx_sharedDevices);
919 return findDevice(sharedDevices, device);
922 void BTAdapter::removeSharedDevice(
const BTDevice & device) noexcept {
923 const std::lock_guard<std::mutex> lock(mtx_sharedDevices);
924 for (
auto it = sharedDevices.begin(); it != sharedDevices.end(); ) {
925 if (
nullptr != *it && device == **it ) {
926 it = sharedDevices.erase(it);
935 const std::lock_guard<std::mutex> lock(mtx_sharedDevices);
936 return findDevice(sharedDevices, address, addressType);
939 void BTAdapter::removeDevice(
BTDevice & device) noexcept {
940 WORDY_PRINT(
"DBTAdapter::removeDevice: Start %s", toString().c_str());
941 removeAllStatusListener(device);
944 WORDY_PRINT(
"BTAdapter::removeDevice: disconnect %s, %s",
to_string(status).c_str(), toString().c_str());
945 unlockConnect(device);
946 removeConnectedDevice(device);
947 removeDiscoveredDevice(device.addressAndType);
948 removeSharedDevice(device);
951 jau::PLAIN_PRINT(
true,
"BTAdapter::removeDevice: End %s, %s", device.getAddressAndType().toString().c_str(), toString().c_str());
957 std::string random_address_info = adapterInfo.addressAndType != visibleAddressAndType ?
" ("+visibleAddressAndType.toString()+
")" :
"";
958 std::string out(
"Adapter[BTMode "+
to_string(btMode)+
", "+adapterInfo.addressAndType.toString()+random_address_info+
960 ", curSettings"+
to_string(adapterInfo.getCurrentSettingMask())+
961 ", scanType[native "+
to_string(hci.getCurrentScanType())+
", meta "+
to_string(currentMetaScanType)+
"]"
965 "], "+javaObjectToString()+
"]");
966 if( includeDiscoveredDevices ) {
968 if( devices.
size() > 0 ) {
970 for(
auto it = devices.
begin(); it != devices.
end(); it++) {
971 std::shared_ptr<BTDevice> p = *it;
973 out.append(
" ").append(p->
toString()).append(
"\n");
984 const uint64_t timestampMS) noexcept
989 p.
listener->adapterSettingsChanged(*
this, old_settings_, current_settings, changes, timestampMS);
990 }
catch (std::exception &e) {
991 ERR_PRINT(
"BTAdapter:CB:NewSettings-CBs %d/%zd: %s of %s: Caught exception %s",
992 i+1, statusListenerList.size(),
993 p.
listener->toString().c_str(), toString().c_str(), e.what());
999 void BTAdapter::sendAdapterSettingsInitial(
AdapterStatusListener & asl,
const uint64_t timestampMS) noexcept
1001 const AdapterSetting current_settings = adapterInfo.getCurrentSettingMask();
1002 COND_PRINT(debug_event,
"BTAdapter::sendAdapterSettingsInitial: NONE -> %s, changes NONE: %s",
1003 to_string(current_settings).c_str(), toString().c_str() );
1006 }
catch (std::exception &e) {
1007 ERR_PRINT(
"BTAdapter::sendAdapterSettingsChanged-CB: %s of %s: Caught exception %s",
1008 asl.toString().c_str(), toString().c_str(), e.what());
1012 void BTAdapter::sendDeviceUpdated(std::string cause, std::shared_ptr<BTDevice> device, uint64_t timestamp,
EIRDataType updateMask) noexcept {
1016 if( p.
listener->matchDevice(*device) ) {
1017 p.listener->deviceUpdated(device, updateMask, timestamp);
1019 }
catch (std::exception &e) {
1020 ERR_PRINT(
"BTAdapter::sendDeviceUpdated-CBs (%s) %d/%zd: %s of %s: Caught exception %s",
1021 cause.c_str(), i+1, statusListenerList.size(),
1022 p.
listener->toString().c_str(), device->toString().c_str(), e.what());
1030 bool BTAdapter::mgmtEvDeviceDiscoveringHCI(
const MgmtEvent& e) noexcept {
1031 return mgmtEvDeviceDiscoveringAny(e,
true );
1034 bool BTAdapter::mgmtEvDeviceDiscoveringMgmt(
const MgmtEvent& e) noexcept {
1035 return mgmtEvDeviceDiscoveringAny(e,
false );
1038 bool BTAdapter::mgmtEvDeviceDiscoveringAny(
const MgmtEvent& e,
const bool hciSourced) noexcept {
1039 const std::string srctkn = hciSourced ?
"hci" :
"mgmt";
1042 const bool eventEnabled =
event.getEnabled();
1043 ScanType currentNativeScanType = hci.getCurrentScanType();
1051 if( eventEnabled ) {
1053 nextMetaScanType =
changeScanType(currentMetaScanType, eventScanType,
true);
1058 nextMetaScanType = currentMetaScanType;
1060 nextMetaScanType =
changeScanType(currentMetaScanType, eventScanType,
false);
1067 DBG_PRINT(
"BTAdapter:%s:DeviceDiscovering: dev_id %d, keepDiscoveringAlive %d: scanType[native %s -> %s, meta %s -> %s]): %s",
1068 srctkn.c_str(), dev_id, keep_le_scan_alive.load(),
1071 event.toString().c_str());
1072 currentNativeScanType = nextNativeScanType;
1073 hci.setCurrentScanType(currentNativeScanType);
1075 DBG_PRINT(
"BTAdapter:%s:DeviceDiscovering: dev_id %d, keepDiscoveringAlive %d: scanType[native %s, meta %s -> %s]): %s",
1076 srctkn.c_str(), dev_id, keep_le_scan_alive.load(),
1077 to_string(currentNativeScanType).c_str(),
1079 event.toString().c_str());
1081 currentMetaScanType = nextMetaScanType;
1083 checkDiscoveryState();
1088 p.
listener->discoveringChanged(*
this, currentMetaScanType, eventScanType, eventEnabled, keep_le_scan_alive, event.getTimestamp());
1089 }
catch (std::exception &except) {
1090 ERR_PRINT(
"BTAdapter:%s:DeviceDiscovering-CBs %d/%zd: %s of %s: Caught exception %s",
1091 srctkn.c_str(), i+1, statusListenerList.size(),
1092 p.
listener->toString().c_str(), toString().c_str(), except.what());
1098 std::thread bg(&BTAdapter::startDiscoveryBackground,
this);
1104 bool BTAdapter::mgmtEvNewSettingsMgmt(
const MgmtEvent& e) noexcept {
1105 COND_PRINT(debug_event,
"BTAdapter:mgmt:NewSettings: %s", e.toString().c_str());
1107 const AdapterSetting new_settings = adapterInfo.setCurrentSettingMask(event.getSettings());
1124 old_settings = new_settings;
1126 COND_PRINT(debug_event,
"BTAdapter::mgmt:NewSettings: %s -> %s, changes %s: %s",
1129 to_string(changes).c_str(), toString().c_str() );
1131 if( justPoweredOn ) {
1133 hci.resetAllStates(
true);
1134 updateDataFromHCI();
1136 sendAdapterSettingsChanged(old_settings_, new_settings, changes, event.getTimestamp());
1138 if( justPoweredOff ) {
1140 std::thread bg(&BTAdapter::poweredOff,
this);
1147 bool BTAdapter::mgmtEvLocalNameChangedMgmt(
const MgmtEvent& e) noexcept {
1148 COND_PRINT(debug_event,
"BTAdapter:mgmt:LocalNameChanged: %s", e.toString().c_str());
1150 std::string old_name = localName.
getName();
1151 std::string old_shortName = localName.getShortName();
1152 bool nameChanged = old_name !=
event.getName();
1153 bool shortNameChanged = old_shortName !=
event.getShortName();
1155 localName.setName(event.getName());
1157 if( shortNameChanged ) {
1158 localName.setShortName(event.getShortName());
1160 COND_PRINT(debug_event,
"BTAdapter:mgmt:LocalNameChanged: Local name: %d: '%s' -> '%s'; short_name: %d: '%s' -> '%s'",
1161 nameChanged, old_name.c_str(), localName.getName().c_str(),
1162 shortNameChanged, old_shortName.c_str(), localName.getShortName().c_str());
1164 (void)shortNameChanged;
1168 bool BTAdapter::mgmtEvDeviceConnectedHCI(
const MgmtEvent& e) noexcept {
1169 COND_PRINT(debug_event,
"BTAdapter:hci:DeviceConnected(dev_id %d): %s", dev_id, e.toString().c_str());
1177 ad_report.
read_data(event.getData(),
event.getDataSize());
1179 int new_connect = 0;
1180 std::shared_ptr<BTDevice> device = findConnectedDevice(event.getAddress(), event.getAddressType());
1181 if(
nullptr == device ) {
1182 device = findDiscoveredDevice(event.getAddress(), event.getAddressType());
1183 if(
nullptr != device ) {
1184 addSharedDevice(device);
1188 if(
nullptr == device ) {
1189 device = findSharedDevice(event.getAddress(), event.getAddressType());
1190 if(
nullptr != device ) {
1191 addDiscoveredDevice(device);
1195 if(
nullptr == device ) {
1197 device = BTDevice::make_shared(*
this, ad_report);
1198 addDiscoveredDevice(device);
1199 addSharedDevice(device);
1205 EIRDataType updateMask = device->update(ad_report);
1206 if( 0 == new_connect ) {
1207 WARN_PRINT(
"BTAdapter::EventHCI:DeviceConnected(dev_id %d, already connected, updated %s): %s, handle %s -> %s,\n %s,\n -> %s",
1208 dev_id,
to_string(updateMask).c_str(), event.toString().c_str(),
1213 addConnectedDevice(device);
1214 if( 2 <= new_connect ) {
1217 COND_PRINT(debug_event,
"BTAdapter::EventHCI:DeviceConnected(dev_id %d, new_connect %d, updated %s): %s, handle %s -> %s,\n %s,\n -> %s",
1218 dev_id, new_connect,
to_string(updateMask).c_str(), event.toString().c_str(),
1223 device->notifyConnected(device, event.getHCIHandle(), io_cap_conn);
1231 if( p.
listener->matchDevice(*device) ) {
1232 if( EIRDataType::NONE != updateMask ) {
1233 p.listener->deviceUpdated(device, updateMask, ad_report.getTimestamp());
1235 if( 0 < new_connect ) {
1236 p.listener->deviceConnected(device, event.getHCIHandle(), event.getTimestamp());
1239 }
catch (std::exception &except) {
1240 ERR_PRINT(
"BTAdapter::EventHCI:DeviceConnected-CBs %d/%zd: %s of %s: Caught exception %s",
1241 i+1, statusListenerList.size(),
1242 p.
listener->toString().c_str(), device->
toString().c_str(), except.what());
1249 bool BTAdapter::mgmtEvConnectFailedHCI(
const MgmtEvent& e) noexcept {
1250 COND_PRINT(debug_event,
"BTAdapter::EventHCI:ConnectFailed: %s", e.toString().c_str());
1253 std::shared_ptr<BTDevice> device = findConnectedDevice(event.getAddress(), event.getAddressType());
1254 if(
nullptr != device ) {
1256 COND_PRINT(debug_event,
"BTAdapter::EventHCI:ConnectFailed(dev_id %d): %s, handle %s -> zero,\n -> %s",
1260 unlockConnect(*device);
1261 device->notifyDisconnected();
1262 removeConnectedDevice(*device);
1268 if( p.
listener->matchDevice(*device) ) {
1269 p.listener->deviceDisconnected(device, event.getHCIStatus(), handle, event.getTimestamp());
1271 }
catch (std::exception &except) {
1272 ERR_PRINT(
"BTAdapter::EventHCI:DeviceDisconnected-CBs %d/%zd: %s of %s: Caught exception %s",
1273 i+1, statusListenerList.size(),
1274 p.
listener->toString().c_str(), device->
toString().c_str(), except.what());
1281 WORDY_PRINT(
"BTAdapter::EventHCI:DeviceDisconnected(dev_id %d): Device not tracked: %s",
1282 dev_id, event.toString().c_str());
1287 bool BTAdapter::mgmtEvHCIEncryptionChangedHCI(
const MgmtEvent& e) noexcept {
1290 std::shared_ptr<BTDevice> device = findConnectedDevice(event.getAddress(), event.getAddressType());
1291 if(
nullptr != device ) {
1294 const bool ok = HCIStatusCode::SUCCESS == evtStatus && 0 !=
event.getEncEnabled();
1295 const SMPPairingState pstate = ok ? SMPPairingState::COMPLETED : SMPPairingState::FAILED;
1296 device->updatePairingState(device, e, evtStatus, pstate);
1298 WORDY_PRINT(
"BTAdapter::EventHCI:EncryptionChanged(dev_id %d): Device not tracked: %s",
1299 dev_id, event.toString().c_str());
1303 bool BTAdapter::mgmtEvHCIEncryptionKeyRefreshCompleteHCI(
const MgmtEvent& e) noexcept {
1306 std::shared_ptr<BTDevice> device = findConnectedDevice(event.getAddress(), event.getAddressType());
1307 if(
nullptr != device ) {
1313 device->updatePairingState(device, e, evtStatus, pstate);
1315 WORDY_PRINT(
"BTAdapter::EventHCI:EncryptionKeyRefreshComplete(dev_id %d): Device not tracked: %s",
1316 dev_id, event.toString().c_str());
1321 bool BTAdapter::mgmtEvHCILERemoteUserFeaturesHCI(
const MgmtEvent& e) noexcept {
1324 std::shared_ptr<BTDevice> device = findConnectedDevice(event.getAddress(), event.getAddressType());
1325 if(
nullptr != device ) {
1326 COND_PRINT(debug_event,
"BTAdapter::EventHCI:LERemoteUserFeatures(dev_id %d): %s, %s",
1327 dev_id, event.toString().c_str(), device->
toString().c_str());
1329 device->notifyLEFeatures(device, event.getFeatures());
1332 WORDY_PRINT(
"BTAdapter::EventHCI:LERemoteUserFeatures(dev_id %d): Device not tracked: %s",
1333 dev_id, event.toString().c_str());
1338 bool BTAdapter::mgmtEvDeviceDisconnectedHCI(
const MgmtEvent& e) noexcept {
1341 std::shared_ptr<BTDevice> device = findConnectedDevice(event.getAddress(), event.getAddressType());
1342 if(
nullptr != device ) {
1344 WORDY_PRINT(
"BTAdapter::EventHCI:DeviceDisconnected(dev_id %d): ConnHandle mismatch %s\n -> %s",
1345 dev_id, event.toString().c_str(), device->
toString().c_str());
1348 COND_PRINT(debug_event,
"BTAdapter::EventHCI:DeviceDisconnected(dev_id %d): %s, handle %s -> zero,\n -> %s",
1349 dev_id, event.toString().c_str(),
jau::to_hexstring(event.getHCIHandle()).c_str(),
1352 unlockConnect(*device);
1353 device->notifyDisconnected();
1354 removeConnectedDevice(*device);
1360 if( p.
listener->matchDevice(*device) ) {
1361 p.listener->deviceDisconnected(device, event.getHCIReason(), event.getHCIHandle(), event.getTimestamp());
1363 }
catch (std::exception &except) {
1364 ERR_PRINT(
"BTAdapter::EventHCI:DeviceDisconnected-CBs %d/%zd: %s of %s: Caught exception %s",
1365 i+1, statusListenerList.size(),
1366 p.
listener->toString().c_str(), device->
toString().c_str(), except.what());
1373 WORDY_PRINT(
"BTAdapter::EventHCI:DeviceDisconnected(dev_id %d): Device not tracked: %s",
1374 dev_id, event.toString().c_str());
1379 bool BTAdapter::mgmtEvDeviceDisconnectedMgmt(
const MgmtEvent& e) noexcept {
1380 COND_PRINT(debug_event,
"BTAdapter:mgmt:DeviceDisconnected: %s", e.toString().c_str());
1386 bool BTAdapter::mgmtEvPairDeviceCompleteMgmt(
const MgmtEvent& e) noexcept {
1389 std::shared_ptr<BTDevice> device = findConnectedDevice(event.getAddress(), event.getAddressType());
1390 if(
nullptr != device ) {
1392 const bool ok = HCIStatusCode::ALREADY_PAIRED == evtStatus;
1393 const SMPPairingState pstate = ok ? SMPPairingState::COMPLETED : SMPPairingState::NONE;
1394 device->updatePairingState(device, e, evtStatus, pstate);
1396 WORDY_PRINT(
"BTAdapter::mgmt:PairDeviceComplete(dev_id %d): Device not tracked: %s",
1397 dev_id, event.toString().c_str());
1402 bool BTAdapter::mgmtEvNewLongTermKeyMgmt(
const MgmtEvent& e) noexcept {
1405 std::shared_ptr<BTDevice> device = findConnectedDevice(ltk_info.
address, ltk_info.
address_type);
1406 if(
nullptr != device ) {
1407 const bool ok = ltk_info.
enc_size > 0 && ltk_info.
key_type != MgmtLTKType::NONE;
1409 device->updatePairingState(device, e, HCIStatusCode::SUCCESS, SMPPairingState::COMPLETED);
1411 WORDY_PRINT(
"BTAdapter::mgmt:NewLongTermKey(dev_id %d): Invalid LTK: %s",
1412 dev_id, event.toString().c_str());
1415 WORDY_PRINT(
"BTAdapter::mgmt:NewLongTermKey(dev_id %d): Device not tracked: %s",
1416 dev_id, event.toString().c_str());
1421 bool BTAdapter::mgmtEvDeviceFoundHCI(
const MgmtEvent& e) noexcept {
1426 if(
nullptr == eir ) {
1428 ABORT(
"BTAdapter:hci:DeviceFound: Not sourced from LE_ADVERTISING_REPORT: %s", deviceFoundEvent.
toString().c_str());
1448 if(
nullptr == dev_discovered ) {
1449 if(
nullptr == dev_shared ) {
1453 dev_shared = BTDevice::make_shared(*
this, *eir);
1454 addDiscoveredDevice(dev_shared);
1455 addSharedDevice(dev_shared);
1456 COND_PRINT(debug_event,
"BTAdapter:hci:DeviceFound(1.1, dev_id %d): New undiscovered/unshared %s -> deviceFound(..) %s",
1460 bool device_used =
false;
1463 if( p.
listener->matchDevice(*dev_shared) ) {
1464 device_used = p.listener->deviceFound(dev_shared, eir->getTimestamp()) || device_used;
1466 }
catch (std::exception &except) {
1467 ERR_PRINT(
"BTAdapter:hci:DeviceFound-CBs %d/%zd: %s of %s: Caught exception %s",
1468 i+1, statusListenerList.size(),
1469 p.
listener->toString().c_str(), dev_shared->
toString().c_str(), except.what());
1473 if( !device_used ) {
1476 removeSharedDevice(*dev_shared);
1486 EIRDataType updateMask = dev_shared->update(*eir);
1487 addDiscoveredDevice(dev_shared);
1489 COND_PRINT(debug_event,
"BTAdapter:hci:DeviceFound(1.2, dev_id %d): Undiscovered but shared %s -> deviceFound(..) [deviceUpdated(..)] %s",
1493 bool device_used =
false;
1496 if( p.
listener->matchDevice(*dev_shared) ) {
1497 device_used = p.listener->deviceFound(dev_shared, eir->getTimestamp()) || device_used;
1499 }
catch (std::exception &except) {
1500 ERR_PRINT(
"BTAdapter:hci:DeviceFound: %d/%zd: %s of %s: Caught exception %s",
1501 i+1, statusListenerList.size(),
1502 p.
listener->toString().c_str(), dev_shared->
toString().c_str(), except.what());
1506 if( !device_used ) {
1509 removeSharedDevice(*dev_shared);
1510 }
else if( EIRDataType::NONE != updateMask ) {
1511 sendDeviceUpdated(
"SharedDeviceFound", dev_shared, eir->
getTimestamp(), updateMask);
1518 const EIRDataType updateMask = dev_discovered->update(*eir);
1519 if(
nullptr == dev_shared ) {
1524 if( EIRDataType::NONE != ( updateMask & EIRDataType::NAME ) ) {
1526 COND_PRINT(debug_event,
"BTAdapter:hci:DeviceFound(2.1.1, dev_id %d): Discovered but unshared %s, name changed %s -> deviceFound(..) %s",
1529 addSharedDevice(dev_discovered);
1531 bool device_used =
false;
1534 if( p.
listener->matchDevice(*dev_discovered) ) {
1535 device_used = p.listener->deviceFound(dev_discovered, eir->getTimestamp()) || device_used;
1537 }
catch (std::exception &except) {
1538 ERR_PRINT(
"BTAdapter:hci:DeviceFound: %d/%zd: %s of %s: Caught exception %s",
1539 i+1, statusListenerList.size(),
1540 p.
listener->toString().c_str(), dev_discovered->
toString().c_str(), except.what());
1544 if( !device_used ) {
1547 removeSharedDevice(*dev_discovered);
1551 COND_PRINT(debug_event,
"BTAdapter:hci:DeviceFound(2.1.2, dev_id %d): Discovered but unshared %s, no name change -> Drop(1) %s",
1559 if( EIRDataType::NONE != updateMask ) {
1560 COND_PRINT(debug_event,
"BTAdapter:hci:DeviceFound(2.2.1, dev_id %d): Discovered and shared %s, updated %s -> deviceUpdated(..) %s",
1563 sendDeviceUpdated(
"DiscoveredDeviceFound", dev_shared, eir->
getTimestamp(), updateMask);
1566 COND_PRINT(debug_event,
"BTAdapter:hci:DeviceFound(2.2.2, dev_id %d): Discovered and shared %s, not-updated -> Drop(2) %s",
1574 bool BTAdapter::mgmtEvDeviceUnpairedMgmt(
const MgmtEvent& e) noexcept {
1576 DBG_PRINT(
"BTAdapter:mgmt:DeviceUnpaired: %s", event.toString().c_str());
1579 bool BTAdapter::mgmtEvPinCodeRequestMgmt(
const MgmtEvent& e) noexcept {
1581 DBG_PRINT(
"BTAdapter:mgmt:PinCodeRequest: %s", event.toString().c_str());
1584 bool BTAdapter::mgmtEvAuthFailedMgmt(
const MgmtEvent& e) noexcept {
1587 std::shared_ptr<BTDevice> device = findConnectedDevice(event.getAddress(), event.getAddressType());
1588 if(
nullptr == device ) {
1589 WORDY_PRINT(
"BTAdapter:hci:SMP: dev_id %d: Device not tracked: address[%s, %s], %s",
1590 dev_id, event.getAddress().toString().c_str(),
to_string(event.getAddressType()).c_str(),
1591 event.toString().c_str());
1595 device->updatePairingState(device, e, evtStatus, SMPPairingState::FAILED);
1598 bool BTAdapter::mgmtEvUserConfirmRequestMgmt(
const MgmtEvent& e) noexcept {
1601 std::shared_ptr<BTDevice> device = findConnectedDevice(event.getAddress(), event.getAddressType());
1602 if(
nullptr == device ) {
1603 WORDY_PRINT(
"BTAdapter:hci:SMP: dev_id %d: Device not tracked: address[%s, %s], %s",
1604 dev_id, event.getAddress().toString().c_str(),
to_string(event.getAddressType()).c_str(),
1605 event.toString().c_str());
1609 device->updatePairingState(device, e, HCIStatusCode::SUCCESS, SMPPairingState::NUMERIC_COMPARE_EXPECTED);
1612 bool BTAdapter::mgmtEvUserPasskeyRequestMgmt(
const MgmtEvent& e) noexcept {
1615 std::shared_ptr<BTDevice> device = findConnectedDevice(event.getAddress(), event.getAddressType());
1616 if(
nullptr == device ) {
1617 WORDY_PRINT(
"BTAdapter:hci:SMP: dev_id %d: Device not tracked: address[%s, %s], %s",
1618 dev_id, event.getAddress().toString().c_str(),
to_string(event.getAddressType()).c_str(),
1619 event.toString().c_str());
1622 device->updatePairingState(device, e, HCIStatusCode::SUCCESS, SMPPairingState::PASSKEY_EXPECTED);
1628 std::shared_ptr<BTDevice> device = findConnectedDevice(addressAndType.address, addressAndType.type);
1629 if(
nullptr == device ) {
1630 WORDY_PRINT(
"BTAdapter:hci:SMP: dev_id %d: Device not tracked: address%s: %s, %s",
1631 dev_id, addressAndType.toString().c_str(),
1632 msg.toString().c_str(), source.toString().c_str());
1636 WORDY_PRINT(
"BTAdapter:hci:SMP: dev_id %d: ConnHandle mismatch address%s: %s, %s\n -> %s",
1637 dev_id, addressAndType.toString().c_str(),
1638 msg.toString().c_str(), source.toString().c_str(), device->
toString().c_str());
1642 device->hciSMPMsgCallback(device, msg, source);
1647 void BTAdapter::sendDevicePairingState(std::shared_ptr<BTDevice> device,
const SMPPairingState state,
const PairingMode mode, uint64_t timestamp) noexcept
1652 if( p.
listener->matchDevice(*device) ) {
1653 p.listener->devicePairingState(device, state, mode, timestamp);
1655 }
catch (std::exception &except) {
1656 ERR_PRINT(
"BTAdapter::sendDevicePairingState: %d/%zd: %s of %s: Caught exception %s",
1657 i+1, statusListenerList.size(),
1658 p.
listener->toString().c_str(), device->
toString().c_str(), except.what());
1664 void BTAdapter::sendDeviceReady(std::shared_ptr<BTDevice> device, uint64_t timestamp) noexcept {
1670 if( p.listener->matchDevice(*device) ) {
1671 p.listener->deviceReady(device, timestamp);
1674 }
catch (std::exception &except) {
1675 ERR_PRINT(
"BTAdapter::sendDeviceReady: %d/%zd: %s of %s: Caught exception %s",
1676 i+1, statusListenerList.size(),
1677 p.
listener->toString().c_str(), device->
toString().c_str(), except.what());