Merge 5.12 into 5.12.1

Change-Id: Ia4746e04af7784d9a33a6c1aa7e0f08fd7dafe1a
This commit is contained in:
Kari Oikarinen 2019-01-08 08:18:01 +02:00
commit 1b4bf7b4e8
29 changed files with 316 additions and 234 deletions

View File

@ -1,3 +1,3 @@
load(qt_build_config)
MODULE_VERSION = 5.12.0
MODULE_VERSION = 5.12.1

View File

@ -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

View File

@ -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];
}
- (void)stopWatchdog
- (bool)objectIsUnderWatch:(id)object operation:(OSXBluetooth::OperationTimeout)type
{
[timeoutWatchdog cancelTimer];
objectUnderWatch = nil;
timeoutType = OSXBluetooth::OperationTimeout::none;
return OSXBluetooth::qt_find_watchdog(timeoutWatchdogs, object, type) != timeoutWatchdogs.end();
}
- (void)timeout
- (void)stopWatchingAfter:(id)object operation:(OSXBluetooth::OperationTimeout)type
{
auto pos = OSXBluetooth::qt_find_watchdog(timeoutWatchdogs, object, type);
if (pos != timeoutWatchdogs.end()) {
[*pos cancelTimer];
timeoutWatchdogs.erase(pos);
}
}
- (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,15 +1459,15 @@ QT_END_NAMESPACE
return;
}
if (service != objectUnderWatch) {
// Timed out already?
return;
}
[self stopWatchdog];
using namespace OSXBluetooth;
if (![self objectIsUnderWatch:service operation:OperationTimeout::characteristicsDiscovery])
return;
QT_BT_MAC_AUTORELEASEPOOL;
[self stopWatchingAfter:service operation:OperationTimeout::characteristicsDiscovery];
Q_ASSERT_X(managerState != CentralManagerUpdating, Q_FUNC_INFO, "invalid state");
if (error) {
@ -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)
using namespace OSXBluetooth;
if (![self objectIsUnderWatch:characteristic operation:OperationTimeout::descriptorsDiscovery])
return;
[self stopWatchdog];
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)
using namespace OSXBluetooth;
if (![self objectIsUnderWatch:descriptor operation:OperationTimeout::descriptorRead])
return;
[self stopWatchdog];
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];
}

View File

@ -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;

View File

@ -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
{

View File

@ -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;

View File

@ -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
{

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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
{

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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
{

View File

@ -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;

View File

@ -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
{

View File

@ -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;

View File

@ -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
{

View File

@ -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

View File

@ -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
{

View File

@ -88,11 +88,6 @@ QList<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;

View File

@ -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
{

View File

@ -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;

View File

@ -427,8 +427,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.

View File

@ -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.

View File

@ -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)
{
}