diff options
author | Alex Blasche <alexander.blasche@qt.io> | 2019-02-11 08:21:47 +0100 |
---|---|---|
committer | Alex Blasche <alexander.blasche@qt.io> | 2019-02-11 08:21:58 +0100 |
commit | 56c5b16dc1a394c72a004b71a9f5364059630d6c (patch) | |
tree | 7fc631b270636d42449871c0c894b9a5998821d9 /src | |
parent | c3820b3d04aca98ee4e0d5eb85b23819c039532f (diff) | |
parent | cd2f90d9157199ebadcf182a471f264a619fd521 (diff) |
Merge remote-tracking branch 'gerrit/dev' into wip/win
Change-Id: I3402f42380068e3e6e7b3df8b15a712f0d86a3cd
Diffstat (limited to 'src')
45 files changed, 392 insertions, 277 deletions
diff --git a/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLE.java b/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLE.java index 4063537b..dc48514a 100644 --- a/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLE.java +++ b/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLE.java @@ -532,7 +532,7 @@ public class QtBluetoothLE { } try { - // BluetoothDevice.,connectGatt(Context, boolean, BluetoothGattCallback, int) was + // BluetoothDevice.connectGatt(Context, boolean, BluetoothGattCallback, int) was // officially introduced by Android API v23. Earlier Android versions have a private // implementation already though. Let's check at runtime and use it if possible. // @@ -1126,7 +1126,7 @@ public class QtBluetoothLE { return true; } - // Called by TimeoutRunnable if the current I/O job timeoutd out. + // Called by TimeoutRunnable if the current I/O job timed out. // By the time we reach this point the handleForTimeout counter has already been reset // and the regular responses will be blocked off. private void interruptCurrentIO(int handle) diff --git a/src/android/nfc/src/org/qtproject/qt5/android/nfc/QtNfc.java b/src/android/nfc/src/org/qtproject/qt5/android/nfc/QtNfc.java index 6b0fbcbd..19e645f5 100644 --- a/src/android/nfc/src/org/qtproject/qt5/android/nfc/QtNfc.java +++ b/src/android/nfc/src/org/qtproject/qt5/android/nfc/QtNfc.java @@ -54,6 +54,7 @@ import android.content.IntentFilter.MalformedMimeTypeException; import android.os.Bundle; import android.util.Log; import android.content.BroadcastReceiver; +import android.content.pm.PackageManager; public class QtNfc { @@ -106,7 +107,9 @@ public class QtNfc static public boolean start() { - if (m_adapter == null || m_activity == null) return false; + if (m_adapter == null || m_activity == null + || !m_activity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC)) + return false; m_activity.runOnUiThread(new Runnable() { public void run() { @@ -143,7 +146,9 @@ public class QtNfc static public boolean stop() { - if (m_adapter == null || m_activity == null) return false; + if (m_adapter == null || m_activity == null + || !m_activity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC)) + return false; m_activity.runOnUiThread(new Runnable() { public void run() { diff --git a/src/bluetooth/android/jni_android.cpp b/src/bluetooth/android/jni_android.cpp index 176416c8..0688c869 100644 --- a/src/bluetooth/android/jni_android.cpp +++ b/src/bluetooth/android/jni_android.cpp @@ -193,6 +193,9 @@ static void QtBluetoothInputStreamThread_readyData(JNIEnv */*env*/, jobject /*ja void QtBluetoothLE_leScanResult(JNIEnv *env, jobject, jlong qtObject, jobject bluetoothDevice, jint rssi, jbyteArray scanRecord) { + if (Q_UNLIKELY(qtObject == 0)) + return; + reinterpret_cast<AndroidBroadcastReceiver*>(qtObject)->onReceiveLeScan( env, bluetoothDevice, rssi, scanRecord); diff --git a/src/bluetooth/bluez/bluez5_helper.cpp b/src/bluetooth/bluez/bluez5_helper.cpp index bacdfe3c..7ce67690 100644 --- a/src/bluetooth/bluez/bluez5_helper.cpp +++ b/src/bluetooth/bluez/bluez5_helper.cpp @@ -195,6 +195,13 @@ bool mandatoryHciIoctlsAvailable() QVersionNumber bluetoothdVersion() { if (bluezDaemonVersion()->isNull()) { + // Register DBus specific meta types (copied from isBluez5()) + // Not all code paths run through isBluez5() but still need the + // registration. + qDBusRegisterMetaType<InterfaceList>(); + qDBusRegisterMetaType<ManagedObjectList>(); + qDBusRegisterMetaType<ManufacturerDataList>(); + qCDebug(QT_BT_BLUEZ) << "Detecting bluetoothd version"; //Order of matching // 1. Pick whatever the user decides via BLUETOOTH_FORCE_DBUS_LE_VERSION diff --git a/src/bluetooth/osx/osxbtcentralmanager.mm b/src/bluetooth/osx/osxbtcentralmanager.mm index 9254bd98..cadabbaf 100644 --- a/src/bluetooth/osx/osxbtcentralmanager.mm +++ b/src/bluetooth/osx/osxbtcentralmanager.mm @@ -46,6 +46,7 @@ #include <QtCore/qdebug.h> #include <algorithm> +#include <vector> #include <limits> Q_DECLARE_METATYPE(QLowEnergyHandle) @@ -92,13 +93,24 @@ ObjCStrongReference<NSError> qt_timeoutNSError(OperationTimeout type) return ObjCStrongReference<NSError>(nsError, false /*do not retain, done already*/); } +auto qt_find_watchdog(const std::vector<GCDTimer> &watchdogs, id object, OperationTimeout type) +{ + return std::find_if(watchdogs.begin(), watchdogs.end(), [object, type](const GCDTimer &other){ + return [other objectUnderWatch] == object && [other timeoutType] == type;}); +} + } // namespace OSXBluetooth QT_END_NAMESPACE +QT_USE_NAMESPACE @interface QT_MANGLE_NAMESPACE(OSXBTCentralManager) (PrivateAPI) +- (void)watchAfter:(id)object timeout:(OSXBluetooth::OperationTimeout)type; +- (bool)objectIsUnderWatch:(id)object operation:(OSXBluetooth::OperationTimeout)type; +- (void)stopWatchingAfter:(id)object operation:(OSXBluetooth::OperationTimeout)type; +- (void)stopWatchers; - (void)retrievePeripheralAndConnect; - (void)connectToPeripheral; - (void)discoverIncludedServices; @@ -125,6 +137,45 @@ QT_END_NAMESPACE @end @implementation QT_MANGLE_NAMESPACE(OSXBTCentralManager) +{ +@private + CBCentralManager *manager; + OSXBluetooth::CentralManagerState managerState; + bool disconnectPending; + + QBluetoothUuid deviceUuid; + + OSXBluetooth::LECBManagerNotifier *notifier; + + // Quite a verbose service discovery machinery + // (a "graph traversal"). + OSXBluetooth::ObjCStrongReference<NSMutableArray> servicesToVisit; + // The service we're discovering now (included services discovery): + NSUInteger currentService; + // Included services, we'll iterate through at the end of 'servicesToVisit': + OSXBluetooth::ObjCStrongReference<NSMutableArray> servicesToVisitNext; + // We'd like to avoid loops in a services' topology: + OSXBluetooth::ObjCStrongReference<NSMutableSet> visitedServices; + + QList<QBluetoothUuid> servicesToDiscoverDetails; + + OSXBluetooth::ServiceHash serviceMap; + OSXBluetooth::CharHash charMap; + OSXBluetooth::DescHash descMap; + + QLowEnergyHandle lastValidHandle; + + bool requestPending; + OSXBluetooth::RequestQueue requests; + QLowEnergyHandle currentReadHandle; + + OSXBluetooth::ValueHash valuesToWrite; + + qint64 timeoutMS; + std::vector<OSXBluetooth::GCDTimer> timeoutWatchdogs; + + CBPeripheral *peripheral; +} - (id)initWith:(OSXBluetooth::LECBManagerNotifier *)aNotifier { @@ -140,7 +191,6 @@ QT_END_NAMESPACE lastValidHandle = 0; requestPending = false; currentReadHandle = 0; - timeoutType = OperationTimeout::none; if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty("BLUETOOTH_GATT_TIMEOUT"))) { bool ok = false; @@ -176,62 +226,91 @@ QT_END_NAMESPACE if (notifier) notifier->deleteLater(); + [self stopWatchers]; [super dealloc]; } +- (CBPeripheral *)peripheral +{ + return peripheral; +} + - (void)watchAfter:(id)object timeout:(OSXBluetooth::OperationTimeout)type { using namespace OSXBluetooth; - objectUnderWatch = object; - timeoutType = type; - [timeoutWatchdog cancelTimer]; - timeoutWatchdog.reset([[GCDTimerObjC alloc] initWithDelegate:self]); - [timeoutWatchdog startWithTimeout:timeoutMS step:200]; + GCDTimer newWatcher([[GCDTimerObjC alloc] initWithDelegate:self], false /*do not retain*/); + [newWatcher watchAfter:object withTimeoutType:type]; + timeoutWatchdogs.push_back(newWatcher); + [newWatcher startWithTimeout:timeoutMS step:200]; +} + +- (bool)objectIsUnderWatch:(id)object operation:(OSXBluetooth::OperationTimeout)type +{ + return OSXBluetooth::qt_find_watchdog(timeoutWatchdogs, object, type) != timeoutWatchdogs.end(); } -- (void)stopWatchdog +- (void)stopWatchingAfter:(id)object operation:(OSXBluetooth::OperationTimeout)type { - [timeoutWatchdog cancelTimer]; - objectUnderWatch = nil; - timeoutType = OSXBluetooth::OperationTimeout::none; + auto pos = OSXBluetooth::qt_find_watchdog(timeoutWatchdogs, object, type); + if (pos != timeoutWatchdogs.end()) { + [*pos cancelTimer]; + timeoutWatchdogs.erase(pos); + } } -- (void)timeout +- (void)stopWatchers { + for (auto &watchdog : timeoutWatchdogs) + [watchdog cancelTimer]; + timeoutWatchdogs.clear(); +} + +- (void)timeout:(id)sender +{ + Q_UNUSED(sender) + using namespace OSXBluetooth; - Q_ASSERT(objectUnderWatch); - NSLog(@"Timeout caused by: %@", objectUnderWatch); - const ObjCStrongReference<NSError> nsError(qt_timeoutNSError(timeoutType)); - switch (timeoutType) { + GCDTimerObjC *watcher = static_cast<GCDTimerObjC *>(sender); + id cbObject = [watcher objectUnderWatch]; + const OperationTimeout type = [watcher timeoutType]; + + Q_ASSERT([self objectIsUnderWatch:cbObject operation:type]); + + NSLog(@"Timeout caused by: %@", cbObject); + + // Note that after this switch the 'watcher' is released (we don't + // own it anymore), though GCD is probably still holding a reference. + const ObjCStrongReference<NSError> nsError(qt_timeoutNSError(type)); + switch (type) { case OperationTimeout::serviceDiscovery: qCWarning(QT_BT_OSX, "Timeout in services discovery"); [self peripheral:peripheral didDiscoverServices:nsError]; break; case OperationTimeout::includedServicesDiscovery: qCWarning(QT_BT_OSX, "Timeout in included services discovery"); - [self peripheral:peripheral didDiscoverIncludedServicesForService:objectUnderWatch error:nsError]; + [self peripheral:peripheral didDiscoverIncludedServicesForService:cbObject error:nsError]; break; case OperationTimeout::characteristicsDiscovery: qCWarning(QT_BT_OSX, "Timeout in characteristics discovery"); - [self peripheral:peripheral didDiscoverCharacteristicsForService:objectUnderWatch error:nsError]; + [self peripheral:peripheral didDiscoverCharacteristicsForService:cbObject error:nsError]; break; case OperationTimeout::characteristicRead: qCWarning(QT_BT_OSX, "Timeout while reading a characteristic"); - [self peripheral:peripheral didUpdateValueForCharacteristic:objectUnderWatch error:nsError]; + [self peripheral:peripheral didUpdateValueForCharacteristic:cbObject error:nsError]; break; case OperationTimeout::descriptorsDiscovery: qCWarning(QT_BT_OSX, "Timeout in descriptors discovery"); - [self peripheral:peripheral didDiscoverDescriptorsForCharacteristic:objectUnderWatch error:nsError]; + [self peripheral:peripheral didDiscoverDescriptorsForCharacteristic:cbObject error:nsError]; break; case OperationTimeout::descriptorRead: qCWarning(QT_BT_OSX, "Timeout while reading a descriptor"); - [self peripheral:peripheral didUpdateValueForDescriptor:objectUnderWatch error:nsError]; + [self peripheral:peripheral didUpdateValueForDescriptor:cbObject error:nsError]; break; case OperationTimeout::characteristicWrite: qCWarning(QT_BT_OSX, "Timeout while writing a characteristic with response"); - [self peripheral:peripheral didWriteValueForCharacteristic:objectUnderWatch error:nsError]; + [self peripheral:peripheral didWriteValueForCharacteristic:cbObject error:nsError]; default:; } } @@ -1119,7 +1198,7 @@ QT_END_NAMESPACE charMap.clear(); descMap.clear(); currentReadHandle = 0; - [self stopWatchdog]; + [self stopWatchers]; // TODO: also serviceToVisit/VisitNext and visitedServices ? } @@ -1272,12 +1351,14 @@ QT_END_NAMESPACE return; } - if (objectUnderWatch != aPeripheral) { - // Timed out. + using namespace OSXBluetooth; + if (![self objectIsUnderWatch:aPeripheral operation:OperationTimeout::serviceDiscovery]) // Timed out already return; - } - [self stopWatchdog]; + QT_BT_MAC_AUTORELEASEPOOL; + + [self stopWatchingAfter:aPeripheral operation:OperationTimeout::serviceDiscovery]; + managerState = OSXBluetooth::CentralManagerIdle; if (error) { @@ -1303,16 +1384,14 @@ QT_END_NAMESPACE return; } - if (service != objectUnderWatch) { - // Timed out. + if (![self objectIsUnderWatch:service operation:OperationTimeout::includedServicesDiscovery]) return; - } QT_BT_MAC_AUTORELEASEPOOL; Q_ASSERT_X(peripheral, Q_FUNC_INFO, "invalid peripheral (nil)"); - [self stopWatchdog]; + [self stopWatchingAfter:service operation:OperationTimeout::includedServicesDiscovery]; managerState = CentralManagerIdle; if (error) { @@ -1380,14 +1459,14 @@ QT_END_NAMESPACE return; } - if (service != objectUnderWatch) { - // Timed out already? + using namespace OSXBluetooth; + + if (![self objectIsUnderWatch:service operation:OperationTimeout::characteristicsDiscovery]) return; - } - [self stopWatchdog]; + QT_BT_MAC_AUTORELEASEPOOL; - using namespace OSXBluetooth; + [self stopWatchingAfter:service operation:OperationTimeout::characteristicsDiscovery]; Q_ASSERT_X(managerState != CentralManagerUpdating, Q_FUNC_INFO, "invalid state"); @@ -1407,21 +1486,21 @@ QT_END_NAMESPACE { Q_UNUSED(aPeripheral) - if (!notifier) { - // Detached. + if (!notifier) // Detached. return; - } - - const bool readMatch = characteristic == objectUnderWatch; - if (readMatch) - [self stopWatchdog]; using namespace OSXBluetooth; + QT_BT_MAC_AUTORELEASEPOOL; + + const bool readMatch = [self objectIsUnderWatch:characteristic operation:OperationTimeout::characteristicRead]; + if (readMatch) + [self stopWatchingAfter:characteristic operation:OperationTimeout::characteristicRead]; + Q_ASSERT_X(managerState != CentralManagerUpdating, Q_FUNC_INFO, "invalid state"); Q_ASSERT_X(peripheral, Q_FUNC_INFO, "invalid peripheral (nil)"); - QT_BT_MAC_AUTORELEASEPOOL; + // First, let's check if we're discovering a service details now. CBService *const service = characteristic.service; const QBluetoothUuid qtUuid(qt_uuid(service.UUID)); @@ -1495,12 +1574,12 @@ QT_END_NAMESPACE QT_BT_MAC_AUTORELEASEPOOL; - if (characteristic != objectUnderWatch) - return; + using namespace OSXBluetooth; - [self stopWatchdog]; + if (![self objectIsUnderWatch:characteristic operation:OperationTimeout::descriptorsDiscovery]) + return; - using namespace OSXBluetooth; + [self stopWatchingAfter:characteristic operation:OperationTimeout::descriptorsDiscovery]; if (error) { NSLog(@"%s failed with error %@", Q_FUNC_INFO, error); @@ -1533,12 +1612,12 @@ QT_END_NAMESPACE QT_BT_MAC_AUTORELEASEPOOL; - if (descriptor != objectUnderWatch) - return; + using namespace OSXBluetooth; - [self stopWatchdog]; + if (![self objectIsUnderWatch:descriptor operation:OperationTimeout::descriptorRead]) + return; - using namespace OSXBluetooth; + [self stopWatchingAfter:descriptor operation:OperationTimeout::descriptorRead]; CBService *const service = descriptor.characteristic.service; const QBluetoothUuid qtUuid(qt_uuid(service.UUID)); @@ -1625,13 +1704,12 @@ QT_END_NAMESPACE QT_BT_MAC_AUTORELEASEPOOL; - if (characteristic != objectUnderWatch) + if (![self objectIsUnderWatch:characteristic operation:OperationTimeout::characteristicWrite]) return; - [self stopWatchdog]; + [self stopWatchingAfter:characteristic operation:OperationTimeout::characteristicWrite]; requestPending = false; - // Error or not, but the cached value has to be deleted ... const QByteArray valueToReport(valuesToWrite.value(characteristic, QByteArray())); if (!valuesToWrite.remove(characteristic)) { @@ -1727,7 +1805,7 @@ QT_END_NAMESPACE notifier = nullptr; } - [self stopWatchdog]; + [self stopWatchers]; [self disconnectFromDevice]; } diff --git a/src/bluetooth/osx/osxbtcentralmanager_p.h b/src/bluetooth/osx/osxbtcentralmanager_p.h index e172d874..ce348dc6 100644 --- a/src/bluetooth/osx/osxbtcentralmanager_p.h +++ b/src/bluetooth/osx/osxbtcentralmanager_p.h @@ -87,18 +87,6 @@ enum CentralManagerState CentralManagerDisconnecting }; -enum class OperationTimeout -{ - none, - serviceDiscovery, - includedServicesDiscovery, - characteristicsDiscovery, - characteristicRead, - descriptorsDiscovery, - descriptorRead, - characteristicWrite -}; - // In Qt we work with handles and UUIDs. Core Bluetooth // has NSArrays (and nested NSArrays inside servces/characteristics). // To simplify a navigation, I need a simple way to map from a handle @@ -148,52 +136,11 @@ QT_END_NAMESPACE @interface QT_MANGLE_NAMESPACE(OSXBTCentralManager) : NSObject<CBCentralManagerDelegate, CBPeripheralDelegate, QT_MANGLE_NAMESPACE(GCDTimerDelegate)> -{ -@private - CBCentralManager *manager; - QT_PREPEND_NAMESPACE(OSXBluetooth)::CentralManagerState managerState; - bool disconnectPending; - - QT_PREPEND_NAMESPACE(QBluetoothUuid) deviceUuid; - - QT_PREPEND_NAMESPACE(OSXBluetooth)::LECBManagerNotifier *notifier; - - // Quite a verbose service discovery machinery - // (a "graph traversal"). - QT_PREPEND_NAMESPACE(OSXBluetooth)::ObjCStrongReference<NSMutableArray> servicesToVisit; - // The service we're discovering now (included services discovery): - NSUInteger currentService; - // Included services, we'll iterate through at the end of 'servicesToVisit': - QT_PREPEND_NAMESPACE(OSXBluetooth)::ObjCStrongReference<NSMutableArray> servicesToVisitNext; - // We'd like to avoid loops in a services' topology: - QT_PREPEND_NAMESPACE(OSXBluetooth)::ObjCStrongReference<NSMutableSet> visitedServices; - - QT_PREPEND_NAMESPACE(QList)<QT_PREPEND_NAMESPACE(QBluetoothUuid)> servicesToDiscoverDetails; - - QT_PREPEND_NAMESPACE(OSXBluetooth)::ServiceHash serviceMap; - QT_PREPEND_NAMESPACE(OSXBluetooth)::CharHash charMap; - QT_PREPEND_NAMESPACE(OSXBluetooth)::DescHash descMap; - - QT_PREPEND_NAMESPACE(QLowEnergyHandle) lastValidHandle; - - bool requestPending; - QT_PREPEND_NAMESPACE(OSXBluetooth)::RequestQueue requests; - QT_PREPEND_NAMESPACE(QLowEnergyHandle) currentReadHandle; - - QT_PREPEND_NAMESPACE(OSXBluetooth)::ValueHash valuesToWrite; - - qint64 timeoutMS; - id objectUnderWatch; - QT_PREPEND_NAMESPACE(OSXBluetooth)::OperationTimeout timeoutType; - QT_PREPEND_NAMESPACE(OSXBluetooth)::GCDTimer timeoutWatchdog; - -@public - CBPeripheral *peripheral; -} - - (id)initWith:(QT_PREPEND_NAMESPACE(OSXBluetooth)::LECBManagerNotifier *)notifier; - (void)dealloc; +- (CBPeripheral *)peripheral; + // IMPORTANT: _all_ these methods are to be executed on qt_LE_queue, // when passing parameters - C++ objects _must_ be copied (see the controller's code). - (void)connectToDevice:(const QT_PREPEND_NAMESPACE(QBluetoothUuid) &)aDeviceUuid; diff --git a/src/bluetooth/osx/osxbtconnectionmonitor.mm b/src/bluetooth/osx/osxbtconnectionmonitor.mm index dcd38726..b777af8e 100644 --- a/src/bluetooth/osx/osxbtconnectionmonitor.mm +++ b/src/bluetooth/osx/osxbtconnectionmonitor.mm @@ -59,6 +59,11 @@ using namespace QT_NAMESPACE; #endif @implementation QT_MANGLE_NAMESPACE(OSXBTConnectionMonitor) +{ + QT_PREPEND_NAMESPACE(OSXBluetooth::ConnectionMonitor) *monitor; + IOBluetoothUserNotification *discoveryNotification; + NSMutableArray *foundConnections; +} - (id)initWithMonitor:(OSXBluetooth::ConnectionMonitor *)aMonitor { diff --git a/src/bluetooth/osx/osxbtconnectionmonitor_p.h b/src/bluetooth/osx/osxbtconnectionmonitor_p.h index 18ffc86a..679f6124 100644 --- a/src/bluetooth/osx/osxbtconnectionmonitor_p.h +++ b/src/bluetooth/osx/osxbtconnectionmonitor_p.h @@ -79,11 +79,6 @@ public: QT_END_NAMESPACE @interface QT_MANGLE_NAMESPACE(OSXBTConnectionMonitor) : NSObject -{ - QT_PREPEND_NAMESPACE(OSXBluetooth::ConnectionMonitor) *monitor; - IOBluetoothUserNotification *discoveryNotification; - NSMutableArray *foundConnections; -} - (id)initWithMonitor:(QT_PREPEND_NAMESPACE(OSXBluetooth::ConnectionMonitor) *)monitor; - (void)connectionNotification:(id)notification withDevice:(IOBluetoothDevice *)device; diff --git a/src/bluetooth/osx/osxbtdeviceinquiry.mm b/src/bluetooth/osx/osxbtdeviceinquiry.mm index 79a8a92c..57cd73e1 100644 --- a/src/bluetooth/osx/osxbtdeviceinquiry.mm +++ b/src/bluetooth/osx/osxbtdeviceinquiry.mm @@ -60,6 +60,11 @@ QT_USE_NAMESPACE @implementation QT_MANGLE_NAMESPACE(OSXBTDeviceInquiry) +{ + IOBluetoothDeviceInquiry *m_inquiry; + bool m_active; + QT_PREPEND_NAMESPACE(OSXBluetooth::DeviceInquiryDelegate) *m_delegate;//C++ "delegate" +} - (id)initWithDelegate:(OSXBluetooth::DeviceInquiryDelegate *)delegate { diff --git a/src/bluetooth/osx/osxbtdeviceinquiry_p.h b/src/bluetooth/osx/osxbtdeviceinquiry_p.h index 777184f9..0fec2db2 100644 --- a/src/bluetooth/osx/osxbtdeviceinquiry_p.h +++ b/src/bluetooth/osx/osxbtdeviceinquiry_p.h @@ -80,11 +80,6 @@ public: QT_END_NAMESPACE @interface QT_MANGLE_NAMESPACE(OSXBTDeviceInquiry) : NSObject<IOBluetoothDeviceInquiryDelegate> -{ - IOBluetoothDeviceInquiry *m_inquiry; - bool m_active; - QT_PREPEND_NAMESPACE(OSXBluetooth::DeviceInquiryDelegate) *m_delegate;//C++ "delegate" -} - (id)initWithDelegate:(QT_PREPEND_NAMESPACE(OSXBluetooth::DeviceInquiryDelegate) *)delegate; - (void)dealloc; diff --git a/src/bluetooth/osx/osxbtdevicepair.mm b/src/bluetooth/osx/osxbtdevicepair.mm index dcaa3536..75dbbcad 100644 --- a/src/bluetooth/osx/osxbtdevicepair.mm +++ b/src/bluetooth/osx/osxbtdevicepair.mm @@ -69,6 +69,13 @@ QT_END_NAMESPACE QT_USE_NAMESPACE @implementation QT_MANGLE_NAMESPACE(OSXBTPairing) +{ + QT_PREPEND_NAMESPACE(QBluetoothAddress) m_targetAddress; + + bool m_active; + IOBluetoothDevicePair *m_pairing; // The real pairing request + QT_PREPEND_NAMESPACE(OSXBluetooth)::PairingDelegate *m_object; +} - (id)initWithTarget:(const QBluetoothAddress &)address delegate:(OSXBluetooth::PairingDelegate *)object diff --git a/src/bluetooth/osx/osxbtdevicepair_p.h b/src/bluetooth/osx/osxbtdevicepair_p.h index d5db5e35..1a2c7d6b 100644 --- a/src/bluetooth/osx/osxbtdevicepair_p.h +++ b/src/bluetooth/osx/osxbtdevicepair_p.h @@ -90,13 +90,6 @@ ObjCStrongReference<IOBluetoothDevice> device_with_address(const QBluetoothAddre QT_END_NAMESPACE @interface QT_MANGLE_NAMESPACE(OSXBTPairing) : NSObject<IOBluetoothDevicePairDelegate> -{ - QT_PREPEND_NAMESPACE(QBluetoothAddress) m_targetAddress; - - bool m_active; - IOBluetoothDevicePair *m_pairing; // The real pairing request - QT_PREPEND_NAMESPACE(OSXBluetooth)::PairingDelegate *m_object; -} - (id)initWithTarget:(const QBluetoothAddress &)address delegate:(QT_PREPEND_NAMESPACE(OSXBluetooth::PairingDelegate) *)object; diff --git a/src/bluetooth/osx/osxbtgcdtimer.mm b/src/bluetooth/osx/osxbtgcdtimer.mm index 095f8680..9663ca93 100644 --- a/src/bluetooth/osx/osxbtgcdtimer.mm +++ b/src/bluetooth/osx/osxbtgcdtimer.mm @@ -44,7 +44,23 @@ #include <algorithm> -@implementation QT_MANGLE_NAMESPACE(OSXBTGCDTimer) +QT_USE_NAMESPACE +using namespace OSXBluetooth; + +@implementation QT_MANGLE_NAMESPACE(OSXBTGCDTimer) { +@private + qint64 timeoutMS; + qint64 timeoutStepMS; + + // Optional: + id objectUnderWatch; + OperationTimeout timeoutType; + + QElapsedTimer timer; + id<QT_MANGLE_NAMESPACE(GCDTimerDelegate)> timeoutHandler; + + bool cancelled; +} - (instancetype)initWithDelegate:(id<QT_MANGLE_NAMESPACE(GCDTimerDelegate)>)delegate { @@ -52,11 +68,19 @@ timeoutHandler = delegate; timeoutMS = 0; timeoutStepMS = 0; + objectUnderWatch = nil; + timeoutType = OperationTimeout::none; cancelled = false; } return self; } +- (void)watchAfter:(id)object withTimeoutType:(OperationTimeout)type +{ + objectUnderWatch = object; + timeoutType = type; +} + - (void)startWithTimeout:(qint64)ms step:(qint64)stepMS { Q_ASSERT(!timeoutMS && !timeoutStepMS); @@ -86,9 +110,8 @@ const qint64 elapsed = timer.elapsed(); if (elapsed >= timeoutMS) { - [timeoutHandler timeout]; + [timeoutHandler timeout:self]; } else { - using namespace QT_PREPEND_NAMESPACE(OSXBluetooth); // Re-schedule: dispatch_queue_t leQueue(qt_LE_queue()); Q_ASSERT(leQueue); @@ -106,6 +129,18 @@ { cancelled = true; timeoutHandler = nil; + objectUnderWatch = nil; + timeoutType = OperationTimeout::none; +} + +- (id)objectUnderWatch +{ + return objectUnderWatch; +} + +- (OperationTimeout)timeoutType +{ + return timeoutType; } @end diff --git a/src/bluetooth/osx/osxbtgcdtimer_p.h b/src/bluetooth/osx/osxbtgcdtimer_p.h index 007a004b..6bd82c9a 100644 --- a/src/bluetooth/osx/osxbtgcdtimer_p.h +++ b/src/bluetooth/osx/osxbtgcdtimer_p.h @@ -58,25 +58,39 @@ #include <Foundation/Foundation.h> +QT_BEGIN_NAMESPACE + +namespace OSXBluetooth { + +enum class OperationTimeout +{ + none, + serviceDiscovery, + includedServicesDiscovery, + characteristicsDiscovery, + characteristicRead, + descriptorsDiscovery, + descriptorRead, + characteristicWrite +}; + +} // namespace OSXBluetooth + +QT_END_NAMESPACE + @protocol QT_MANGLE_NAMESPACE(GCDTimerDelegate) @required -- (void)timeout; +- (void)timeout:(id)sender; @end -@interface QT_MANGLE_NAMESPACE(OSXBTGCDTimer) : NSObject { -@private - qint64 timeoutMS; - qint64 timeoutStepMS; - QT_PREPEND_NAMESPACE(QElapsedTimer) timer; - id<QT_MANGLE_NAMESPACE(GCDTimerDelegate)> timeoutHandler; - bool cancelled; -} - +@interface QT_MANGLE_NAMESPACE(OSXBTGCDTimer) : NSObject - (instancetype)initWithDelegate:(id<QT_MANGLE_NAMESPACE(GCDTimerDelegate)>)delegate; +- (void)watchAfter:(id)object withTimeoutType:(QT_PREPEND_NAMESPACE(OSXBluetooth)::OperationTimeout)type; - (void)startWithTimeout:(qint64)ms step:(qint64)stepMS; - (void)handleTimeout; - (void)cancelTimer; - +- (id)objectUnderWatch; +- (QT_PREPEND_NAMESPACE(OSXBluetooth)::OperationTimeout)timeoutType; @end QT_BEGIN_NAMESPACE @@ -84,9 +98,9 @@ QT_BEGIN_NAMESPACE namespace OSXBluetooth { using GCDTimerObjC = QT_MANGLE_NAMESPACE(OSXBTGCDTimer); -using GCDTimer = ObjCScopedPointer<GCDTimerObjC>; +using GCDTimer = ObjCStrongReference<GCDTimerObjC>; -} +} // namespace OSXBluetooth QT_END_NAMESPACE diff --git a/src/bluetooth/osx/osxbtl2capchannel.mm b/src/bluetooth/osx/osxbtl2capchannel.mm index 474fe04b..dc8468a0 100644 --- a/src/bluetooth/osx/osxbtl2capchannel.mm +++ b/src/bluetooth/osx/osxbtl2capchannel.mm @@ -48,6 +48,12 @@ QT_USE_NAMESPACE @implementation QT_MANGLE_NAMESPACE(OSXBTL2CAPChannel) +{ + QT_PREPEND_NAMESPACE(OSXBluetooth)::ChannelDelegate *delegate; + IOBluetoothDevice *device; + IOBluetoothL2CAPChannel *channel; + bool connected; +} - (id)initWithDelegate:(OSXBluetooth::ChannelDelegate *)aDelegate { diff --git a/src/bluetooth/osx/osxbtl2capchannel_p.h b/src/bluetooth/osx/osxbtl2capchannel_p.h index a8a08975..512087b4 100644 --- a/src/bluetooth/osx/osxbtl2capchannel_p.h +++ b/src/bluetooth/osx/osxbtl2capchannel_p.h @@ -72,12 +72,6 @@ class ChannelDelegate; QT_END_NAMESPACE @interface QT_MANGLE_NAMESPACE(OSXBTL2CAPChannel) : NSObject<IOBluetoothL2CAPChannelDelegate> -{ - QT_PREPEND_NAMESPACE(OSXBluetooth)::ChannelDelegate *delegate; - IOBluetoothDevice *device; - IOBluetoothL2CAPChannel *channel; - bool connected; -} - (id)initWithDelegate:(QT_PREPEND_NAMESPACE(OSXBluetooth)::ChannelDelegate *)aDelegate; - (id)initWithDelegate:(QT_PREPEND_NAMESPACE(OSXBluetooth)::ChannelDelegate *)aDelegate diff --git a/src/bluetooth/osx/osxbtledeviceinquiry.mm b/src/bluetooth/osx/osxbtledeviceinquiry.mm index 677a4660..c56b6da3 100644 --- a/src/bluetooth/osx/osxbtledeviceinquiry.mm +++ b/src/bluetooth/osx/osxbtledeviceinquiry.mm @@ -122,6 +122,16 @@ QT_END_NAMESPACE QT_USE_NAMESPACE @implementation QT_MANGLE_NAMESPACE(OSXBTLEDeviceInquiry) +{ + LECBManagerNotifier *notifier; + ObjCScopedPointer<CBCentralManager> manager; + + QList<QBluetoothDeviceInfo> devices; + LEInquiryState internalState; + int inquiryTimeoutMS; + + QT_PREPEND_NAMESPACE(OSXBluetooth)::GCDTimer elapsedTimer; +} -(id)initWithNotifier:(LECBManagerNotifier *)aNotifier { @@ -151,8 +161,10 @@ QT_USE_NAMESPACE [super dealloc]; } -- (void)timeout +- (void)timeout:(id)sender { + Q_UNUSED(sender) + if (internalState == InquiryActive) { [manager stopScan]; [manager setDelegate:nil]; @@ -204,7 +216,7 @@ QT_USE_NAMESPACE if (inquiryTimeoutMS > 0) { [elapsedTimer cancelTimer]; - elapsedTimer.reset([[GCDTimerObjC alloc] initWithDelegate:self]); + elapsedTimer.resetWithoutRetain([[GCDTimerObjC alloc] initWithDelegate:self]); [elapsedTimer startWithTimeout:inquiryTimeoutMS step:timeStepMS]; } @@ -239,7 +251,7 @@ QT_USE_NAMESPACE // we'll receive 'PoweredOn' state update later. // No change in internalState. Wait for 30 seconds. [elapsedTimer cancelTimer]; - elapsedTimer.reset([[GCDTimerObjC alloc] initWithDelegate:self]); + elapsedTimer.resetWithoutRetain([[GCDTimerObjC alloc] initWithDelegate:self]); [elapsedTimer startWithTimeout:powerOffTimeoutMS step:300]; return; #else diff --git a/src/bluetooth/osx/osxbtledeviceinquiry_p.h b/src/bluetooth/osx/osxbtledeviceinquiry_p.h index a19055ab..d99a93bd 100644 --- a/src/bluetooth/osx/osxbtledeviceinquiry_p.h +++ b/src/bluetooth/osx/osxbtledeviceinquiry_p.h @@ -89,17 +89,6 @@ enum LEInquiryState }; @interface QT_MANGLE_NAMESPACE(OSXBTLEDeviceInquiry) : NSObject<CBCentralManagerDelegate, QT_MANGLE_NAMESPACE(GCDTimerDelegate)> -{ - LECBManagerNotifier *notifier; - ObjCScopedPointer<CBCentralManager> manager; - - QList<QBluetoothDeviceInfo> devices; - LEInquiryState internalState; - int inquiryTimeoutMS; - - QT_PREPEND_NAMESPACE(OSXBluetooth)::GCDTimer elapsedTimer; -} - - (id)initWithNotifier:(LECBManagerNotifier *)aNotifier; - (void)dealloc; diff --git a/src/bluetooth/osx/osxbtobexsession.mm b/src/bluetooth/osx/osxbtobexsession.mm index 9fbc2c12..868b2319 100644 --- a/src/bluetooth/osx/osxbtobexsession.mm +++ b/src/bluetooth/osx/osxbtobexsession.mm @@ -418,6 +418,27 @@ QT_USE_NAMESPACE @end @implementation QT_MANGLE_NAMESPACE(OSXBTOBEXSession) +{ + QT_PREPEND_NAMESPACE(OSXBluetooth)::OBEXSessionDelegate *delegate; + IOBluetoothDevice *device; + quint16 channelID; + IOBluetoothOBEXSession *session; + + QT_PREPEND_NAMESPACE(OSXBluetooth)::OBEXRequest currentRequest; + + bool connected; + bool connectionIDFound; + quint32 connectionID; + + QT_PREPEND_NAMESPACE(QIODevice) *inputStream; + + // TODO: switch to scoped pointers or strong reference objects instead. + NSMutableData *headersData; + NSMutableData *bodyData; + + quint32 bytesSent; + bool pendingAbort; +} + (OBEXMaxPacketLength) maxPacketLength { diff --git a/src/bluetooth/osx/osxbtobexsession_p.h b/src/bluetooth/osx/osxbtobexsession_p.h index 78c93452..49465f24 100644 --- a/src/bluetooth/osx/osxbtobexsession_p.h +++ b/src/bluetooth/osx/osxbtobexsession_p.h @@ -101,27 +101,6 @@ QT_END_NAMESPACE // (it does not have an interface to re-send data or re-use the same transfer reply). // It either succeeds or fails and tries to cleanup in any case. @interface QT_MANGLE_NAMESPACE(OSXBTOBEXSession) : NSObject -{ - QT_PREPEND_NAMESPACE(OSXBluetooth)::OBEXSessionDelegate *delegate; - IOBluetoothDevice *device; - quint16 channelID; - IOBluetoothOBEXSession *session; - - QT_PREPEND_NAMESPACE(OSXBluetooth)::OBEXRequest currentRequest; - - bool connected; - bool connectionIDFound; - quint32 connectionID; - - QT_PREPEND_NAMESPACE(QIODevice) *inputStream; - - // TODO: switch to scoped pointers or strong reference objects instead. - NSMutableData *headersData; - NSMutableData *bodyData; - - quint32 bytesSent; - bool pendingAbort; -} - (id)initWithDelegate:(QT_PREPEND_NAMESPACE(OSXBluetooth::OBEXSessionDelegate) *)aDelegate remoteDevice:(const QBluetoothAddress &)deviceAddress channelID:(quint16)port; diff --git a/src/bluetooth/osx/osxbtperipheralmanager.mm b/src/bluetooth/osx/osxbtperipheralmanager.mm index d3d92f41..1998340a 100644 --- a/src/bluetooth/osx/osxbtperipheralmanager.mm +++ b/src/bluetooth/osx/osxbtperipheralmanager.mm @@ -178,6 +178,33 @@ bool qt_validate_value_range(const QLowEnergyCharacteristicData &data) @end @implementation QT_MANGLE_NAMESPACE(OSXBTPeripheralManager) +{ + ObjCScopedPointer<CBPeripheralManager> manager; + LECBManagerNotifier *notifier; + + QLowEnergyHandle lastHandle; + // Services in this vector are placed in such order: + // the one that has included services, must + // follow its included services to avoid exceptions from CBPeripheralManager. + std::vector<ObjCStrongReference<CBMutableService>> services; + decltype(services.size()) nextServiceToAdd; + + // Lookup map for included services: + std::map<QBluetoothUuid, CBService *> serviceIndex; + ObjCScopedPointer<NSMutableDictionary> advertisementData; + + GenericLEMap<CBCharacteristic *> charMap; + GenericLEMap<ObjCStrongReference<NSMutableData>> charValues; + + QMap<QLowEnergyHandle, ValueRange> valueRanges; + + std::deque<UpdateRequest> updateQueue; + + ObjCScopedPointer<NSMutableSet> connectedCentrals; + + PeripheralState state; + NSUInteger maxNotificationValueLength; +} - (id)initWith:(LECBManagerNotifier *)aNotifier { diff --git a/src/bluetooth/osx/osxbtperipheralmanager_p.h b/src/bluetooth/osx/osxbtperipheralmanager_p.h index 19a831d8..fcf55698 100644 --- a/src/bluetooth/osx/osxbtperipheralmanager_p.h +++ b/src/bluetooth/osx/osxbtperipheralmanager_p.h @@ -122,33 +122,6 @@ struct UpdateRequest using ValueRange = QPair<NSUInteger, NSUInteger>; @interface QT_MANGLE_NAMESPACE(OSXBTPeripheralManager) : NSObject<CBPeripheralManagerDelegate> -{ - ObjCScopedPointer<CBPeripheralManager> manager; - LECBManagerNotifier *notifier; - - QLowEnergyHandle lastHandle; - // Services in this vector are placed in such order: - // the one that has included services, must - // follow its included services to avoid exceptions from CBPeripheralManager. - std::vector<ObjCStrongReference<CBMutableService>> services; - decltype(services.size()) nextServiceToAdd; - - // Lookup map for included services: - std::map<QBluetoothUuid, CBService *> serviceIndex; - ObjCScopedPointer<NSMutableDictionary> advertisementData; - - GenericLEMap<CBCharacteristic *> charMap; - GenericLEMap<ObjCStrongReference<NSMutableData>> charValues; - - QMap<QLowEnergyHandle, ValueRange> valueRanges; - - std::deque<UpdateRequest> updateQueue; - - ObjCScopedPointer<NSMutableSet> connectedCentrals; - - PeripheralState state; - NSUInteger maxNotificationValueLength; -} - (id)initWith:(LECBManagerNotifier *)notifier; - (void)dealloc; diff --git a/src/bluetooth/osx/osxbtrfcommchannel.mm b/src/bluetooth/osx/osxbtrfcommchannel.mm index bd87aae0..00b67ee0 100644 --- a/src/bluetooth/osx/osxbtrfcommchannel.mm +++ b/src/bluetooth/osx/osxbtrfcommchannel.mm @@ -45,6 +45,12 @@ QT_USE_NAMESPACE @implementation QT_MANGLE_NAMESPACE(OSXBTRFCOMMChannel) +{ + QT_PREPEND_NAMESPACE(OSXBluetooth)::ChannelDelegate *delegate; + IOBluetoothDevice *device; + IOBluetoothRFCOMMChannel *channel; + bool connected; +} - (id)initWithDelegate:(OSXBluetooth::ChannelDelegate *)aDelegate { diff --git a/src/bluetooth/osx/osxbtrfcommchannel_p.h b/src/bluetooth/osx/osxbtrfcommchannel_p.h index bb615559..775999ed 100644 --- a/src/bluetooth/osx/osxbtrfcommchannel_p.h +++ b/src/bluetooth/osx/osxbtrfcommchannel_p.h @@ -72,12 +72,6 @@ class ChannelDelegate; QT_END_NAMESPACE @interface QT_MANGLE_NAMESPACE(OSXBTRFCOMMChannel) : NSObject<IOBluetoothRFCOMMChannelDelegate> -{ - QT_PREPEND_NAMESPACE(OSXBluetooth)::ChannelDelegate *delegate; - IOBluetoothDevice *device; - IOBluetoothRFCOMMChannel *channel; - bool connected; -} - (id)initWithDelegate:(QT_PREPEND_NAMESPACE(OSXBluetooth)::ChannelDelegate *)aDelegate; - (id)initWithDelegate:(QT_PREPEND_NAMESPACE(OSXBluetooth)::ChannelDelegate *)aDelegate diff --git a/src/bluetooth/osx/osxbtsdpinquiry.mm b/src/bluetooth/osx/osxbtsdpinquiry.mm index 5b58bc62..a7bdc2c4 100644 --- a/src/bluetooth/osx/osxbtsdpinquiry.mm +++ b/src/bluetooth/osx/osxbtsdpinquiry.mm @@ -212,6 +212,11 @@ QT_USE_NAMESPACE using namespace OSXBluetooth; @implementation QT_MANGLE_NAMESPACE(OSXBTSDPInquiry) +{ + QT_PREPEND_NAMESPACE(OSXBluetooth::SDPInquiryDelegate) *delegate; + IOBluetoothDevice *device; + bool isActive; +} - (id)initWithDelegate:(SDPInquiryDelegate *)aDelegate { diff --git a/src/bluetooth/osx/osxbtsdpinquiry_p.h b/src/bluetooth/osx/osxbtsdpinquiry_p.h index f8eaf735..dd38a28b 100644 --- a/src/bluetooth/osx/osxbtsdpinquiry_p.h +++ b/src/bluetooth/osx/osxbtsdpinquiry_p.h @@ -89,11 +89,6 @@ QVector<QBluetoothUuid> extract_services_uuids(IOBluetoothDevice *device); QT_END_NAMESPACE @interface QT_MANGLE_NAMESPACE(OSXBTSDPInquiry) : NSObject -{ - QT_PREPEND_NAMESPACE(OSXBluetooth::SDPInquiryDelegate) *delegate; - IOBluetoothDevice *device; - bool isActive; -} - (id)initWithDelegate:(QT_PREPEND_NAMESPACE(OSXBluetooth::SDPInquiryDelegate) *)aDelegate; - (void)dealloc; diff --git a/src/bluetooth/osx/osxbtsocketlistener.mm b/src/bluetooth/osx/osxbtsocketlistener.mm index 52243990..517b7f2d 100644 --- a/src/bluetooth/osx/osxbtsocketlistener.mm +++ b/src/bluetooth/osx/osxbtsocketlistener.mm @@ -57,6 +57,11 @@ QT_END_NAMESPACE QT_USE_NAMESPACE @implementation QT_MANGLE_NAMESPACE(OSXBTSocketListener) +{ + IOBluetoothUserNotification *connectionNotification; + QT_PREPEND_NAMESPACE(OSXBluetooth::SocketListener) *delegate; + quint16 port; +} - (id)initWithListener:(OSXBluetooth::SocketListener *)aDelegate { diff --git a/src/bluetooth/osx/osxbtsocketlistener_p.h b/src/bluetooth/osx/osxbtsocketlistener_p.h index afe3eadc..cac0b7c4 100644 --- a/src/bluetooth/osx/osxbtsocketlistener_p.h +++ b/src/bluetooth/osx/osxbtsocketlistener_p.h @@ -82,11 +82,6 @@ QT_END_NAMESPACE // RFCOMM or L2CAP protocol. It must be deleted to stop listening. @interface QT_MANGLE_NAMESPACE(OSXBTSocketListener) : NSObject -{ - IOBluetoothUserNotification *connectionNotification; - QT_PREPEND_NAMESPACE(OSXBluetooth::SocketListener) *delegate; - quint16 port; -} - (id)initWithListener:(QT_PREPEND_NAMESPACE(OSXBluetooth::SocketListener) *)aDelegate; - (void)dealloc; diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent.cpp index e69dcce3..b132a3a6 100644 --- a/src/bluetooth/qbluetoothdevicediscoveryagent.cpp +++ b/src/bluetooth/qbluetoothdevicediscoveryagent.cpp @@ -431,6 +431,6 @@ QString QBluetoothDeviceDiscoveryAgent::errorString() const return d->errorString; } -#include "moc_qbluetoothdevicediscoveryagent.cpp" - QT_END_NAMESPACE + +#include "moc_qbluetoothdevicediscoveryagent.cpp" diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp index 50f3aef9..443be14d 100644 --- a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp +++ b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp @@ -88,6 +88,9 @@ QBluetoothDeviceDiscoveryAgentPrivate::~QBluetoothDeviceDiscoveryAgentPrivate() if (m_active != NoScanActive) stop(); + if (leScanner.isValid()) + leScanner.setField<jlong>("qtObject", reinterpret_cast<jlong>(nullptr)); + if (receiver) { receiver->unregisterReceiver(); delete receiver; @@ -332,21 +335,29 @@ void QBluetoothDeviceDiscoveryAgentPrivate::processDiscoveredDevices( updatedFields.setFlag(QBluetoothDeviceInfo::Field::ManufacturerData); } - if (!updatedFields.testFlag(QBluetoothDeviceInfo::Field::None)) { - emit q->deviceUpdated(discoveredDevices[i], updatedFields); + if (lowEnergySearchTimeout > 0) { + if (discoveredDevices[i] != info) { + if (discoveredDevices.at(i).name() == info.name()) { + qCDebug(QT_BT_ANDROID) << "Almost Duplicate " << info.address() + << info.name() << "- replacing in place"; + discoveredDevices.replace(i, info); + emit q->deviceDiscovered(info); + } + } else { + if (!updatedFields.testFlag(QBluetoothDeviceInfo::Field::None)) + emit q->deviceUpdated(discoveredDevices[i], updatedFields); + } + return; } - if (discoveredDevices[i] == info) - return; + discoveredDevices.replace(i, info); + emit q->deviceDiscovered(info); - if (discoveredDevices.at(i).name() == info.name()) { - qCDebug(QT_BT_ANDROID) << "Almost Duplicate "<< info.address() - << info.name() << "- replacing in place"; - discoveredDevices.replace(i, info); - emit q->deviceDiscovered(info); - return; - } + if (!updatedFields.testFlag(QBluetoothDeviceInfo::Field::None)) + emit q->deviceUpdated(discoveredDevices[i], updatedFields); + + return; } } diff --git a/src/bluetooth/qbluetoothlocaldevice.cpp b/src/bluetooth/qbluetoothlocaldevice.cpp index 173650a0..38dd56f4 100644 --- a/src/bluetooth/qbluetoothlocaldevice.cpp +++ b/src/bluetooth/qbluetoothlocaldevice.cpp @@ -326,6 +326,6 @@ bool QBluetoothLocalDevice::isValid() const the resulting local device selects the local default device. */ -#include "moc_qbluetoothlocaldevice.cpp" - QT_END_NAMESPACE + +#include "moc_qbluetoothlocaldevice.cpp" diff --git a/src/bluetooth/qbluetoothserver.cpp b/src/bluetooth/qbluetoothserver.cpp index 8f760eed..6991518f 100644 --- a/src/bluetooth/qbluetoothserver.cpp +++ b/src/bluetooth/qbluetoothserver.cpp @@ -323,6 +323,6 @@ QBluetoothServer::Error QBluetoothServer::error() const return d->m_lastError; } -#include "moc_qbluetoothserver.cpp" - QT_END_NAMESPACE + +#include "moc_qbluetoothserver.cpp" diff --git a/src/bluetooth/qbluetoothservicediscoveryagent.cpp b/src/bluetooth/qbluetoothservicediscoveryagent.cpp index 390b9f74..a5fc7654 100644 --- a/src/bluetooth/qbluetoothservicediscoveryagent.cpp +++ b/src/bluetooth/qbluetoothservicediscoveryagent.cpp @@ -575,6 +575,6 @@ bool QBluetoothServiceDiscoveryAgentPrivate::isDuplicatedService( return false; } -#include "moc_qbluetoothservicediscoveryagent.cpp" - QT_END_NAMESPACE + +#include "moc_qbluetoothservicediscoveryagent.cpp" diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp b/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp index e16caff6..6a93143b 100644 --- a/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp +++ b/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp @@ -291,7 +291,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_finishSdpScan(QBluetoothServiceD emit q->error(error); } else if (!xmlRecords.isEmpty() && discoveryState() != Inactive) { for (const QString &record : xmlRecords) { - const QBluetoothServiceInfo serviceInfo = parseServiceXml(record); + QBluetoothServiceInfo serviceInfo = parseServiceXml(record); //apply uuidFilter if (!uuidFilter.isEmpty()) { @@ -313,6 +313,22 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_finishSdpScan(QBluetoothServiceD if (!serviceInfo.isValid()) continue; + // Bluez sdpscanner declares custom uuids into the service class uuid list. + // Let's move a potential custom uuid from QBluetoothServiceInfo::serviceClassUuids() + // to QBluetoothServiceInfo::serviceUuid(). If there is more than one, just move the first uuid + const QList<QBluetoothUuid> serviceClassUuids = serviceInfo.serviceClassUuids(); + for (const QBluetoothUuid &id : serviceClassUuids) { + if (id.minimumSize() == 16) { + serviceInfo.setServiceUuid(id); + serviceInfo.setServiceName(QBluetoothServiceDiscoveryAgent::tr("Custom Service")); + QBluetoothServiceInfo::Sequence modSeq = + serviceInfo.attribute(QBluetoothServiceInfo::ServiceClassIds).value<QBluetoothServiceInfo::Sequence>(); + modSeq.removeOne(QVariant::fromValue(id)); + serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceClassIds, modSeq); + break; + } + } + if (!isDuplicatedService(serviceInfo)) { discoveredServices.append(serviceInfo); qCDebug(QT_BT_BLUEZ) << "Discovered services" << discoveredDevices.at(0).address().toString() diff --git a/src/bluetooth/qbluetoothsocket.cpp b/src/bluetooth/qbluetoothsocket.cpp index 2367052c..54eb6024 100644 --- a/src/bluetooth/qbluetoothsocket.cpp +++ b/src/bluetooth/qbluetoothsocket.cpp @@ -431,8 +431,8 @@ void QBluetoothSocket::connectToService(const QBluetoothAddress &address, const At any point, the socket can emit error() to signal that an error occurred. - On Android, a connection to a service can not be established using a port. Calling this function - will emit a \l {QBluetoothSocket::ServiceNotFoundError}{ServiceNotFoundError}. + On Android and BlueZ (version 5.46 or above), a connection to a service can not be established using a port. + Calling this function will emit a \l {QBluetoothSocket::ServiceNotFoundError}{ServiceNotFoundError}. Note that most platforms require a pairing prior to connecting to the remote device. Otherwise the connection process may fail. @@ -844,6 +844,6 @@ QDebug operator<<(QDebug debug, QBluetoothSocket::SocketState state) } #endif -#include "moc_qbluetoothsocket.cpp" - QT_END_NAMESPACE + +#include "moc_qbluetoothsocket.cpp" diff --git a/src/bluetooth/qbluetoothsocket.h b/src/bluetooth/qbluetoothsocket.h index ddbe72ca..eefcd2ad 100644 --- a/src/bluetooth/qbluetoothsocket.h +++ b/src/bluetooth/qbluetoothsocket.h @@ -187,7 +187,6 @@ protected: explicit QBluetoothSocket(QBluetoothSocketBasePrivate *d, QBluetoothServiceInfo::Protocol socketType, QObject *parent = nullptr); - friend class QBluetoothServerPrivate; #endif #ifndef QT_OSX_BLUETOOTH QBluetoothSocketBasePrivate *d_ptr; diff --git a/src/bluetooth/qbluetoothsocket_android.cpp b/src/bluetooth/qbluetoothsocket_android.cpp index a478819b..d7f17d17 100644 --- a/src/bluetooth/qbluetoothsocket_android.cpp +++ b/src/bluetooth/qbluetoothsocket_android.cpp @@ -196,7 +196,7 @@ static QBluetoothUuid reverseUuid(const QBluetoothUuid &serviceUuid) bool isBaseUuid = false; serviceUuid.toUInt32(&isBaseUuid); if (isBaseUuid) - return QBluetoothUuid(); + return serviceUuid; const quint128 original = serviceUuid.toUInt128(); quint128 reversed; diff --git a/src/bluetooth/qbluetoothtransfermanager.cpp b/src/bluetooth/qbluetoothtransfermanager.cpp index 165faceb..37a3191a 100644 --- a/src/bluetooth/qbluetoothtransfermanager.cpp +++ b/src/bluetooth/qbluetoothtransfermanager.cpp @@ -130,6 +130,7 @@ QBluetoothTransferReply *QBluetoothTransferManager::put(const QBluetoothTransfer return 0; #endif } -#include "moc_qbluetoothtransfermanager.cpp" QT_END_NAMESPACE + +#include "moc_qbluetoothtransfermanager.cpp" diff --git a/src/bluetooth/qbluetoothtransferreply.cpp b/src/bluetooth/qbluetoothtransferreply.cpp index 0faea96c..a5da8f8f 100644 --- a/src/bluetooth/qbluetoothtransferreply.cpp +++ b/src/bluetooth/qbluetoothtransferreply.cpp @@ -209,6 +209,6 @@ QBluetoothTransferReplyPrivate::QBluetoothTransferReplyPrivate() { } -#include "moc_qbluetoothtransferreply.cpp" - QT_END_NAMESPACE + +#include "moc_qbluetoothtransferreply.cpp" diff --git a/src/bluetooth/qlowenergycontroller_osx.mm b/src/bluetooth/qlowenergycontroller_osx.mm index d01686ae..8cef621c 100644 --- a/src/bluetooth/qlowenergycontroller_osx.mm +++ b/src/bluetooth/qlowenergycontroller_osx.mm @@ -234,7 +234,7 @@ void QLowEnergyControllerPrivateOSX::_q_serviceDiscoveryFinished() QT_BT_MAC_AUTORELEASEPOOL; - NSArray *const services = centralManager.data()->peripheral.services; + NSArray *const services = [centralManager.data() peripheral].services; // Now we have to traverse the discovered services tree. // Essentially it's an iterative version of more complicated code from the // OSXBTCentralManager's code. diff --git a/src/imports/nfc/qdeclarativendeffilter.cpp b/src/imports/nfc/qdeclarativendeffilter.cpp index 6cbda747..c382ccd9 100644 --- a/src/imports/nfc/qdeclarativendeffilter.cpp +++ b/src/imports/nfc/qdeclarativendeffilter.cpp @@ -104,7 +104,7 @@ */ QDeclarativeNdefFilter::QDeclarativeNdefFilter(QObject *parent) -: QObject(parent), m_minimum(1), m_maximum(UINT_MAX) +: QObject(parent), m_minimum(1), m_maximum(INT_MAX) { } diff --git a/src/nfc/qnearfieldmanager_emulator.cpp b/src/nfc/qnearfieldmanager_emulator.cpp index c2c037f6..8a61a3a9 100644 --- a/src/nfc/qnearfieldmanager_emulator.cpp +++ b/src/nfc/qnearfieldmanager_emulator.cpp @@ -49,12 +49,10 @@ QT_BEGIN_NAMESPACE QNearFieldManagerPrivateImpl::QNearFieldManagerPrivateImpl() { - TagActivator *tagActivator = TagActivator::instance(); + globalTagActivator->initialize(); - tagActivator->initialize(); - - connect(tagActivator, &TagActivator::tagActivated, this, &QNearFieldManagerPrivateImpl::tagActivated); - connect(tagActivator, &TagActivator::tagDeactivated, this, &QNearFieldManagerPrivateImpl::tagDeactivated); + connect(globalTagActivator, &TagActivator::tagActivated, this, &QNearFieldManagerPrivateImpl::tagActivated); + connect(globalTagActivator, &TagActivator::tagDeactivated, this, &QNearFieldManagerPrivateImpl::tagDeactivated); } QNearFieldManagerPrivateImpl::~QNearFieldManagerPrivateImpl() @@ -68,7 +66,7 @@ bool QNearFieldManagerPrivateImpl::isAvailable() const void QNearFieldManagerPrivateImpl::reset() { - TagActivator::instance()->reset(); + globalTagActivator->reset(); } void QNearFieldManagerPrivateImpl::tagActivated(TagBase *tag) diff --git a/src/nfc/qnearfieldtarget_emulator.cpp b/src/nfc/qnearfieldtarget_emulator.cpp index 030718cc..0723b655 100644 --- a/src/nfc/qnearfieldtarget_emulator.cpp +++ b/src/nfc/qnearfieldtarget_emulator.cpp @@ -51,7 +51,6 @@ QT_BEGIN_NAMESPACE static QMutex tagMutex; static QMap<TagBase *, bool> tagMap; -static TagActivator tagActivator; TagType1::TagType1(TagBase *tag, QObject *parent) : QNearFieldTagType1(parent), m_tag(tag) @@ -201,7 +200,11 @@ void TagActivator::initialize() if (!tagMap.isEmpty()) return; +#ifndef BUILTIN_TESTDATA QDirIterator nfcTargets(QDir::currentPath(), QStringList(QStringLiteral("*.nfc")), QDir::Files); +#else + QDirIterator nfcTargets(":/nfcdata", QStringList(QStringLiteral("*.nfc")), QDir::Files); +#endif while (nfcTargets.hasNext()) { const QString targetFilename = nfcTargets.next(); @@ -244,11 +247,6 @@ void TagActivator::reset() tagMap.clear(); } -TagActivator *TagActivator::instance() -{ - return &tagActivator; -} - void TagActivator::timerEvent(QTimerEvent *e) { Q_UNUSED(e); diff --git a/src/nfc/qnearfieldtarget_emulator_p.h b/src/nfc/qnearfieldtarget_emulator_p.h index 70a67be8..1b9f7bdb 100644 --- a/src/nfc/qnearfieldtarget_emulator_p.h +++ b/src/nfc/qnearfieldtarget_emulator_p.h @@ -122,6 +122,8 @@ private: int timerId; }; +Q_GLOBAL_STATIC(TagActivator, globalTagActivator); + QT_END_NAMESPACE #endif // QNEARFIELDTARGET_EMULATOR_P_H diff --git a/src/nfc/qqmlndefrecord.cpp b/src/nfc/qqmlndefrecord.cpp index a7304f00..bc3667fe 100644 --- a/src/nfc/qqmlndefrecord.cpp +++ b/src/nfc/qqmlndefrecord.cpp @@ -40,7 +40,7 @@ #include "qqmlndefrecord.h" #include <QtCore/QMap> -#include <QtCore/QRegExp> +#include <QtCore/QRegularExpression> #include <QtCore/qglobalstatic.h> @@ -219,8 +219,8 @@ QQmlNdefRecord *qNewDeclarativeNdefRecordForNdefRecord(const QNdefRecord &record while (i.hasNext()) { i.next(); - QRegExp ex(i.key()); - if (!ex.exactMatch(urn)) + QRegularExpression rx(QRegularExpression::anchoredPattern(i.key())); + if (!rx.match(urn).hasMatch()) continue; const QMetaObject *metaObject = i.value(); |