summaryrefslogtreecommitdiffstats
path: root/src/bluetooth/osx
diff options
context:
space:
mode:
authorAlex Blasche <alexander.blasche@theqtcompany.com>2016-05-13 08:26:38 +0200
committerAlex Blasche <alexander.blasche@theqtcompany.com>2016-05-13 08:27:40 +0200
commit61a7dd3f79525f82345f2e0606b05fce74cb9ec5 (patch)
tree5a669a730ea765487e0895bc254eb802c8b29429 /src/bluetooth/osx
parent03e956dc8f80d7131f89f8e6088c5dfc68eaf94d (diff)
parent2d98ac01e74dc53d9fd42668e3757ca806af9556 (diff)
Merge branch 'dev' into btle
Diffstat (limited to 'src/bluetooth/osx')
-rw-r--r--src/bluetooth/osx/corebluetoothwrapper_p.h45
-rw-r--r--src/bluetooth/osx/osxbt.pri17
-rw-r--r--src/bluetooth/osx/osxbtcentralmanager.mm463
-rw-r--r--src/bluetooth/osx/osxbtcentralmanager_p.h122
-rw-r--r--src/bluetooth/osx/osxbtchanneldelegate.mm34
-rw-r--r--src/bluetooth/osx/osxbtchanneldelegate_p.h45
-rw-r--r--src/bluetooth/osx/osxbtconnectionmonitor.mm34
-rw-r--r--src/bluetooth/osx/osxbtconnectionmonitor_p.h45
-rw-r--r--src/bluetooth/osx/osxbtdeviceinquiry.mm34
-rw-r--r--src/bluetooth/osx/osxbtdeviceinquiry_p.h45
-rw-r--r--src/bluetooth/osx/osxbtdevicepair.mm34
-rw-r--r--src/bluetooth/osx/osxbtdevicepair_p.h45
-rw-r--r--src/bluetooth/osx/osxbtl2capchannel.mm34
-rw-r--r--src/bluetooth/osx/osxbtl2capchannel_p.h45
-rw-r--r--src/bluetooth/osx/osxbtledeviceinquiry.mm341
-rw-r--r--src/bluetooth/osx/osxbtledeviceinquiry_p.h116
-rw-r--r--src/bluetooth/osx/osxbtnotifier.cpp1
-rw-r--r--src/bluetooth/osx/osxbtnotifier_p.h98
-rw-r--r--src/bluetooth/osx/osxbtobexsession.mm34
-rw-r--r--src/bluetooth/osx/osxbtobexsession_p.h45
-rw-r--r--src/bluetooth/osx/osxbtperipheralmanager.mm754
-rw-r--r--src/bluetooth/osx/osxbtperipheralmanager_p.h176
-rw-r--r--src/bluetooth/osx/osxbtrfcommchannel.mm34
-rw-r--r--src/bluetooth/osx/osxbtrfcommchannel_p.h45
-rw-r--r--src/bluetooth/osx/osxbtsdpinquiry.mm34
-rw-r--r--src/bluetooth/osx/osxbtsdpinquiry_p.h45
-rw-r--r--src/bluetooth/osx/osxbtservicerecord.mm34
-rw-r--r--src/bluetooth/osx/osxbtservicerecord_p.h45
-rw-r--r--src/bluetooth/osx/osxbtsocketlistener.mm34
-rw-r--r--src/bluetooth/osx/osxbtsocketlistener_p.h45
-rw-r--r--src/bluetooth/osx/osxbtutility.mm76
-rw-r--r--src/bluetooth/osx/osxbtutility_p.h56
-rw-r--r--src/bluetooth/osx/uistrings.cpp34
-rw-r--r--src/bluetooth/osx/uistrings_p.h45
34 files changed, 2291 insertions, 843 deletions
diff --git a/src/bluetooth/osx/corebluetoothwrapper_p.h b/src/bluetooth/osx/corebluetoothwrapper_p.h
index d0b6f23c..1d67c6ba 100644
--- a/src/bluetooth/osx/corebluetoothwrapper_p.h
+++ b/src/bluetooth/osx/corebluetoothwrapper_p.h
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -34,6 +40,17 @@
#ifndef COREBLUETOOTHWRAPPER_P_H
#define COREBLUETOOTHWRAPPER_P_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#ifndef QT_OSX_BLUETOOTH
#import <CoreBluetooth/CoreBluetooth.h>
diff --git a/src/bluetooth/osx/osxbt.pri b/src/bluetooth/osx/osxbt.pri
index 06389fcc..fc0a5a65 100644
--- a/src/bluetooth/osx/osxbt.pri
+++ b/src/bluetooth/osx/osxbt.pri
@@ -1,5 +1,6 @@
-SOURCES += osx/uistrings.cpp
+SOURCES += osx/uistrings.cpp osx/osxbtnotifier.cpp
PRIVATE_HEADERS += osx/uistrings_p.h
+//QMAKE_CXXFLAGS_WARN_ON += -Wno-nullability-completeness
CONFIG(osx) {
PRIVATE_HEADERS += osx/osxbtutility_p.h \
@@ -15,7 +16,9 @@ CONFIG(osx) {
osx/osxbtobexsession_p.h \
osx/osxbtledeviceinquiry_p.h \
osx/corebluetoothwrapper_p.h \
- osx/osxbtcentralmanager_p.h
+ osx/osxbtcentralmanager_p.h \
+ osx/osxbtnotifier_p.h \
+ osx/osxbtperipheralmanager_p.h
OBJECTIVE_SOURCES += osx/osxbtutility.mm \
osx/osxbtdevicepair.mm \
@@ -29,14 +32,18 @@ CONFIG(osx) {
osx/osxbtsocketlistener.mm \
osx/osxbtobexsession.mm \
osx/osxbtledeviceinquiry.mm \
- osx/osxbtcentralmanager.mm
+ osx/osxbtcentralmanager.mm \
+ osx/osxbtperipheralmanager.mm
} else {
PRIVATE_HEADERS += osx/osxbtutility_p.h \
osx/osxbtledeviceinquiry_p.h \
osx/corebluetoothwrapper_p.h \
- osx/osxbtcentralmanager_p.h
+ osx/osxbtcentralmanager_p.h \
+ osx/osxbtnotifier_p.h \
+ osx/osxbtperipheralmanager_p.h
OBJECTIVE_SOURCES += osx/osxbtutility.mm \
osx/osxbtledeviceinquiry.mm \
- osx/osxbtcentralmanager.mm
+ osx/osxbtcentralmanager.mm \
+ osx/osxbtperipheralmanager.mm
}
diff --git a/src/bluetooth/osx/osxbtcentralmanager.mm b/src/bluetooth/osx/osxbtcentralmanager.mm
index 08905da8..3b0e098d 100644
--- a/src/bluetooth/osx/osxbtcentralmanager.mm
+++ b/src/bluetooth/osx/osxbtcentralmanager.mm
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -34,7 +40,7 @@
#include "qlowenergyserviceprivate_p.h"
#include "qlowenergycharacteristic.h"
#include "osxbtcentralmanager_p.h"
-
+#include "osxbtnotifier_p.h"
#include <QtCore/qloggingcategory.h>
#include <QtCore/qsysinfo.h>
@@ -43,14 +49,14 @@
#include <algorithm>
#include <limits>
+Q_DECLARE_METATYPE(QLowEnergyCharacteristic)
+Q_DECLARE_METATYPE(QLowEnergyDescriptor)
+Q_DECLARE_METATYPE(QLowEnergyHandle)
+
QT_BEGIN_NAMESPACE
namespace OSXBluetooth {
-CentralManagerDelegate::~CentralManagerDelegate()
-{
-}
-
NSUInteger qt_countGATTEntries(CBService *service)
{
// Identify, how many characteristics/descriptors we have on a given service,
@@ -81,14 +87,10 @@ NSUInteger qt_countGATTEntries(CBService *service)
QT_END_NAMESPACE
-#ifdef QT_NAMESPACE
-using namespace QT_NAMESPACE;
-#endif
-
@interface QT_MANGLE_NAMESPACE(OSXBTCentralManager) (PrivateAPI)
-- (QLowEnergyController::Error)connectToDevice; // "Device" is in Qt's world ...
-- (void)connectToPeripheral; // "Peripheral" is in Core Bluetooth.
+- (void)retrievePeripheralAndConnect;
+- (void)connectToPeripheral;
- (void)discoverIncludedServices;
- (void)readCharacteristics:(CBService *)service;
- (void)serviceDetailsDiscoveryFinished:(CBService *)service;
@@ -114,16 +116,14 @@ using namespace QT_NAMESPACE;
@implementation QT_MANGLE_NAMESPACE(OSXBTCentralManager)
-- (id)initWithDelegate:(QT_PREPEND_NAMESPACE(OSXBluetooth)::CentralManagerDelegate *)aDelegate
+- (id)initWith:(OSXBluetooth::LECBManagerNotifier *)aNotifier
{
- Q_ASSERT_X(aDelegate, Q_FUNC_INFO, "invalid delegate (null)");
-
if (self = [super init]) {
manager = nil;
managerState = OSXBluetooth::CentralManagerIdle;
disconnectPending = false;
peripheral = nil;
- delegate = aDelegate;
+ notifier = aNotifier;
currentService = 0;
lastValidHandle = 0;
requestPending = false;
@@ -150,32 +150,37 @@ using namespace QT_NAMESPACE;
[peripheral setDelegate:nil];
[peripheral release];
+ if (notifier)
+ notifier->deleteLater();
+
[super dealloc];
}
-- (QLowEnergyController::Error)connectToDevice:(const QBluetoothUuid &)aDeviceUuid
+- (void)connectToDevice:(const QBluetoothUuid &)aDeviceUuid
{
- Q_ASSERT_X(managerState == OSXBluetooth::CentralManagerIdle,
- Q_FUNC_INFO, "invalid state");
-
+ disconnectPending = false; // Cancel the previous disconnect if any.
deviceUuid = aDeviceUuid;
if (!manager) {
- managerState = OSXBluetooth::CentralManagerUpdating; // We'll have to wait for updated state.
- manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
+ // The first time we try to connect, no manager created yet,
+ // no status update received.
+ if (const dispatch_queue_t leQueue = OSXBluetooth::qt_LE_queue()) {
+ managerState = OSXBluetooth::CentralManagerUpdating;
+ manager = [[CBCentralManager alloc] initWithDelegate:self queue:leQueue];
+ }
+
if (!manager) {
managerState = OSXBluetooth::CentralManagerIdle;
- qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "failed to allocate a "
- "central manager";
- return QLowEnergyController::ConnectionError;
+ qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "failed to allocate a central manager";
+ if (notifier)
+ emit notifier->CBManagerError(QLowEnergyController::ConnectionError);
}
- return QLowEnergyController::NoError;
- } else {
- return [self connectToDevice];
+ } else if (managerState != OSXBluetooth::CentralManagerUpdating) {
+ [self retrievePeripheralAndConnect];
}
}
-- (QLowEnergyController::Error)connectToDevice
+- (void)retrievePeripheralAndConnect
{
Q_ASSERT_X(manager, Q_FUNC_INFO, "invalid central manager (nil)");
Q_ASSERT_X(managerState == OSXBluetooth::CentralManagerIdle,
@@ -183,13 +188,14 @@ using namespace QT_NAMESPACE;
if ([self isConnected]) {
qCDebug(QT_BT_OSX) << Q_FUNC_INFO << "already connected";
- delegate->connectSuccess();
- return QLowEnergyController::NoError;
+ if (notifier)
+ emit notifier->connected();
+ return;
} else if (peripheral) {
// Was retrieved already, but not connected
// or disconnected.
[self connectToPeripheral];
- return QLowEnergyController::NoError;
+ return;
}
using namespace OSXBluetooth;
@@ -198,11 +204,13 @@ using namespace QT_NAMESPACE;
ObjCScopedPointer<NSMutableArray> uuids([[NSMutableArray alloc] init]);
if (!uuids) {
qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "failed to allocate identifiers";
- return QLowEnergyController::ConnectionError;
+ if (notifier)
+ emit notifier->CBManagerError(QLowEnergyController::ConnectionError);
+ return;
}
-#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_9, __IPHONE_6_0)
- if (QSysInfo::MacintoshVersion >= qt_OS_limit(QSysInfo::MV_10_9, QSysInfo::MV_IOS_6_0)) {
+#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_9, __IPHONE_7_0)
+ if (QSysInfo::MacintoshVersion >= qt_OS_limit(QSysInfo::MV_10_9, QSysInfo::MV_IOS_7_0)) {
const quint128 qtUuidData(deviceUuid.toUInt128());
// STATIC_ASSERT on sizes would be handy!
uuid_t uuidData = {};
@@ -210,37 +218,47 @@ using namespace QT_NAMESPACE;
const ObjCScopedPointer<NSUUID> nsUuid([[NSUUID alloc] initWithUUIDBytes:uuidData]);
if (!nsUuid) {
qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "failed to allocate NSUUID identifier";
- return QLowEnergyController::ConnectionError;
+ if (notifier)
+ emit notifier->CBManagerError(QLowEnergyController::ConnectionError);
+ return;
}
[uuids addObject:nsUuid];
-
// With the latest CoreBluetooth, we can synchronously retrive peripherals:
QT_BT_MAC_AUTORELEASEPOOL;
NSArray *const peripherals = [manager retrievePeripheralsWithIdentifiers:uuids];
if (!peripherals || peripherals.count != 1) {
qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "failed to retrive a peripheral";
- return QLowEnergyController::UnknownRemoteDeviceError;
+ if (notifier)
+ emit notifier->CBManagerError(QLowEnergyController::UnknownRemoteDeviceError);
+ return;
}
peripheral = [static_cast<CBPeripheral *>([peripherals objectAtIndex:0]) retain];
[self connectToPeripheral];
-
- return QLowEnergyController::NoError;
+ return;
}
#endif
+ // Either SDK or the target is below 10.9/7.0
+ if (![manager respondsToSelector:@selector(retrievePeripherals:)]) {
+ qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "failed to retrive a peripheral";
+ if (notifier)
+ emit notifier->CBManagerError(QLowEnergyController::UnknownRemoteDeviceError);
+ return;
+ }
+
OSXBluetooth::CFStrongReference<CFUUIDRef> cfUuid(OSXBluetooth::cf_uuid(deviceUuid));
if (!cfUuid) {
qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "failed to create CFUUID object";
- return QLowEnergyController::ConnectionError;
+ if (notifier)
+ emit notifier->CBManagerError(QLowEnergyController::ConnectionError);
+ return;
}
- // TODO: With ARC this cast will be illegal:
+ // With ARC this cast will be illegal:
[uuids addObject:(id)cfUuid.data()];
// Unfortunately, with old Core Bluetooth this call is asynchronous ...
managerState = OSXBluetooth::CentralManagerConnecting;
- [manager retrievePeripherals:uuids];
-
- return QLowEnergyController::NoError;
+ [manager performSelector:@selector(retrievePeripherals:) withObject:uuids.data()];
}
- (void)connectToPeripheral
@@ -253,7 +271,8 @@ using namespace QT_NAMESPACE;
// The state is still the same - connecting.
if ([self isConnected]) {
qCDebug(QT_BT_OSX) << Q_FUNC_INFO << "already connected";
- delegate->connectSuccess();
+ if (notifier)
+ emit notifier->connected();
} else {
qCDebug(QT_BT_OSX) << Q_FUNC_INFO << "trying to connect";
managerState = OSXBluetooth::CentralManagerConnecting;
@@ -272,7 +291,12 @@ using namespace QT_NAMESPACE;
if (QSysInfo::MacintoshVersion >= qt_OS_limit(QSysInfo::MV_10_9, QSysInfo::MV_IOS_7_0))
return peripheral.state == CBPeripheralStateConnected;
#endif
- return peripheral.isConnected;
+ // Either SDK or the target is below 10.9/7.0 ...
+ if (![peripheral respondsToSelector:@selector(isConnected)])
+ return false;
+
+ // Ugly cast to deal with id being a pointer ...
+ return reinterpret_cast<quintptr>([peripheral performSelector:@selector(isConnected)]);
}
- (void)disconnectFromDevice
@@ -280,10 +304,17 @@ using namespace QT_NAMESPACE;
[self reset];
if (managerState == OSXBluetooth::CentralManagerUpdating) {
- disconnectPending = true;
+ disconnectPending = true; // this is for 'didUpdate' method.
+ if (notifier) {
+ // We were waiting for the first update
+ // with 'PoweredOn' status, when suddenly got disconnected called.
+ // Since we have not attempted to connect yet, emit now.
+ // Note: we do not change the state, since we still maybe interested
+ // in the status update before the next connect attempt.
+ emit notifier->disconnected();
+ }
} else {
disconnectPending = false;
-
if ([self isConnected])
managerState = OSXBluetooth::CentralManagerDisconnecting;
else
@@ -292,8 +323,9 @@ using namespace QT_NAMESPACE;
// We have to call -cancelPeripheralConnection: even
// if not connected (to cancel a pending connect attempt).
// Unfortunately, didDisconnect callback is not always called
- // (despite of Apple's docs saying it _must_).
- [manager cancelPeripheralConnection:peripheral];
+ // (despite of Apple's docs saying it _must_ be).
+ if (peripheral)
+ [manager cancelPeripheralConnection:peripheral];
}
}
@@ -310,7 +342,6 @@ using namespace QT_NAMESPACE;
//parameter to nil is considerably slower and is not recommended."
//
// ... but we'd like to have them all:
-
[peripheral setDelegate:self];
managerState = OSXBluetooth::CentralManagerDiscovering;
[peripheral discoverServices:nil];
@@ -320,19 +351,17 @@ using namespace QT_NAMESPACE;
{
using namespace OSXBluetooth;
- Q_ASSERT_X(managerState == CentralManagerIdle, Q_FUNC_INFO,
- "invalid state");
+ Q_ASSERT_X(managerState == CentralManagerIdle, Q_FUNC_INFO, "invalid state");
Q_ASSERT_X(manager, Q_FUNC_INFO, "invalid manager (nil)");
Q_ASSERT_X(peripheral, Q_FUNC_INFO, "invalid peripheral (nil)");
QT_BT_MAC_AUTORELEASEPOOL;
NSArray *const services = peripheral.services;
- if (!services || !services.count) { // Actually, !services.count works in both cases, but ...
+ if (!services || !services.count) {
// A peripheral without any services at all.
- Q_ASSERT_X(delegate, Q_FUNC_INFO,
- "invalid delegate (null)");
- delegate->serviceDiscoveryFinished(ObjCStrongReference<NSArray>());
+ if (notifier)
+ emit notifier->serviceDiscoveryFinished();
} else {
// 'reset' also calls retain on a parameter.
servicesToVisitNext.reset(nil);
@@ -347,7 +376,7 @@ using namespace QT_NAMESPACE;
}
}
-- (bool)discoverServiceDetails:(const QBluetoothUuid &)serviceUuid
+- (void)discoverServiceDetails:(const QBluetoothUuid &)serviceUuid
{
// This function does not change 'managerState', since it
// can be called concurrently (not waiting for the previous
@@ -362,7 +391,7 @@ using namespace QT_NAMESPACE;
if (servicesToDiscoverDetails.contains(serviceUuid)) {
qCWarning(QT_BT_OSX) << Q_FUNC_INFO <<"already discovering for "
<< serviceUuid;
- return true;
+ return;
}
QT_BT_MAC_AUTORELEASEPOOL;
@@ -370,13 +399,16 @@ using namespace QT_NAMESPACE;
if (CBService *const service = [self serviceForUUID:serviceUuid]) {
servicesToDiscoverDetails.append(serviceUuid);
[peripheral discoverCharacteristics:nil forService:service];
- return true;
+ return;
}
qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "unknown service uuid "
<< serviceUuid;
- return false;
+ if (notifier) {
+ emit notifier->CBManagerError(serviceUuid,
+ QLowEnergyService::UnknownError);
+ }
}
- (void)readCharacteristics:(CBService *)service
@@ -389,11 +421,9 @@ using namespace QT_NAMESPACE;
QT_BT_MAC_AUTORELEASEPOOL;
- Q_ASSERT_X(managerState != CentralManagerUpdating, Q_FUNC_INFO,
- "invalid state");
+ Q_ASSERT_X(managerState != CentralManagerUpdating, Q_FUNC_INFO, "invalid state");
Q_ASSERT_X(manager, Q_FUNC_INFO, "invalid manager (nil)");
Q_ASSERT_X(peripheral, Q_FUNC_INFO, "invalid peripheral (nil)");
- Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
if (!service.characteristics || !service.characteristics.count)
return [self serviceDetailsDiscoveryFinished:service];
@@ -433,20 +463,16 @@ using namespace QT_NAMESPACE;
- (void)readDescriptors:(CBService *)service
{
- Q_ASSERT_X(service, "-readDescriptors:",
- "invalid service (nil)");
+ Q_ASSERT_X(service, Q_FUNC_INFO, "invalid service (nil)");
Q_ASSERT_X(managerState != OSXBluetooth::CentralManagerUpdating,
- "-readDescriptors:",
- "invalid state");
- Q_ASSERT_X(peripheral, "-readDescriptors:",
- "invalid peripheral (nil)");
+ Q_FUNC_INFO, "invalid state");
+ Q_ASSERT_X(peripheral, Q_FUNC_INFO, "invalid peripheral (nil)");
QT_BT_MAC_AUTORELEASEPOOL;
NSArray *const cs = service.characteristics;
// We can never be here if we have no characteristics.
- Q_ASSERT_X(cs && cs.count, "-readDescriptors:",
- "invalid service");
+ Q_ASSERT_X(cs && cs.count, Q_FUNC_INFO, "invalid service");
for (CBCharacteristic *c in cs) {
if (c.descriptors && c.descriptors.count)
return [peripheral readValueForDescriptor:[c.descriptors objectAtIndex:0]];
@@ -458,9 +484,7 @@ using namespace QT_NAMESPACE;
- (void)serviceDetailsDiscoveryFinished:(CBService *)service
{
- //
Q_ASSERT_X(service, Q_FUNC_INFO, "invalid service (nil)");
- Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
using namespace OSXBluetooth;
@@ -476,7 +500,8 @@ using namespace QT_NAMESPACE;
if (nHandles >= maxHandle || lastValidHandle > maxHandle - nHandles) {
// Well, that's unlikely :) But we must be sure.
qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "can not allocate more handles";
- delegate->error(serviceUuid, QLowEnergyService::OperationError);
+ if (notifier)
+ notifier->CBManagerError(serviceUuid, QLowEnergyService::OperationError);
return;
}
@@ -539,8 +564,8 @@ using namespace QT_NAMESPACE;
qtService->endHandle = lastValidHandle;
- ObjCStrongReference<CBService> leService(service, true);
- delegate->serviceDetailsDiscoveryFinished(qtService);
+ if (notifier)
+ emit notifier->serviceDetailsDiscoveryFinished(qtService);
}
- (void)performNextRequest
@@ -683,28 +708,37 @@ using namespace QT_NAMESPACE;
}
}
-- (bool)setNotifyValue:(const QByteArray &)value
- forCharacteristic:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))charHandle
+- (void)setNotifyValue:(const QByteArray &)value
+ forCharacteristic:(QLowEnergyHandle)charHandle
+ onService:(const QBluetoothUuid &)serviceUuid
{
using namespace OSXBluetooth;
Q_ASSERT_X(charHandle, Q_FUNC_INFO, "invalid characteristic handle (0)");
- Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
if (!charMap.contains(charHandle)) {
qCWarning(QT_BT_OSX) << Q_FUNC_INFO
- << "unknown characteristic handle " << charHandle;
- return false;
+ << "unknown characteristic handle "
+ << charHandle;
+ if (notifier) {
+ emit notifier->CBManagerError(serviceUuid,
+ QLowEnergyService::DescriptorWriteError);
+ }
+ return;
}
// At the moment we call setNotifyValue _only_ from 'writeDescriptor';
- // from Qt's API POV it's a descriptor write oprtation and we must report
+ // from Qt's API POV it's a descriptor write operation and we must report
// it back, so check _now_ that we really have this descriptor.
const QBluetoothUuid qtUuid(QBluetoothUuid::ClientCharacteristicConfiguration);
if (![self descriptor:qtUuid forCharacteristic:charMap[charHandle]]) {
qCWarning(QT_BT_OSX) << Q_FUNC_INFO
<< "no client characteristic configuration found";
- return false;
+ if (notifier) {
+ emit notifier->CBManagerError(serviceUuid,
+ QLowEnergyService::DescriptorWriteError);
+ }
+ return;
}
LERequest request;
@@ -714,11 +748,10 @@ using namespace QT_NAMESPACE;
requests.enqueue(request);
[self performNextRequest];
-
- return true;
}
-- (bool)readCharacteristic:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))charHandle
+- (void)readCharacteristic:(QLowEnergyHandle)charHandle
+ onService:(const QBluetoothUuid &)serviceUuid
{
using namespace OSXBluetooth;
@@ -728,7 +761,12 @@ using namespace QT_NAMESPACE;
if (!charMap.contains(charHandle)) {
qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "characteristic: " << charHandle << " not found";
- return false;
+ if (notifier) {
+ emit notifier->CBManagerError(serviceUuid,
+ QLowEnergyService::CharacteristicReadError);
+
+ }
+ return;
}
LERequest request;
@@ -737,12 +775,11 @@ using namespace QT_NAMESPACE;
requests.enqueue(request);
[self performNextRequest];
-
- return true;
}
-- (bool)write:(const QT_PREPEND_NAMESPACE(QByteArray) &)value
- charHandle:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))charHandle
+- (void)write:(const QByteArray &)value
+ charHandle:(QLowEnergyHandle)charHandle
+ onService:(const QBluetoothUuid &)serviceUuid
withResponse:(bool)withResponse
{
using namespace OSXBluetooth;
@@ -752,8 +789,13 @@ using namespace QT_NAMESPACE;
QT_BT_MAC_AUTORELEASEPOOL;
if (!charMap.contains(charHandle)) {
- qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "characteristic: " << charHandle << " not found";
- return false;
+ qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "characteristic: "
+ << charHandle << " not found";
+ if (notifier) {
+ emit notifier->CBManagerError(serviceUuid,
+ QLowEnergyService::CharacteristicWriteError);
+ }
+ return;
}
LERequest request;
@@ -764,11 +806,10 @@ using namespace QT_NAMESPACE;
requests.enqueue(request);
[self performNextRequest];
-
- return true;
}
-- (bool)readDescriptor:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))descHandle
+- (void)readDescriptor:(QLowEnergyHandle)descHandle
+ onService:(const QBluetoothUuid &)serviceUuid
{
using namespace OSXBluetooth;
@@ -777,7 +818,11 @@ using namespace QT_NAMESPACE;
if (!descMap.contains(descHandle)) {
qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "handle:"
<< descHandle << "not found";
- return false;
+ if (notifier) {
+ emit notifier->CBManagerError(serviceUuid,
+ QLowEnergyService::DescriptorReadError);
+ }
+ return;
}
LERequest request;
@@ -786,11 +831,11 @@ using namespace QT_NAMESPACE;
requests.enqueue(request);
[self performNextRequest];
-
- return true;
}
-- (bool)write:(const QByteArray &)value descHandle:(QLowEnergyHandle)descHandle
+- (void)write:(const QByteArray &)value
+ descHandle:(QLowEnergyHandle)descHandle
+ onService:(const QBluetoothUuid &)serviceUuid
{
using namespace OSXBluetooth;
@@ -799,7 +844,11 @@ using namespace QT_NAMESPACE;
if (!descMap.contains(descHandle)) {
qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "handle: "
<< descHandle << " not found";
- return false;
+ if (notifier) {
+ emit notifier->CBManagerError(serviceUuid,
+ QLowEnergyService::DescriptorWriteError);
+ }
+ return;
}
LERequest request;
@@ -809,8 +858,6 @@ using namespace QT_NAMESPACE;
requests.enqueue(request);
[self performNextRequest];
-
- return true;
}
// Aux. methods:
@@ -831,7 +878,7 @@ using namespace QT_NAMESPACE;
CBService *const s = [toVisit objectAtIndex:i];
if (equal_uuids(s.UUID, qtUuid))
return s;
- if ([visitedNodes containsObject:s] && s.includedServices && s.includedServices.count) {
+ if (![visitedNodes containsObject:s] && s.includedServices && s.includedServices.count) {
[visitedNodes addObject:s];
[toVisitNext addObjectsFromArray:s.includedServices];
}
@@ -1028,8 +1075,6 @@ using namespace QT_NAMESPACE;
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
- Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
-
using namespace OSXBluetooth;
const CBCentralManagerState state = central.state;
@@ -1044,47 +1089,42 @@ using namespace QT_NAMESPACE;
return;
}
- if (disconnectPending) {
- disconnectPending = false;
- managerState = OSXBluetooth::CentralManagerIdle;
- return [self disconnectFromDevice];
- }
-
// Let's check some states we do not like first:
if (state == CBCentralManagerStateUnsupported || state == CBCentralManagerStateUnauthorized) {
if (managerState == CentralManagerUpdating) {
// We tried to connect just to realize, LE is not supported. Report this.
managerState = CentralManagerIdle;
- delegate->LEnotSupported();
+ if (notifier)
+ emit notifier->LEnotSupported();
} else {
// TODO: if we are here, LE _was_ supported and we first managed to update
// and reset managerState from CentralManagerUpdating.
managerState = CentralManagerIdle;
- delegate->error(QLowEnergyController::InvalidBluetoothAdapterError);
+ if (notifier)
+ emit notifier->CBManagerError(QLowEnergyController::InvalidBluetoothAdapterError);
}
return;
}
if (state == CBCentralManagerStatePoweredOff) {
+ managerState = CentralManagerIdle;
if (managerState == CentralManagerUpdating) {
- // I've seen this instead of Unsopported on OS X.
- managerState = CentralManagerIdle;
- delegate->LEnotSupported();
+ // I've seen this instead of Unsupported on OS X.
+ if (notifier)
+ emit notifier->LEnotSupported();
} else {
- managerState = CentralManagerIdle;
// TODO: we need a better error +
// what will happen if later the state changes to PoweredOn???
- delegate->error(QLowEnergyController::InvalidBluetoothAdapterError);
+ if (notifier)
+ emit notifier->CBManagerError(QLowEnergyController::InvalidBluetoothAdapterError);
}
return;
}
if (state == CBCentralManagerStatePoweredOn) {
- if (managerState == CentralManagerUpdating) {
+ if (managerState == CentralManagerUpdating && !disconnectPending) {
managerState = CentralManagerIdle;
- const QLowEnergyController::Error status = [self connectToDevice];
- if (status != QLowEnergyController::NoError)// An allocation problem?
- delegate->error(status);
+ [self retrievePeripheralAndConnect];
}
} else {
// We actually handled all known states, but .. Core Bluetooth can change?
@@ -1107,12 +1147,9 @@ using namespace QT_NAMESPACE;
managerState = OSXBluetooth::CentralManagerIdle;
if (!peripherals || peripherals.count != 1) {
- Q_ASSERT_X(delegate, Q_FUNC_INFO,
- "invalid delegate (null)");
-
qCDebug(QT_BT_OSX) << Q_FUNC_INFO <<"unexpected number of peripherals (!= 1)";
-
- delegate->error(QLowEnergyController::UnknownRemoteDeviceError);
+ if (notifier)
+ emit notifier->CBManagerError(QLowEnergyController::UnknownRemoteDeviceError);
} else {
peripheral = [static_cast<CBPeripheral *>([peripherals objectAtIndex:0]) retain];
[self connectToPeripheral];
@@ -1124,15 +1161,14 @@ using namespace QT_NAMESPACE;
Q_UNUSED(central)
Q_UNUSED(aPeripheral)
- Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
-
if (managerState != OSXBluetooth::CentralManagerConnecting) {
// We called cancel but before disconnected, managed to connect?
return;
}
managerState = OSXBluetooth::CentralManagerIdle;
- delegate->connectSuccess();
+ if (notifier)
+ emit notifier->connected();
}
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)aPeripheral
@@ -1142,8 +1178,6 @@ using namespace QT_NAMESPACE;
Q_UNUSED(aPeripheral)
Q_UNUSED(error)
- Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
-
if (managerState != OSXBluetooth::CentralManagerConnecting) {
// Canceled already.
return;
@@ -1151,7 +1185,8 @@ using namespace QT_NAMESPACE;
managerState = OSXBluetooth::CentralManagerIdle;
// TODO: better error mapping is required.
- delegate->error(QLowEnergyController::UnknownRemoteDeviceError);
+ if (notifier)
+ notifier->CBManagerError(QLowEnergyController::UnknownRemoteDeviceError);
}
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)aPeripheral
@@ -1160,19 +1195,18 @@ using namespace QT_NAMESPACE;
Q_UNUSED(central)
Q_UNUSED(aPeripheral)
- Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
-
// Clear internal caches/data.
[self reset];
if (error && managerState == OSXBluetooth::CentralManagerDisconnecting) {
managerState = OSXBluetooth::CentralManagerIdle;
qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "failed to disconnect";
- // TODO: instead of 'unknown' - .. ?
- delegate->error(QLowEnergyController::UnknownRemoteDeviceError);
+ if (notifier)
+ emit notifier->CBManagerError(QLowEnergyController::UnknownRemoteDeviceError);
} else {
managerState = OSXBluetooth::CentralManagerIdle;
- delegate->disconnected();
+ if (notifier)
+ emit notifier->disconnected();
}
}
@@ -1190,10 +1224,10 @@ using namespace QT_NAMESPACE;
managerState = OSXBluetooth::CentralManagerIdle;
if (error) {
- // NSLog, not qCDebug/Warning - to print the error.
NSLog(@"%s failed with error %@", Q_FUNC_INFO, error);
// TODO: better error mapping required.
- delegate->error(QLowEnergyController::UnknownError);
+ if (notifier)
+ emit notifier->CBManagerError(QLowEnergyController::UnknownError);
} else {
[self discoverIncludedServices];
}
@@ -1214,14 +1248,11 @@ using namespace QT_NAMESPACE;
QT_BT_MAC_AUTORELEASEPOOL;
- Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
Q_ASSERT_X(peripheral, Q_FUNC_INFO, "invalid peripheral (nil)");
- // TODO: asserts on other "pointers" ...
managerState = CentralManagerIdle;
if (error) {
- // NSLog, not qCWarning/Critical - to log the actual NSError and service UUID.
NSLog(@"%s: finished with error %@ for service %@",
Q_FUNC_INFO, error, service.UUID);
} else if (service.includedServices && service.includedServices.count) {
@@ -1268,8 +1299,8 @@ using namespace QT_NAMESPACE;
servicesToVisit.reset(nil);
servicesToVisitNext.reset(nil);
- const ObjCStrongReference<NSArray> services(peripheral.services, true); // true == retain.
- delegate->serviceDiscoveryFinished(services);
+ if (notifier)
+ emit notifier->serviceDiscoveryFinished();
}
- (void)peripheral:(CBPeripheral *)aPeripheral didDiscoverCharacteristicsForService:(CBService *)service
@@ -1279,21 +1310,20 @@ using namespace QT_NAMESPACE;
// discoveries active.
Q_UNUSED(aPeripheral)
- // TODO: check that this can never be called after cancelPeripheralConnection was executed.
+ if (!notifier) {
+ // Detached.
+ return;
+ }
using namespace OSXBluetooth;
- Q_ASSERT_X(managerState != CentralManagerUpdating,
- Q_FUNC_INFO, "invalid state");
- Q_ASSERT_X(delegate, Q_FUNC_INFO,
- "invalid delegate (null)");
+ Q_ASSERT_X(managerState != CentralManagerUpdating, Q_FUNC_INFO, "invalid state");
if (error) {
- // NSLog to show the actual NSError (can contain something interesting).
NSLog(@"%s failed with error: %@", Q_FUNC_INFO, error);
// We did not discover any characteristics and can not discover descriptors,
// inform our delegate (it will set a service state also).
- delegate->error(qt_uuid(service.UUID), QLowEnergyController::UnknownError);
+ emit notifier->CBManagerError(qt_uuid(service.UUID), QLowEnergyController::UnknownError);
} else {
[self readCharacteristics:service];
}
@@ -1305,11 +1335,15 @@ using namespace QT_NAMESPACE;
{
Q_UNUSED(aPeripheral)
+ if (!notifier) {
+ // Detached.
+ return;
+ }
+
using namespace OSXBluetooth;
Q_ASSERT_X(managerState != CentralManagerUpdating, Q_FUNC_INFO, "invalid state");
Q_ASSERT_X(peripheral, Q_FUNC_INFO, "invalid peripheral (nil)");
- Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
QT_BT_MAC_AUTORELEASEPOOL;
// First, let's check if we're discovering a service details now.
@@ -1319,13 +1353,12 @@ using namespace QT_NAMESPACE;
const QLowEnergyHandle chHandle = charMap.key(characteristic);
if (error) {
- // Use NSLog, not qCDebug/qCWarning to log the actual error.
NSLog(@"%s failed with error %@", Q_FUNC_INFO, error);
if (!isDetailsDiscovery) {
if (chHandle && chHandle == currentReadHandle) {
currentReadHandle = 0;
requestPending = false;
- delegate->error(qtUuid, QLowEnergyService::CharacteristicReadError);
+ emit notifier->CBManagerError(qtUuid, QLowEnergyService::CharacteristicReadError);
[self performNextRequest];
}
return;
@@ -1359,10 +1392,10 @@ using namespace QT_NAMESPACE;
requestPending = false;
currentReadHandle = 0;
//
- delegate->characteristicReadNotification(chHandle, qt_bytearray(characteristic.value));
+ emit notifier->characteristicRead(chHandle, qt_bytearray(characteristic.value));
[self performNextRequest];
} else {
- delegate->characteristicUpdateNotification(chHandle, qt_bytearray(characteristic.value));
+ emit notifier->characteristicUpdated(chHandle, qt_bytearray(characteristic.value));
}
}
}
@@ -1375,12 +1408,16 @@ using namespace QT_NAMESPACE;
// have several discoveries active at the same time.
Q_UNUSED(aPeripheral)
+ if (!notifier) {
+ // Detached, no need to continue ...
+ return;
+ }
+
QT_BT_MAC_AUTORELEASEPOOL;
using namespace OSXBluetooth;
if (error) {
- // Log the error using NSLog:
NSLog(@"%s failed with error %@", Q_FUNC_INFO, error);
// We can continue though ...
}
@@ -1402,6 +1439,11 @@ using namespace QT_NAMESPACE;
Q_ASSERT_X(peripheral, Q_FUNC_INFO, "invalid peripheral (nil)");
+ if (!notifier) {
+ // Detached ...
+ return;
+ }
+
QT_BT_MAC_AUTORELEASEPOOL;
using namespace OSXBluetooth;
@@ -1412,14 +1454,13 @@ using namespace QT_NAMESPACE;
const QLowEnergyHandle dHandle = descMap.key(descriptor);
if (error) {
- // NSLog to log the actual error ...
NSLog(@"%s failed with error %@", Q_FUNC_INFO, error);
if (!isDetailsDiscovery) {
if (dHandle && dHandle == currentReadHandle) {
currentReadHandle = 0;
requestPending = false;
- delegate->error(qtUuid, QLowEnergyService::DescriptorReadError);
+ emit notifier->CBManagerError(qtUuid, QLowEnergyService::DescriptorReadError);
[self performNextRequest];
}
return;
@@ -1459,7 +1500,7 @@ using namespace QT_NAMESPACE;
if (dHandle == currentReadHandle) {
currentReadHandle = 0;
requestPending = false;
- delegate->descriptorReadNotification(dHandle, qt_bytearray(static_cast<NSObject *>(descriptor.value)));
+ emit notifier->descriptorRead(dHandle, qt_bytearray(static_cast<NSObject *>(descriptor.value)));
[self performNextRequest];
}
}
@@ -1472,6 +1513,11 @@ using namespace QT_NAMESPACE;
Q_UNUSED(aPeripheral)
Q_UNUSED(characteristic)
+ if (!notifier) {
+ // Detached.
+ return;
+ }
+
// From docs:
//
// "This method is invoked only when your app calls the writeValue:forCharacteristic:type:
@@ -1485,8 +1531,6 @@ using namespace QT_NAMESPACE;
requestPending = false;
- Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
-
// Error or not, but the cached value has to be deleted ...
const QByteArray valueToReport(valuesToWrite.value(characteristic, QByteArray()));
@@ -1496,15 +1540,12 @@ using namespace QT_NAMESPACE;
}
if (error) {
- // Use NSLog to log the actual error:
NSLog(@"%s failed with error %@", Q_FUNC_INFO, error);
- delegate->error(qt_uuid(characteristic.service.UUID),
- QLowEnergyService::CharacteristicWriteError);
+ emit notifier->CBManagerError(qt_uuid(characteristic.service.UUID),
+ QLowEnergyService::CharacteristicWriteError);
} else {
- // Keys are unique.
const QLowEnergyHandle cHandle = charMap.key(characteristic);
- Q_ASSERT_X(cHandle, Q_FUNC_INFO, "invalid handle, not found in the characteristics map");
- delegate->characteristicWriteNotification(cHandle, valueToReport);
+ emit notifier->characteristicWritten(cHandle, valueToReport);
}
[self performNextRequest];
@@ -1516,7 +1557,10 @@ using namespace QT_NAMESPACE;
{
Q_UNUSED(aPeripheral)
- Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
+ if (!notifier) {
+ // Detached already.
+ return;
+ }
using namespace OSXBluetooth;
@@ -1524,23 +1568,20 @@ using namespace QT_NAMESPACE;
requestPending = false;
- using namespace OSXBluetooth;
-
// Error or not, a value (if any) must be removed.
const QByteArray valueToReport(valuesToWrite.value(descriptor, QByteArray()));
if (!valuesToWrite.remove(descriptor))
qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "no updated value found";
if (error) {
- // NSLog to log the actual NSError:
NSLog(@"%s failed with error %@", Q_FUNC_INFO, error);
- delegate->error(qt_uuid(descriptor.characteristic.service.UUID),
- QLowEnergyService::DescriptorWriteError);
+ emit notifier->CBManagerError(qt_uuid(descriptor.characteristic.service.UUID),
+ QLowEnergyService::DescriptorWriteError);
} else {
const QLowEnergyHandle dHandle = descMap.key(descriptor);
Q_ASSERT_X(dHandle, Q_FUNC_INFO,
"descriptor not found in the descriptors map");
- delegate->descriptorWriteNotification(dHandle, valueToReport);
+ emit notifier->descriptorWritten(dHandle, valueToReport);
}
[self performNextRequest];
@@ -1552,40 +1593,42 @@ using namespace QT_NAMESPACE;
{
Q_UNUSED(aPeripheral)
+ if (!notifier)
+ return;
+
using namespace OSXBluetooth;
QT_BT_MAC_AUTORELEASEPOOL;
requestPending = false;
- Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (nil)");
-
const QBluetoothUuid qtUuid(QBluetoothUuid::ClientCharacteristicConfiguration);
CBDescriptor *const descriptor = [self descriptor:qtUuid forCharacteristic:characteristic];
const QByteArray valueToReport(valuesToWrite.value(descriptor, QByteArray()));
const int nRemoved = valuesToWrite.remove(descriptor);
if (error) {
- // NSLog to log the actual NSError:
NSLog(@"%s failed with error %@", Q_FUNC_INFO, error);
- delegate->error(qt_uuid(characteristic.service.UUID),
- // In Qt's API it's a descriptor write actually.
- QLowEnergyService::DescriptorWriteError);
- } else {
- if (nRemoved) {
- const QLowEnergyHandle dHandle = descMap.key(descriptor);
- delegate->descriptorWriteNotification(dHandle, valueToReport);
- } else {
- /*
- qCWarning(QT_BT_OSX) << Q_FUNC_INFO << ": notification value set to "
- << int(characteristic.isNotifying)
- << " but no client characteristic configuration descriptor found"
- " or no previous writeDescriptor request found";
- */
- }
+ // In Qt's API it's a descriptor write actually.
+ emit notifier->CBManagerError(qt_uuid(characteristic.service.UUID),
+ QLowEnergyService::DescriptorWriteError);
+ } else if (nRemoved) {
+ const QLowEnergyHandle dHandle = descMap.key(descriptor);
+ emit notifier->descriptorWritten(dHandle, valueToReport);
}
[self performNextRequest];
}
+- (void)detach
+{
+ if (notifier) {
+ notifier->disconnect();
+ notifier->deleteLater();
+ notifier = 0;
+ }
+
+ [self disconnectFromDevice];
+}
+
@end
diff --git a/src/bluetooth/osx/osxbtcentralmanager_p.h b/src/bluetooth/osx/osxbtcentralmanager_p.h
index e8d7d234..5453822f 100644
--- a/src/bluetooth/osx/osxbtcentralmanager_p.h
+++ b/src/bluetooth/osx/osxbtcentralmanager_p.h
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -34,6 +40,17 @@
#ifndef OSXBTCENTRALMANAGER_P_H
#define OSXBTCENTRALMANAGER_P_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include "qlowenergycontroller.h"
#include "qlowenergyservice.h"
#include "qbluetoothuuid.h"
@@ -58,41 +75,7 @@ class QLowEnergyServicePrivate;
namespace OSXBluetooth {
-class CentralManagerDelegate
-{
-public:
- typedef QT_MANGLE_NAMESPACE(OSXBTCentralManager) ObjCCentralManager;
- typedef ObjCStrongReference<NSArray> LEServices;
- typedef QSharedPointer<QLowEnergyServicePrivate> LEService;
- typedef ObjCStrongReference<CBCharacteristic> LECharacteristic;
-
- virtual ~CentralManagerDelegate();
-
- virtual void LEnotSupported() = 0;
- virtual void connectSuccess() = 0;
- virtual void serviceDiscoveryFinished(LEServices services) = 0;
- virtual void serviceDetailsDiscoveryFinished(LEService service) = 0;
- virtual void characteristicReadNotification(QLowEnergyHandle charHandle,
- const QByteArray &value) = 0;
- virtual void characteristicWriteNotification(QLowEnergyHandle charHandle,
- const QByteArray &value) = 0;
- virtual void characteristicUpdateNotification(QLowEnergyHandle charHandle,
- const QByteArray &value) = 0;
- virtual void descriptorReadNotification(QLowEnergyHandle descHandle,
- const QByteArray &value) = 0;
- virtual void descriptorWriteNotification(QLowEnergyHandle descHandle,
- const QByteArray &value) = 0;
- virtual void disconnected() = 0;
-
- // General errors.
- virtual void error(QLowEnergyController::Error error) = 0;
- // Service related errors.
- virtual void error(const QBluetoothUuid &serviceUuid,
- QLowEnergyController::Error error) = 0;
- // Characteristics/descriptors related errors.
- virtual void error(const QBluetoothUuid &serviceUuid,
- QLowEnergyService::ServiceError error) = 0;
-};
+class LECBManagerNotifier;
enum CentralManagerState
{
@@ -115,8 +98,8 @@ typedef QHash<QLowEnergyHandle, CBService *> ServiceHash;
typedef QHash<QLowEnergyHandle, CBCharacteristic *> CharHash;
typedef QHash<QLowEnergyHandle, CBDescriptor *> DescHash;
-// Descriptor/charactesirsti read/write requests
-// - we have to serialize 'concurrent' write requests.
+// Descriptor/charactesirstic read/write requests
+// - we have to serialize 'concurrent' requests.
struct LERequest {
enum RequestType {
CharRead,
@@ -154,14 +137,14 @@ QT_END_NAMESPACE
@interface QT_MANGLE_NAMESPACE(OSXBTCentralManager) : NSObject<CBCentralManagerDelegate, CBPeripheralDelegate>
{
+@private
CBCentralManager *manager;
QT_PREPEND_NAMESPACE(OSXBluetooth)::CentralManagerState managerState;
bool disconnectPending;
QT_PREPEND_NAMESPACE(QBluetoothUuid) deviceUuid;
- CBPeripheral *peripheral;
- QT_PREPEND_NAMESPACE(OSXBluetooth)::CentralManagerDelegate *delegate;
+ QT_PREPEND_NAMESPACE(OSXBluetooth)::LECBManagerNotifier *notifier;
// Quite a verbose service discovery machinery
// (a "graph traversal").
@@ -186,32 +169,43 @@ QT_END_NAMESPACE
QT_PREPEND_NAMESPACE(QLowEnergyHandle) currentReadHandle;
QT_PREPEND_NAMESPACE(OSXBluetooth)::ValueHash valuesToWrite;
+@public
+ CBPeripheral *peripheral;
}
-- (id)initWithDelegate:(QT_PREPEND_NAMESPACE(OSXBluetooth)::CentralManagerDelegate *)aDelegate;
+- (id)initWith:(QT_PREPEND_NAMESPACE(OSXBluetooth)::LECBManagerNotifier *)notifier;
- (void)dealloc;
-- (QT_PREPEND_NAMESPACE(QLowEnergyController)::Error)
- connectToDevice:(const QT_PREPEND_NAMESPACE(QBluetoothUuid) &)aDeviceUuid;
+// 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;
- (void)disconnectFromDevice;
- (void)discoverServices;
-- (bool)discoverServiceDetails:(const QT_PREPEND_NAMESPACE(QBluetoothUuid) &)serviceUuid;
+- (void)discoverServiceDetails:(const QT_PREPEND_NAMESPACE(QBluetoothUuid) &)serviceUuid;
-- (bool)setNotifyValue:(const QT_PREPEND_NAMESPACE(QByteArray) &)value
- forCharacteristic:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))charHandle;
+- (void)setNotifyValue:(const QT_PREPEND_NAMESPACE(QByteArray) &)value
+ forCharacteristic:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))charHandle
+ onService:(const QT_PREPEND_NAMESPACE(QBluetoothUuid) &)serviceUuid;
-- (bool)readCharacteristic:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))charHandle;
+- (void)readCharacteristic:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))charHandle
+ onService:(const QT_PREPEND_NAMESPACE(QBluetoothUuid) &)serviceUuid;
-- (bool)write:(const QT_PREPEND_NAMESPACE(QByteArray) &)value
+- (void)write:(const QT_PREPEND_NAMESPACE(QByteArray) &)value
charHandle:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))charHandle
+ onService:(const QT_PREPEND_NAMESPACE(QBluetoothUuid) &)serviceUuid
withResponse:(bool)writeWithResponse;
-- (bool)readDescriptor:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))descHandle;
+- (void)readDescriptor:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))descHandle
+ onService:(const QT_PREPEND_NAMESPACE(QBluetoothUuid) &)serviceUuid;
+
+- (void)write:(const QT_PREPEND_NAMESPACE(QByteArray) &)value
+ descHandle:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))descHandle
+ onService:(const QT_PREPEND_NAMESPACE(QBluetoothUuid) &)serviceUuid;
+
+- (void)detach;
-- (bool)write:(const QT_PREPEND_NAMESPACE(QByteArray) &)value
- descHandle:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))descHandle;
@end
#endif
diff --git a/src/bluetooth/osx/osxbtchanneldelegate.mm b/src/bluetooth/osx/osxbtchanneldelegate.mm
index 2214168b..822e9d4e 100644
--- a/src/bluetooth/osx/osxbtchanneldelegate.mm
+++ b/src/bluetooth/osx/osxbtchanneldelegate.mm
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/bluetooth/osx/osxbtchanneldelegate_p.h b/src/bluetooth/osx/osxbtchanneldelegate_p.h
index edcf6950..1102e935 100644
--- a/src/bluetooth/osx/osxbtchanneldelegate_p.h
+++ b/src/bluetooth/osx/osxbtchanneldelegate_p.h
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -34,6 +40,17 @@
#ifndef OSXBTCHANNELDELEGATE_P_H
#define OSXBTCHANNELDELEGATE_P_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include <QtCore/qglobal.h>
#include <IOKit/IOReturn.h>
diff --git a/src/bluetooth/osx/osxbtconnectionmonitor.mm b/src/bluetooth/osx/osxbtconnectionmonitor.mm
index 8228d135..6cbe9b01 100644
--- a/src/bluetooth/osx/osxbtconnectionmonitor.mm
+++ b/src/bluetooth/osx/osxbtconnectionmonitor.mm
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/bluetooth/osx/osxbtconnectionmonitor_p.h b/src/bluetooth/osx/osxbtconnectionmonitor_p.h
index 4ad28885..7f95db87 100644
--- a/src/bluetooth/osx/osxbtconnectionmonitor_p.h
+++ b/src/bluetooth/osx/osxbtconnectionmonitor_p.h
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -34,6 +40,17 @@
#ifndef OSXBTCONNECTIONMONITOR_P_H
#define OSXBTCONNECTIONMONITOR_P_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include "qbluetoothaddress.h"
#include <QtCore/qglobal.h>
diff --git a/src/bluetooth/osx/osxbtdeviceinquiry.mm b/src/bluetooth/osx/osxbtdeviceinquiry.mm
index 949b035a..d38110c7 100644
--- a/src/bluetooth/osx/osxbtdeviceinquiry.mm
+++ b/src/bluetooth/osx/osxbtdeviceinquiry.mm
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/bluetooth/osx/osxbtdeviceinquiry_p.h b/src/bluetooth/osx/osxbtdeviceinquiry_p.h
index 4397b45d..13227839 100644
--- a/src/bluetooth/osx/osxbtdeviceinquiry_p.h
+++ b/src/bluetooth/osx/osxbtdeviceinquiry_p.h
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -34,6 +40,17 @@
#ifndef OSXBTDEVICEINQUIRY_P_H
#define OSXBTDEVICEINQUIRY_P_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include <QtCore/qglobal.h>
// We have to import objc code (it does not have inclusion guards).
diff --git a/src/bluetooth/osx/osxbtdevicepair.mm b/src/bluetooth/osx/osxbtdevicepair.mm
index 41c20b8b..737a312f 100644
--- a/src/bluetooth/osx/osxbtdevicepair.mm
+++ b/src/bluetooth/osx/osxbtdevicepair.mm
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/bluetooth/osx/osxbtdevicepair_p.h b/src/bluetooth/osx/osxbtdevicepair_p.h
index a2aa2de0..35709734 100644
--- a/src/bluetooth/osx/osxbtdevicepair_p.h
+++ b/src/bluetooth/osx/osxbtdevicepair_p.h
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -34,6 +40,17 @@
#ifndef OSXBTDEVICEPAIR_P_H
#define OSXBTDEVICEPAIR_P_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include "qbluetoothaddress.h"
#include "osxbtutility_p.h"
diff --git a/src/bluetooth/osx/osxbtl2capchannel.mm b/src/bluetooth/osx/osxbtl2capchannel.mm
index 93e15012..2d596654 100644
--- a/src/bluetooth/osx/osxbtl2capchannel.mm
+++ b/src/bluetooth/osx/osxbtl2capchannel.mm
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/bluetooth/osx/osxbtl2capchannel_p.h b/src/bluetooth/osx/osxbtl2capchannel_p.h
index 9736bd1d..7bc88102 100644
--- a/src/bluetooth/osx/osxbtl2capchannel_p.h
+++ b/src/bluetooth/osx/osxbtl2capchannel_p.h
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -34,6 +40,17 @@
#ifndef OSXBTL2CAPCHANNEL_P_H
#define OSXBTL2CAPCHANNEL_P_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include <QtCore/qglobal.h>
#include <Foundation/Foundation.h>
diff --git a/src/bluetooth/osx/osxbtledeviceinquiry.mm b/src/bluetooth/osx/osxbtledeviceinquiry.mm
index af304d8d..88370fa6 100644
--- a/src/bluetooth/osx/osxbtledeviceinquiry.mm
+++ b/src/bluetooth/osx/osxbtledeviceinquiry.mm
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -46,10 +52,6 @@ QT_BEGIN_NAMESPACE
namespace OSXBluetooth {
-LEDeviceInquiryDelegate::~LEDeviceInquiryDelegate()
-{
-}
-
#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_9, __IPHONE_6_0)
QBluetoothUuid qt_uuid(NSUUID *nsUuid)
@@ -107,32 +109,19 @@ using namespace QT_NAMESPACE;
#endif
-@interface QT_MANGLE_NAMESPACE(OSXBTLEDeviceInquiry) (PrivateAPI) <CBCentralManagerDelegate, CBPeripheralDelegate>
-// "Timeout" callback to stop a scan.
+@interface QT_MANGLE_NAMESPACE(OSXBTLEDeviceInquiry) (PrivateAPI) <CBCentralManagerDelegate>
- (void)stopScan;
+- (void)handlePoweredOff;
@end
@implementation QT_MANGLE_NAMESPACE(OSXBTLEDeviceInquiry)
-+ (int)inquiryLength
-{
- // There is no default timeout,
- // scan does not stop if not asked.
- // Return in milliseconds
- return 10 * 1000;
-}
-
-- (id)initWithDelegate:(OSXBluetooth::LEDeviceInquiryDelegate *)aDelegate
+- (id)init
{
- Q_ASSERT_X(aDelegate, Q_FUNC_INFO, "invalid delegate (null)");
-
if (self = [super init]) {
- delegate = aDelegate;
- peripherals = [[NSMutableDictionary alloc] init];
- manager = nil;
- pendingStart = false;
- cancelled = false;
- isActive = false;
+ uuids.reset([[NSMutableSet alloc] init]);
+ internalState = InquiryStarting;
+ state.store(int(internalState));
}
return self;
@@ -140,115 +129,137 @@ using namespace QT_NAMESPACE;
- (void)dealloc
{
- [NSObject cancelPreviousPerformRequestsWithTarget:self];
-
if (manager) {
[manager setDelegate:nil];
- if (isActive)
+ if (internalState == InquiryActive)
[manager stopScan];
- [manager release];
}
- [peripherals release];
[super dealloc];
}
- (void)stopScan
{
- // Scan's timeout.
- Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
- Q_ASSERT_X(manager, Q_FUNC_INFO, "invalid central (nil)");
- Q_ASSERT_X(!pendingStart, Q_FUNC_INFO, "invalid state");
- Q_ASSERT_X(!cancelled, Q_FUNC_INFO, "invalid state");
- Q_ASSERT_X(isActive, Q_FUNC_INFO, "invalid state");
-
- [manager setDelegate:nil];
- [manager stopScan];
- isActive = false;
+ // Scan's "timeout" - we consider LE device
+ // discovery finished.
+ using namespace OSXBluetooth;
- delegate->LEdeviceInquiryFinished();
+ if (internalState == InquiryActive) {
+ if (scanTimer.elapsed() >= qt_LE_deviceInquiryLength() * 1000) {
+ // We indeed stop now:
+ [manager stopScan];
+ [manager setDelegate:nil];
+ internalState = InquiryFinished;
+ state.store(int(internalState));
+ } else {
+ dispatch_queue_t leQueue(qt_LE_queue());
+ Q_ASSERT(leQueue);
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
+ int64_t(qt_LE_deviceInquiryLength() / 100. * NSEC_PER_SEC)),
+ leQueue,
+ ^{
+ [self stopScan];
+ });
+ }
+ }
}
-- (bool)start
+- (void)handlePoweredOff
{
- Q_ASSERT_X(![self isActive], Q_FUNC_INFO, "LE device scan is already active");
- Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
-
- if (!peripherals) {
- qCCritical(QT_BT_OSX) << Q_FUNC_INFO << "internal error";
- return false;
- }
+ // This is interesting on iOS only, where
+ // the system shows an alert asking to enable
+ // Bluetooth in the 'Settings' app. If not done yet (after 30
+ // seconds) - we consider it an error.
+ if (internalState == InquiryStarting) {
+ if (errorTimer.elapsed() >= 30000) {
+ [manager setDelegate:nil];
+ internalState = ErrorPoweredOff;
+ state.store(int(internalState));
+ } else {
+ dispatch_queue_t leQueue(OSXBluetooth::qt_LE_queue());
+ Q_ASSERT(leQueue);
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
+ (int64_t)(30 / 100. * NSEC_PER_SEC)),
+ leQueue,
+ ^{
+ [self handlePoweredOff];
+ });
- cancelled = false;
- [peripherals removeAllObjects];
-
- if (manager) {
- // We can never be here, if status was not updated yet.
- [manager setDelegate:nil];
- [manager release];
+ }
}
+}
- startTime = QTime();
- pendingStart = true;
- manager = [CBCentralManager alloc];
- manager = [manager initWithDelegate:self queue:nil];
- if (!manager) {
- qCCritical(QT_BT_OSX) << Q_FUNC_INFO << "failed to create a central manager";
- return false;
- }
+- (void)start
+{
+ dispatch_queue_t leQueue(OSXBluetooth::qt_LE_queue());
- return true;
+ Q_ASSERT(leQueue);
+ manager.reset([[CBCentralManager alloc] initWithDelegate:self queue:leQueue]);
}
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
- Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
+ if (central != manager)
+ return;
- if (cancelled) {
- Q_ASSERT_X(!isActive, Q_FUNC_INFO, "isActive is true");
- pendingStart = false;
- delegate->LEdeviceInquiryFinished();
+ if (internalState != InquiryActive && internalState != InquiryStarting)
return;
- }
- const CBCentralManagerState state = central.state;
- if (state == CBCentralManagerStatePoweredOn) {
- if (pendingStart) {
- pendingStart = false;
- isActive = true;
-#ifndef Q_OS_OSX
- const NSTimeInterval timeout([QT_MANGLE_NAMESPACE(OSXBTLEDeviceInquiry) inquiryLength] / 1000);
- Q_ASSERT_X(timeout > 0., Q_FUNC_INFO, "invalid scan timeout");
- [self performSelector:@selector(stopScan) withObject:nil afterDelay:timeout];
-#endif
- startTime = QTime::currentTime();
+ using namespace OSXBluetooth;
+
+ dispatch_queue_t leQueue(qt_LE_queue());
+ Q_ASSERT(leQueue);
+
+ const CBCentralManagerState cbState(central.state);
+ if (cbState == CBCentralManagerStatePoweredOn) {
+ if (internalState == InquiryStarting) {
+ internalState = InquiryActive;
+ // Scan time is actually 10 seconds. Having a block with such delay can prevent
+ // 'self' from being deleted in time, which is not good. So we split this
+ // 10 s. timeout into smaller 'chunks'.
+ scanTimer.start();
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
+ int64_t(qt_LE_deviceInquiryLength() / 100. * NSEC_PER_SEC)),
+ leQueue,
+ ^{
+ [self stopScan];
+ });
[manager scanForPeripheralsWithServices:nil options:nil];
} // Else we ignore.
} else if (state == CBCentralManagerStateUnsupported || state == CBCentralManagerStateUnauthorized) {
- if (pendingStart) {
- pendingStart = false;
- delegate->LEnotSupported();
- } else if (isActive) {
- // It's not clear if this thing can happen at all.
- // We had LE supported and now .. not anymore?
- // Report as an error.
- [NSObject cancelPreviousPerformRequestsWithTarget:self];
- isActive = false;
+ if (internalState == InquiryActive) {
[manager stopScan];
- delegate->LEdeviceInquiryError(QBluetoothDeviceDiscoveryAgent::PoweredOffError);
+ // Not sure how this is possible at all, probably, can never happen.
+ internalState = ErrorPoweredOff;
+ } else {
+ internalState = ErrorLENotSupported;
}
- } else if (state == CBCentralManagerStatePoweredOff) {
- if (pendingStart) {
- pendingStart = false;
- delegate->LEnotSupported();
- } else if (isActive) {
- // We were able to start (isActive == true), so we had
- // powered ON and now the adapter is OFF.
- [NSObject cancelPreviousPerformRequestsWithTarget:self];
- isActive = false;
+
+ [manager setDelegate:nil];
+ } else if (cbState == CBCentralManagerStatePoweredOff) {
+ if (internalState == InquiryStarting) {
+#ifndef Q_OS_OSX
+ // On iOS a user can see at this point an alert asking to enable
+ // Bluetooth in the "Settings" app. If a user does,
+ // we'll receive 'PoweredOn' state update later.
+ // No change in state. Wait for 30 seconds (we split it into 'chunks' not
+ // to retain 'self' for too long ) ...
+ errorTimer.start();
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
+ (int64_t)(30 / 100. * NSEC_PER_SEC)),
+ leQueue,
+ ^{
+ [self handlePoweredOff];
+ });
+ return;
+#endif
+ internalState = ErrorPoweredOff;
+ } else {
+ internalState = ErrorPoweredOff;
[manager stopScan];
- delegate->LEdeviceInquiryError(QBluetoothDeviceDiscoveryAgent::PoweredOffError);
- } // Else we ignore.
+ }
+
+ [manager setDelegate:nil];
} else {
// The following two states we ignore (from Apple's docs):
//"
@@ -259,78 +270,102 @@ using namespace QT_NAMESPACE;
// -CBCentralManagerStateResetting
// The connection with the system service was momentarily
// lost; an update is imminent. "
- //
- // TODO: check if "is imminent" means UpdateState will
- // be called again with something more reasonable.
+ // Wait for this imminent update.
}
+
+ state.store(int(internalState));
}
- (void)stop
{
- [NSObject cancelPreviousPerformRequestsWithTarget:self];
-
- if (pendingStart || cancelled) {
- // We have to wait for a status update.
- cancelled = true;
- return;
- }
-
- if (isActive) {
+ if (internalState == InquiryActive)
[manager stopScan];
- isActive = false;
- delegate->LEdeviceInquiryFinished();
- }
+
+ [manager setDelegate:nil];
+ internalState = InquiryCancelled;
+ state.store(int(internalState));
}
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
- Q_UNUSED(central)
- Q_UNUSED(advertisementData)
+ Q_UNUSED(advertisementData);
using namespace OSXBluetooth;
- if (!isActive)
+ if (central != manager)
+ return;
+
+ if (internalState != InquiryActive)
return;
- Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
+ QBluetoothUuid deviceUuid;
-#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_9, __IPHONE_6_0)
- if (QSysInfo::MacintoshVersion >= qt_OS_limit(QSysInfo::MV_10_9, QSysInfo::MV_IOS_6_0)) {
+#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_9, __IPHONE_7_0)
+ if (QSysInfo::MacintoshVersion >= qt_OS_limit(QSysInfo::MV_10_9, QSysInfo::MV_IOS_7_0)) {
if (!peripheral.identifier) {
qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "peripheral without NSUUID";
return;
}
- if (![peripherals objectForKey:peripheral.identifier]) {
- [peripherals setObject:peripheral forKey:peripheral.identifier];
- const QBluetoothUuid deviceUuid(OSXBluetooth::qt_uuid(peripheral.identifier));
- delegate->LEdeviceFound(peripheral, deviceUuid, advertisementData, RSSI);
+ if ([uuids containsObject:peripheral.identifier]) {
+ // We already know this peripheral ...
+ return;
}
- return;
+
+ [uuids addObject:peripheral.identifier];
+ deviceUuid = OSXBluetooth::qt_uuid(peripheral.identifier);
}
#endif
- if (!peripheral.UUID) {
- qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "peripheral without UUID";
- return;
+ // Either SDK or the target is below 10.9/7.0:
+ // The property UUID was finally removed in iOS 9, we have
+ // to avoid compilation errors ...
+ if (deviceUuid.isNull()) {
+ CFUUIDRef cfUUID = Q_NULLPTR;
+
+ if ([peripheral respondsToSelector:@selector(UUID)]) {
+ // This will require a bridged cast if we switch to ARC ...
+ cfUUID = reinterpret_cast<CFUUIDRef>([peripheral performSelector:@selector(UUID)]);
+ }
+
+ if (!cfUUID) {
+ qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "peripheral without CFUUID";
+ return;
+ }
+
+ StringStrongReference key(uuid_as_nsstring(cfUUID));
+ if ([uuids containsObject:key.data()])
+ return; // We've seen this peripheral before ...
+ [uuids addObject:key.data()];
+ deviceUuid = OSXBluetooth::qt_uuid(cfUUID);
}
- StringStrongReference key(uuid_as_nsstring(peripheral.UUID));
- if (![peripherals objectForKey:key.data()]) {
- [peripherals setObject:peripheral forKey:key.data()];
- const QBluetoothUuid deviceUuid(OSXBluetooth::qt_uuid(peripheral.UUID));
- delegate->LEdeviceFound(peripheral, deviceUuid, advertisementData, RSSI);
+ if (deviceUuid.isNull()) {
+ qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "no way to address peripheral, QBluetoothUuid is null";
+ return;
}
+
+ QString name;
+ if (peripheral.name)
+ name = QString::fromNSString(peripheral.name);
+
+ // TODO: fix 'classOfDevice' (0 for now).
+ QBluetoothDeviceInfo newDeviceInfo(deviceUuid, name, 0);
+ if (RSSI)
+ newDeviceInfo.setRssi([RSSI shortValue]);
+ // CoreBluetooth scans only for LE devices.
+ newDeviceInfo.setCoreConfigurations(QBluetoothDeviceInfo::LowEnergyCoreConfiguration);
+ devices.append(newDeviceInfo);
}
-- (bool)isActive
+- (LEInquiryState) inquiryState
{
- return pendingStart || isActive;
+ return LEInquiryState(state.load());
}
-- (const QTime&)startTime
+- (const QList<QBluetoothDeviceInfo> &)discoveredDevices
{
- return startTime;
+ return devices;
}
@end
diff --git a/src/bluetooth/osx/osxbtledeviceinquiry_p.h b/src/bluetooth/osx/osxbtledeviceinquiry_p.h
index 7e6d0c8f..24bf181e 100644
--- a/src/bluetooth/osx/osxbtledeviceinquiry_p.h
+++ b/src/bluetooth/osx/osxbtledeviceinquiry_p.h
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -34,77 +40,71 @@
#ifndef OSXBTLEDEVICEINQUIRY_P_H
#define OSXBTLEDEVICEINQUIRY_P_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include "qbluetoothdevicediscoveryagent.h"
+#include "qbluetoothdeviceinfo.h"
+#include "osxbtutility_p.h"
-#include <QtCore/qdatetime.h>
+#include <QtCore/qelapsedtimer.h>
#include <QtCore/qglobal.h>
+#include <QtCore/qatomic.h>
#include <QtCore/qlist.h>
#include <Foundation/Foundation.h>
-@class QT_MANGLE_NAMESPACE(OSXBTLEDeviceInquiry);
-
@class CBCentralManager;
@class CBPeripheral;
QT_BEGIN_NAMESPACE
-class QBluetoothDeviceInfo;
class QBluetoothUuid;
-namespace OSXBluetooth {
+QT_END_NAMESPACE
-class LEDeviceInquiryDelegate
+enum LEInquiryState
{
-public:
- typedef QT_MANGLE_NAMESPACE(OSXBTLEDeviceInquiry) LEDeviceInquiryObjC;
-
- virtual ~LEDeviceInquiryDelegate();
-
- // At the moment the only error we're reporting is PoweredOffError!
- virtual void LEdeviceInquiryError(QBluetoothDeviceDiscoveryAgent::Error error) = 0;
-
- virtual void LEnotSupported() = 0;
- virtual void LEdeviceFound(CBPeripheral *peripheral, const QBluetoothUuid &uuid,
- NSDictionary *advertisementData, NSNumber *RSSI) = 0;
- virtual void LEdeviceInquiryFinished() = 0;
+ InquiryStarting,
+ InquiryActive,
+ InquiryFinished,
+ InquiryCancelled,
+ ErrorPoweredOff,
+ ErrorLENotSupported
};
-}
+@interface QT_MANGLE_NAMESPACE(OSXBTLEDeviceInquiry) : NSObject
+{
+ QT_PREPEND_NAMESPACE(OSXBluetooth)::ObjCScopedPointer<NSMutableSet> uuids;
+ QT_PREPEND_NAMESPACE(OSXBluetooth)::ObjCScopedPointer<CBCentralManager> manager;
-QT_END_NAMESPACE
+ QList<QBluetoothDeviceInfo> devices;
-// Bluetooth Low Energy scan for iOS and OS X.
+ LEInquiryState internalState;
+ QT_PREPEND_NAMESPACE(QAtomicInt) state;
-@interface QT_MANGLE_NAMESPACE(OSXBTLEDeviceInquiry) : NSObject
-{// Protocols are adopted in the mm file.
- QT_PREPEND_NAMESPACE(OSXBluetooth)::LEDeviceInquiryDelegate *delegate;
-
- // TODO: scoped pointers/shared pointers?
- NSMutableDictionary *peripherals; // Found devices.
- CBCentralManager *manager;
-
- // pending - waiting for a status update first.
- bool pendingStart;
- bool cancelled;
- // scan actually started.
- bool isActive;
- QTime startTime;
+ // Timers to check if we can execute delayed callbacks:
+ QT_PREPEND_NAMESPACE(QElapsedTimer) errorTimer;
+ QT_PREPEND_NAMESPACE(QElapsedTimer) scanTimer;
}
-// Inquiry length in milliseconds.
-+ (int)inquiryLength;
-
-- (id)initWithDelegate:(QT_PREPEND_NAMESPACE(OSXBluetooth)::LEDeviceInquiryDelegate *)aDelegate;
+- (id)init;
- (void)dealloc;
-// Actual scan can be delayed - we have to wait for a status update first.
-- (bool)start;
-// Stop can be delayed - if we're waiting for a status update.
+// IMPORTANT: both 'start' and 'stop' are to be executed on the "Qt's LE queue".
+- (void)start;
- (void)stop;
-- (bool)isActive;
-- (const QTime &)startTime;
+- (LEInquiryState)inquiryState;
+- (const QList<QBluetoothDeviceInfo> &)discoveredDevices;
@end
diff --git a/src/bluetooth/osx/osxbtnotifier.cpp b/src/bluetooth/osx/osxbtnotifier.cpp
new file mode 100644
index 00000000..0e0343cf
--- /dev/null
+++ b/src/bluetooth/osx/osxbtnotifier.cpp
@@ -0,0 +1 @@
+#include "osxbtnotifier_p.h"
diff --git a/src/bluetooth/osx/osxbtnotifier_p.h b/src/bluetooth/osx/osxbtnotifier_p.h
new file mode 100644
index 00000000..3059e2d3
--- /dev/null
+++ b/src/bluetooth/osx/osxbtnotifier_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OSXBTNOTIFIER_P_H
+#define OSXBTNOTIFIER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#include "qlowenergycontroller.h"
+#include "qbluetoothuuid.h"
+#include "qbluetooth.h"
+
+#include <QtCore/qsharedpointer.h>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qglobal.h>
+#include <QtCore/qobject.h>
+
+QT_BEGIN_NAMESPACE
+
+class QLowEnergyServicePrivate;
+
+namespace OSXBluetooth
+{
+
+class LECBManagerNotifier : public QObject
+{
+ Q_OBJECT
+
+Q_SIGNALS:
+ void connected();
+ void disconnected();
+
+ void serviceDiscoveryFinished();
+ void serviceDetailsDiscoveryFinished(QSharedPointer<QLowEnergyServicePrivate> service);
+ void characteristicRead(QLowEnergyHandle charHandle, const QByteArray &value);
+ void characteristicWritten(QLowEnergyHandle charHandle, const QByteArray &value);
+ void characteristicUpdated(QLowEnergyHandle charHandle, const QByteArray &value);
+ void descriptorRead(QLowEnergyHandle descHandle, const QByteArray &value);
+ void descriptorWritten(QLowEnergyHandle descHandle, const QByteArray &value);
+
+ void LEnotSupported();
+ void CBManagerError(QLowEnergyController::Error error);
+ void CBManagerError(const QBluetoothUuid &serviceUuid, QLowEnergyController::Error error);
+ void CBManagerError(const QBluetoothUuid &serviceUuid, QLowEnergyService::ServiceError error);
+
+};
+
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/bluetooth/osx/osxbtobexsession.mm b/src/bluetooth/osx/osxbtobexsession.mm
index f48da22d..4e4013f3 100644
--- a/src/bluetooth/osx/osxbtobexsession.mm
+++ b/src/bluetooth/osx/osxbtobexsession.mm
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/bluetooth/osx/osxbtobexsession_p.h b/src/bluetooth/osx/osxbtobexsession_p.h
index ac2699cf..dfb3d48a 100644
--- a/src/bluetooth/osx/osxbtobexsession_p.h
+++ b/src/bluetooth/osx/osxbtobexsession_p.h
@@ -1,36 +1,53 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include <QtCore/qvariant.h>
#include <QtCore/qglobal.h>
diff --git a/src/bluetooth/osx/osxbtperipheralmanager.mm b/src/bluetooth/osx/osxbtperipheralmanager.mm
new file mode 100644
index 00000000..4731fdd2
--- /dev/null
+++ b/src/bluetooth/osx/osxbtperipheralmanager.mm
@@ -0,0 +1,754 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+
+#include "qlowenergycharacteristicdata.h"
+#include "qlowenergydescriptordata.h"
+#include "osxbtperipheralmanager_p.h"
+#include "qlowenergyservicedata.h"
+#include "osxbtnotifier_p.h"
+#include "qbluetooth.h"
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qlist.h>
+
+#include <algorithm>
+#include <limits>
+#include <set>
+
+namespace
+{
+
+CBCharacteristicProperties cb_properties(const QLowEnergyCharacteristicData &data)
+{
+ // Direct 'mapping' is ok.
+ return CBCharacteristicProperties(int(data.properties()));
+}
+
+CBAttributePermissions cb_permissions(const QLowEnergyCharacteristicData &data)
+{
+ using QLEC = QLowEnergyCharacteristic;
+
+ const auto props = data.properties();
+ CBAttributePermissions cbFlags = {};
+
+ if ((props & QLEC::Write) || (props & QLEC::WriteNoResponse)
+ || (props & QLEC::WriteSigned)) {
+ cbFlags = CBAttributePermissions(cbFlags | CBAttributePermissionsWriteable);
+ }
+
+ if (props & QLEC::Read)
+ cbFlags = CBAttributePermissions(cbFlags | CBAttributePermissionsReadable);
+
+ if (data.writeConstraints() & QBluetooth::AttEncryptionRequired)
+ cbFlags = CBAttributePermissions(cbFlags | CBAttributePermissionsWriteEncryptionRequired);
+
+ if (data.readConstraints() & QBluetooth::AttEncryptionRequired)
+ cbFlags = CBAttributePermissions(cbFlags | CBAttributePermissionsReadEncryptionRequired);
+
+ return cbFlags;
+}
+
+ObjCStrongReference<CBMutableCharacteristic> create_characteristic(const QLowEnergyCharacteristicData &data)
+{
+ const ObjCStrongReference<CBMutableCharacteristic> ch([[CBMutableCharacteristic alloc] initWithType:cb_uuid(data.uuid())
+ properties:cb_properties(data)
+ value:nil
+ permissions:cb_permissions(data)],
+ false /*do not retain*/);
+ return ch;
+}
+
+ObjCStrongReference<CBMutableDescriptor> create_descriptor(const QLowEnergyDescriptorData &data)
+{
+ // CoreBluetooth supports only:
+ /*
+ "That said, only two of these are currently supported when creating local,
+ mutable descriptors: the characteristic user description descriptor and
+ the characteristic format descriptor, represented by the CBUUID constants
+ CBUUIDCharacteristicUserDescriptionString and CBUUIDCharacteristicFormatString"
+ */
+
+ if (data.uuid() != QBluetoothUuid::CharacteristicUserDescription &&
+ data.uuid() != QBluetoothUuid::CharacteristicPresentationFormat) {
+ qCWarning(QT_BT_OSX) << "unsupported descriptor" << data.uuid();
+ return {};
+ }
+
+ QT_BT_MAC_AUTORELEASEPOOL
+
+ // Descriptors are immutable with CoreBluetooth, that's why we
+ // have to provide a value here and not able to change it later.
+ ObjCStrongReference<NSObject> value;
+ if (data.uuid() == QBluetoothUuid::CharacteristicUserDescription) {
+ const QString asQString(QString::fromUtf8(data.value()));
+ value.reset(asQString.toNSString());
+ } else {
+ const auto nsData = data_from_bytearray(data.value());
+ value.reset(nsData.data());
+ }
+
+ const ObjCStrongReference<CBMutableDescriptor> d([[CBMutableDescriptor alloc]
+ initWithType:cb_uuid(data.uuid())
+ value:value], false /*do not retain*/);
+ return d;
+}
+
+quint32 qt_countGATTEntries(const QLowEnergyServiceData &data)
+{
+ const auto maxu32 = std::numeric_limits<quint32>::max();
+ // + 1 for a service itself.
+ quint32 nEntries = 1 + quint32(data.includedServices().count());
+ for (const auto &ch : data.characteristics()) {
+ if (maxu32 - 2 < nEntries)
+ return {};
+ nEntries += 2;
+ if (maxu32 - ch.descriptors().count() < nEntries)
+ return {};
+ nEntries += ch.descriptors().count();
+ }
+
+ return nEntries;
+}
+
+}
+
+@interface QT_MANGLE_NAMESPACE(OSXBTPeripheralManager) (PrivateAPI)
+
+- (void)addConnectedCentral:(CBCentral *)central;
+- (void)removeConnectedCentral:(CBCentral *)central;
+- (CBService *)findIncludedService:(const QBluetoothUuid &)qtUUID;
+
+- (void)addIncludedServices:(const QLowEnergyServiceData &)data
+ to:(CBMutableService *)cbService
+ qtService:(QLowEnergyServicePrivate *)qtService;
+
+- (void)addCharacteristicsAndDescriptors:(const QLowEnergyServiceData &)data
+ to:(CBMutableService *)cbService
+ qtService:(QLowEnergyServicePrivate *)qtService;
+
+- (CBATTError)validateWriteRequest:(CBATTRequest *)request;
+
+@end
+
+@implementation QT_MANGLE_NAMESPACE(OSXBTPeripheralManager)
+
+- (id)initWith:(LECBManagerNotifier *)aNotifier
+{
+ if (self = [super init]) {
+ Q_ASSERT(aNotifier);
+ notifier = aNotifier;
+ state = PeripheralState::idle;
+ nextServiceToAdd = {};
+ connectedCentrals.reset([[NSMutableSet alloc] init]);
+ }
+
+ return self;
+}
+
+- (void)dealloc
+{
+ [self detach];
+ [super dealloc];
+}
+
+- (QSharedPointer<QLowEnergyServicePrivate>)addService:(const QLowEnergyServiceData &)data
+{
+ using QLES = QLowEnergyService;
+
+ const auto nEntries = qt_countGATTEntries(data);
+ if (!nEntries || nEntries > std::numeric_limits<QLowEnergyHandle>::max() - lastHandle) {
+ qCCritical(QT_BT_OSX) << "addService: not enough handles";
+ return {};
+ }
+
+ QT_BT_MAC_AUTORELEASEPOOL
+
+ const BOOL primary = data.type() == QLowEnergyServiceData::ServiceTypePrimary;
+ const auto cbUUID = cb_uuid(data.uuid());
+
+ const ObjCStrongReference<CBMutableService>
+ newCBService([[CBMutableService alloc] initWithType:cbUUID primary:primary],
+ false /*do not retain*/);
+
+ if (!newCBService) {
+ qCCritical(QT_BT_OSX) << "addService: failed to create CBMutableService";
+ return {};
+ }
+
+ auto newQtService = QSharedPointer<QLowEnergyServicePrivate>::create();
+ newQtService->state = QLowEnergyService::LocalService;
+ newQtService->uuid = data.uuid();
+ newQtService->type = primary ? QLES::PrimaryService : QLES::IncludedService;
+ newQtService->startHandle = ++lastHandle;
+ // Controller will be set by ... controller :)
+
+ [self addIncludedServices:data to:newCBService qtService:newQtService.data()];
+ [self addCharacteristicsAndDescriptors:data to:newCBService qtService:newQtService.data()];
+
+ services.push_back(newCBService);
+ serviceIndex[data.uuid()] = newCBService;
+
+ return newQtService;
+}
+
+- (void) setParameters:(const QLowEnergyAdvertisingParameters &)parameters
+ data:(const QLowEnergyAdvertisingData &)data
+ scanResponse:(const QLowEnergyAdvertisingData &)scanResponse
+{
+ Q_UNUSED(parameters)
+
+ // This is the last method we call on the controller's thread
+ // before starting advertising on the Qt's LE queue.
+ // From Apple's docs:
+ /*
+ - (void)startAdvertising:(NSDictionary *)advertisementData
+
+ Advertises peripheral manager data.
+
+ * advertisementData
+
+ - An optional dictionary containing the data you want to advertise.
+ The possible keys of an advertisementData dictionary are detailed in CBCentralManagerDelegate
+ Protocol Reference. That said, only two of the keys are supported for peripheral manager objects:
+ CBAdvertisementDataLocalNameKey and CBAdvertisementDataServiceUUIDsKey.
+ */
+
+ QT_BT_MAC_AUTORELEASEPOOL
+
+ advertisementData.reset([[NSMutableDictionary alloc] init]);
+ if (!advertisementData) {
+ qCWarning(QT_BT_OSX) << "setParameters: failed to allocate "
+ "NSMutableDictonary (advertisementData)";
+ return;
+ }
+
+ auto localName = scanResponse.localName();
+ if (!localName.size())
+ localName = data.localName();
+
+ if (localName.size()) {
+ [advertisementData setObject:localName.toNSString()
+ forKey:CBAdvertisementDataLocalNameKey];
+ }
+
+ if (!data.services().count() && !scanResponse.services().count())
+ return;
+
+ const ObjCScopedPointer<NSMutableArray> uuids([[NSMutableArray alloc] init]);
+ if (!uuids) {
+ qCWarning(QT_BT_OSX) << "setParameters: failed to allocate "
+ "NSMutableArray (services uuids)";
+ return;
+ }
+
+
+ for (const auto &qtUUID : data.services()) {
+ const auto cbUUID = cb_uuid(qtUUID);
+ if (cbUUID)
+ [uuids addObject:cbUUID];
+ }
+
+ for (const auto &qtUUID : scanResponse.services()) {
+ const auto cbUUID = cb_uuid(qtUUID);
+ if (cbUUID)
+ [uuids addObject:cbUUID];
+ }
+
+ if ([uuids count]) {
+ [advertisementData setObject:uuids
+ forKey:CBAdvertisementDataServiceUUIDsKey];
+ }
+}
+
+- (void)startAdvertising
+{
+ state = PeripheralState::waitingForPowerOn;
+ if (manager)
+ [manager setDelegate:nil];
+ manager.reset([[CBPeripheralManager alloc] initWithDelegate:self
+ queue:OSXBluetooth::qt_LE_queue()]);
+}
+
+- (void)stopAdvertising
+{
+ [manager stopAdvertising];
+ state = PeripheralState::idle;
+}
+
+- (void)detach
+{
+ if (notifier) {
+ notifier->disconnect();
+ notifier->deleteLater();
+ notifier = nullptr;
+ }
+
+ if (state == PeripheralState::advertising) {
+ [manager stopAdvertising];
+ [manager setDelegate:nil];
+ state = PeripheralState::idle;
+ }
+}
+
+- (void)write:(const QByteArray &)value
+ charHandle:(QLowEnergyHandle)charHandle
+{
+ if (!notifier)
+ return;
+
+ QT_BT_MAC_AUTORELEASEPOOL
+
+ if (!charMap.contains(charHandle)) {
+ emit notifier->CBManagerError(QLowEnergyController::UnknownError);
+ return;
+ }
+
+ const auto nsData = data_from_bytearray(value);
+ charValues[charHandle] = nsData;
+ updateQueue.push_back(UpdateRequest{charHandle, nsData});
+ [self sendUpdateRequests];
+}
+
+- (void) addServicesToPeripheral
+{
+ Q_ASSERT(manager);
+
+ if (nextServiceToAdd < services.size())
+ [manager addService:services[nextServiceToAdd++]];
+}
+
+// CBPeripheralManagerDelegate:
+
+- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral
+{
+ if (peripheral != manager || !notifier)
+ return;
+
+ if (peripheral.state == CBPeripheralManagerStatePoweredOn) {
+ // "Bluetooth is currently powered on and is available to use."
+ if (state == PeripheralState::waitingForPowerOn) {
+ [manager removeAllServices];
+ nextServiceToAdd = {};
+ state = PeripheralState::advertising;
+ [self addServicesToPeripheral];
+ }
+ return;
+ }
+
+ /*
+ "A state with a value lower than CBPeripheralManagerStatePoweredOn implies that
+ advertising has stopped and that any connected centrals have been disconnected."
+ */
+
+ [connectedCentrals removeAllObjects];
+
+ if (state == PeripheralState::advertising) {
+ state = PeripheralState::waitingForPowerOn;
+ } else if (state == PeripheralState::connected) {
+ state = PeripheralState::idle;
+ emit notifier->disconnected();
+ }
+
+ // The next four states are _below_ "powered off"; according to the docs:
+ /*
+ "In addition, the local database is cleared and all services must be
+ explicitly added again."
+ */
+
+ if (peripheral.state == CBPeripheralManagerStateUnauthorized ||
+ peripheral.state == CBPeripheralManagerStateUnsupported) {
+ emit notifier->LEnotSupported();
+ state = PeripheralState::idle;
+ }
+}
+
+- (void)peripheralManager:(CBPeripheralManager *)peripheral
+ willRestoreState:(NSDictionary *)dict
+{
+ Q_UNUSED(peripheral)
+ Q_UNUSED(dict)
+ // NOOP atm.
+}
+
+- (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral
+ error:(NSError *)error
+{
+ if (peripheral != manager || !notifier)
+ return;
+
+ if (error) {
+ NSLog(@"failed to start advertising, error: %@", error);
+ state = PeripheralState::idle;
+ emit notifier->CBManagerError(QLowEnergyController::AdvertisingError);
+ }
+}
+
+- (void)peripheralManager:(CBPeripheralManager *)peripheral
+ didAddService:(CBService *)service error:(NSError *)error
+{
+ Q_UNUSED(service)
+
+ if (peripheral != manager || !notifier)
+ return;
+
+ if (error) {
+ NSLog(@"failed to add a service, error: %@", error);
+ emit notifier->CBManagerError(QLowEnergyController::AdvertisingError);
+ state = PeripheralState::idle;
+ return;
+ }
+
+ if (nextServiceToAdd == services.size())
+ [manager startAdvertising:[advertisementData count] ? advertisementData.data() : nil];
+ else
+ [self addServicesToPeripheral];
+}
+
+- (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central
+ didSubscribeToCharacteristic:(CBCharacteristic *)characteristic
+{
+ Q_UNUSED(characteristic)
+
+ if (peripheral != manager || !notifier)
+ return;
+
+ [self addConnectedCentral:central];
+}
+
+- (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central
+ didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic
+{
+ Q_UNUSED(characteristic)
+
+ if (peripheral != manager || !notifier)
+ return;
+
+ [self removeConnectedCentral:central];
+}
+
+- (void)peripheralManager:(CBPeripheralManager *)peripheral
+ didReceiveReadRequest:(CBATTRequest *)request
+{
+ if (peripheral != manager || !notifier)
+ return;
+
+ QT_BT_MAC_AUTORELEASEPOOL
+
+ const auto handle = charMap.key(request.characteristic);
+ if (!handle || !charValues.contains(handle)) {
+ qCWarning(QT_BT_OSX) << "invalid read request, unknown characteristic";
+ [manager respondToRequest:request withResult:CBATTErrorInvalidHandle];
+ return;
+ }
+
+ const auto &value = charValues[handle];
+ if (request.offset > [value length]) {
+ qCWarning(QT_BT_OSX) << "invalid offset in a read request";
+ [manager respondToRequest:request withResult:CBATTErrorInvalidOffset];
+ return;
+ }
+
+ [self addConnectedCentral:request.central];
+
+ NSData *dataToSend = nil;
+ if (!request.offset) {
+ dataToSend = value;
+ } else {
+ dataToSend = [value subdataWithRange:
+ NSMakeRange(request.offset, [value length] - request.offset)];
+ }
+
+ request.value = dataToSend;
+ [manager respondToRequest:request withResult:CBATTErrorSuccess];
+}
+
+- (void)peripheralManager:(CBPeripheralManager *)peripheral
+ didReceiveWriteRequests:(NSArray *)requests
+{
+ QT_BT_MAC_AUTORELEASEPOOL
+
+ if (peripheral != manager || !notifier) {
+ // Detached already.
+ return;
+ }
+
+ // We first test if all requests are valid
+ // since CoreBluetooth requires "all or none"
+ // and respond only _once_ to the first one.
+ for (CBATTRequest *request in requests) {
+ const auto status = [self validateWriteRequest:request];
+ if (status != CBATTErrorSuccess) {
+ [manager respondToRequest:[requests objectAtIndex:0]
+ withResult:status];
+ return;
+ }
+ }
+
+ std::set<QLowEnergyHandle> updated;
+
+ for (CBATTRequest *request in requests) {
+ // Transition to 'connected' if needed.
+ [self addConnectedCentral:request.central];
+
+ const auto charHandle = charMap.key(request.characteristic);
+ updated.insert(charHandle);
+ NSMutableData *const data = static_cast<NSMutableData *>(charValues[charHandle]);
+ [data replaceBytesInRange:NSMakeRange(request.offset, request.value.length)
+ withBytes:data.bytes];
+ }
+
+ for (const auto handle : updated)
+ emit notifier->characteristicUpdated(handle, qt_bytearray(charValues[handle]));
+
+ if (requests.count) {
+ [manager respondToRequest:[requests objectAtIndex:0]
+ withResult:CBATTErrorSuccess];
+ }
+}
+
+- (void)peripheralManagerIsReadyToUpdateSubscribers:(CBPeripheralManager *)peripheral
+{
+ if (peripheral != manager || !notifier) {
+ // Detached.
+ return;
+ }
+
+ [self sendUpdateRequests];
+}
+
+- (void)sendUpdateRequests
+{
+ QT_BT_MAC_AUTORELEASEPOOL
+
+ while (updateQueue.size()) {
+ const auto &request = updateQueue.front();
+ Q_ASSERT(charMap.contains(request.charHandle));
+ const BOOL res = [manager updateValue:request.value
+ forCharacteristic:static_cast<CBMutableCharacteristic *>(charMap[request.charHandle])
+ onSubscribedCentrals:nil];
+ if (!res) {
+ // Have to wait for the 'ManagerIsReadyToUpdate'.
+ break;
+ }
+
+ updateQueue.pop_front();
+ }
+}
+
+// Private API:
+
+- (void)addConnectedCentral:(CBCentral *)central
+{
+ if (!central)
+ return;
+
+ if (!notifier) {
+ // We were detached.
+ return;
+ }
+
+ QT_BT_MAC_AUTORELEASEPOOL
+
+ if (state == PeripheralState::advertising) {
+ state = PeripheralState::connected;
+ [manager stopAdvertising];
+ emit notifier->connected();
+ }
+
+ if (![connectedCentrals containsObject:central.identifier])
+ [connectedCentrals addObject:central.identifier];
+}
+
+- (void)removeConnectedCentral:(CBCentral *)central
+{
+ if (!notifier) {
+ // Detached.
+ return;
+ }
+
+ QT_BT_MAC_AUTORELEASEPOOL
+
+ if ([connectedCentrals containsObject:central.identifier])
+ [connectedCentrals removeObject:central.identifier];
+
+ if (state == PeripheralState::connected && ![connectedCentrals count]) {
+ state = PeripheralState::idle;
+ emit notifier->disconnected();
+ }
+}
+
+- (CBService *)findIncludedService:(const QBluetoothUuid &)qtUUID
+{
+ const auto it = serviceIndex.find(qtUUID);
+ if (it == serviceIndex.end())
+ return nil;
+
+ return it->second;
+}
+
+- (void)addIncludedServices:(const QLowEnergyServiceData &)data
+ to:(CBMutableService *)cbService
+ qtService:(QLowEnergyServicePrivate *)qtService
+{
+ Q_ASSERT(cbService);
+ Q_ASSERT(qtService);
+
+ QT_BT_MAC_AUTORELEASEPOOL
+
+ ObjCScopedPointer<NSMutableArray> included([[NSMutableArray alloc] init]);
+ if (!included) {
+ qCWarning(QT_BT_OSX) << "addIncludedSerivces: failed "
+ "to allocate NSMutableArray";
+ return;
+ }
+
+ for (auto includedService : data.includedServices()) {
+ if (CBService *cbs = [self findIncludedService:includedService->serviceUuid()]) {
+ [included addObject:cbs];
+ qtService->includedServices << includedService->serviceUuid();
+ ++lastHandle;
+ } else {
+ qCWarning(QT_BT_OSX) << "can not use" << includedService->serviceUuid()
+ << "as included, it has to be added first";
+ }
+ }
+
+ if ([included count])
+ cbService.includedServices = included;
+}
+
+- (void)addCharacteristicsAndDescriptors:(const QLowEnergyServiceData &)data
+ to:(CBMutableService *)cbService
+ qtService:(QLowEnergyServicePrivate *)qtService
+{
+ Q_ASSERT(cbService);
+ Q_ASSERT(qtService);
+
+ QT_BT_MAC_AUTORELEASEPOOL
+
+ ObjCScopedPointer<NSMutableArray> newCBChars([[NSMutableArray alloc] init]);
+ if (!newCBChars) {
+ qCWarning(QT_BT_OSX) << "addCharacteristicsAndDescritptors: "
+ "failed to allocate NSMutableArray "
+ "(characteristics)";
+ return;
+ }
+
+ for (const auto &ch : data.characteristics()) {
+ const auto cbChar(create_characteristic(ch));
+ if (!cbChar) {
+ qCWarning(QT_BT_OSX) << "addCharacteristicsAndDescritptors: "
+ "failed to allocate a characteristic";
+ continue;
+ }
+
+ const auto nsData(data_from_bytearray(ch.value()));
+ if (!nsData) {
+ qCWarning(QT_BT_OSX) << "addCharacteristicsAndDescritptors: "
+ "addService: failed to allocate NSData (char value)";
+ continue;
+ }
+
+ [newCBChars addObject:cbChar];
+
+ const auto declHandle = ++lastHandle;
+ // CB part:
+ charMap[declHandle] = cbChar;
+ charValues[declHandle] = data_from_bytearray(ch.value());
+ // QT part:
+ QLowEnergyServicePrivate::CharData charData;
+ charData.valueHandle = ++lastHandle;
+ charData.uuid = ch.uuid();
+ charData.properties = ch.properties();
+ charData.value = ch.value();
+
+ const ObjCScopedPointer<NSMutableArray> newCBDescs([[NSMutableArray alloc] init]);
+ if (!newCBDescs) {
+ qCWarning(QT_BT_OSX) << "addCharacteristicsAndDescritptors: "
+ "failed to allocate NSMutableArray "
+ "(descriptors)";
+ continue;
+ }
+
+ for (const auto &desc : ch.descriptors()) {
+ // CB part:
+ const auto cbDesc(create_descriptor(desc));
+ const auto descHandle = ++lastHandle;
+ if (cbDesc) {
+ // See comments in create_descriptor on
+ // why cbDesc can be nil.
+ [newCBDescs addObject:cbDesc];
+ }
+ // QT part:
+ QLowEnergyServicePrivate::DescData descData;
+ descData.uuid = desc.uuid();
+ descData.value = desc.value();
+ charData.descriptorList.insert(descHandle, descData);
+ }
+
+ if ([newCBDescs count])
+ cbChar.data().descriptors = newCBDescs.data(); // retains
+
+ qtService->characteristicList.insert(declHandle, charData);
+ }
+
+ if ([newCBChars count])
+ cbService.characteristics = newCBChars.data();
+}
+
+- (CBATTError)validateWriteRequest:(CBATTRequest *)request
+{
+ Q_ASSERT(request);
+
+ QT_BT_MAC_AUTORELEASEPOOL
+
+ const auto handle = charMap.key(request.characteristic);
+ if (!handle || !charValues.contains(handle))
+ return CBATTErrorInvalidHandle;
+
+ NSMutableData *data = static_cast<NSMutableData *>(charValues[handle]);
+ if (request.offset > data.length || request.value.length > data.length - request.offset)
+ return CBATTErrorInvalidOffset;
+
+ return CBATTErrorSuccess;
+}
+
+@end
diff --git a/src/bluetooth/osx/osxbtperipheralmanager_p.h b/src/bluetooth/osx/osxbtperipheralmanager_p.h
new file mode 100644
index 00000000..481a9fab
--- /dev/null
+++ b/src/bluetooth/osx/osxbtperipheralmanager_p.h
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OSXBTPERIPHERALMANAGER_P_H
+#define OSXBTPERIPHERALMANAGER_P_H
+
+
+#include "osxbtutility_p.h"
+
+#include "qlowenergyadvertisingparameters.h"
+#include "qlowenergyserviceprivate_p.h"
+#include "qbluetoothuuid.h"
+#include "qbluetooth.h"
+
+#include <QtCore/qsharedpointer.h>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qsysinfo.h>
+#include <QtCore/qglobal.h>
+#include <QtCore/qmap.h>
+
+#include <vector>
+#include <deque>
+#include <map>
+
+// Foundation.h must be included before corebluetoothwrapper_p.h -
+// a workaround for a broken 10.9 SDK.
+#include <Foundation/Foundation.h>
+
+#include "corebluetoothwrapper_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QLowEnergyServiceData;
+
+namespace OSXBluetooth
+{
+
+class LECBManagerNotifier;
+
+}
+
+QT_END_NAMESPACE
+
+
+// Exposing names in a header is ugly, but constant QT_PREPEND_NAMESPACE is even worse ...
+// After all, this header is to be included only in its own and controller's *.mm files.
+
+QT_USE_NAMESPACE
+
+using namespace OSXBluetooth;
+
+
+template<class Type>
+using GenericLEMap = QMap<QLowEnergyHandle, Type>;
+
+enum class PeripheralState
+{
+ idle,
+ waitingForPowerOn,
+ advertising,
+ connected
+};
+
+struct UpdateRequest
+{
+ UpdateRequest() = default;
+ UpdateRequest(QLowEnergyHandle handle, const ObjCStrongReference<NSData> &val)
+ : charHandle(handle),
+ value(val)
+ {
+ }
+
+ QLowEnergyHandle charHandle = {};
+ ObjCStrongReference<NSData> value;
+};
+
+@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<NSData>> charValues;
+
+ std::deque<UpdateRequest> updateQueue;
+
+ ObjCScopedPointer<NSMutableSet> connectedCentrals;
+
+ PeripheralState state;
+}
+
+- (id)initWith:(LECBManagerNotifier *)notifier;
+- (void)dealloc;
+
+- (QSharedPointer<QLowEnergyServicePrivate>)addService:(const QLowEnergyServiceData &)data;
+- (void) setParameters:(const QLowEnergyAdvertisingParameters &)parameters
+ data:(const QLowEnergyAdvertisingData &)data
+ scanResponse:(const QLowEnergyAdvertisingData &)scanResponse;
+
+// To be executed on the Qt's special BTLE dispatch queue.
+- (void)startAdvertising;
+- (void)stopAdvertising;
+- (void)detach;
+
+- (void)write:(const QByteArray &)value
+ charHandle:(QLowEnergyHandle)charHandle;
+
+
+// CBPeripheralManagerDelegate's callbacks (BTLE queue).
+- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral;
+- (void)peripheralManager:(CBPeripheralManager *)peripheral
+ willRestoreState:(NSDictionary *)dict;
+- (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral
+ error:(NSError *)error;
+- (void)peripheralManager:(CBPeripheralManager *)peripheral
+ didAddService:(CBService *)service error:(NSError *)error;
+- (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central
+ didSubscribeToCharacteristic:(CBCharacteristic *)characteristic;
+- (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central
+ didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic;
+- (void)peripheralManager:(CBPeripheralManager *)peripheral
+ didReceiveReadRequest:(CBATTRequest *)request;
+- (void)peripheralManager:(CBPeripheralManager *)peripheral
+ didReceiveWriteRequests:(NSArray *)requests;
+- (void)peripheralManagerIsReadyToUpdateSubscribers:(CBPeripheralManager *)peripheral;
+
+@end
+
+#endif
diff --git a/src/bluetooth/osx/osxbtrfcommchannel.mm b/src/bluetooth/osx/osxbtrfcommchannel.mm
index a91f62dc..b2ee8b64 100644
--- a/src/bluetooth/osx/osxbtrfcommchannel.mm
+++ b/src/bluetooth/osx/osxbtrfcommchannel.mm
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/bluetooth/osx/osxbtrfcommchannel_p.h b/src/bluetooth/osx/osxbtrfcommchannel_p.h
index 80758ab0..89d765d8 100644
--- a/src/bluetooth/osx/osxbtrfcommchannel_p.h
+++ b/src/bluetooth/osx/osxbtrfcommchannel_p.h
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -34,6 +40,17 @@
#ifndef OSXBTRFCOMMCHANNEL_P_H
#define OSXBTRFCOMMCHANNEL_P_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include <QtCore/qglobal.h>
#include <Foundation/Foundation.h>
diff --git a/src/bluetooth/osx/osxbtsdpinquiry.mm b/src/bluetooth/osx/osxbtsdpinquiry.mm
index 004d9e61..28dc2342 100644
--- a/src/bluetooth/osx/osxbtsdpinquiry.mm
+++ b/src/bluetooth/osx/osxbtsdpinquiry.mm
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/bluetooth/osx/osxbtsdpinquiry_p.h b/src/bluetooth/osx/osxbtsdpinquiry_p.h
index 20b6c66c..ea75e649 100644
--- a/src/bluetooth/osx/osxbtsdpinquiry_p.h
+++ b/src/bluetooth/osx/osxbtsdpinquiry_p.h
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -34,6 +40,17 @@
#ifndef OSXBTSDPINQUIRY_H
#define OSXBTSDPINQUIRY_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include "qbluetoothaddress.h"
#include "qbluetoothuuid.h"
diff --git a/src/bluetooth/osx/osxbtservicerecord.mm b/src/bluetooth/osx/osxbtservicerecord.mm
index cd80ee63..11dcac88 100644
--- a/src/bluetooth/osx/osxbtservicerecord.mm
+++ b/src/bluetooth/osx/osxbtservicerecord.mm
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/bluetooth/osx/osxbtservicerecord_p.h b/src/bluetooth/osx/osxbtservicerecord_p.h
index fa84147b..6b2db8a8 100644
--- a/src/bluetooth/osx/osxbtservicerecord_p.h
+++ b/src/bluetooth/osx/osxbtservicerecord_p.h
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -34,6 +40,17 @@
#ifndef OSXBTSERVICERECORD_P_H
#define OSXBTSERVICERECORD_P_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include "osxbtutility_p.h"
#include <QtCore/qglobal.h>
diff --git a/src/bluetooth/osx/osxbtsocketlistener.mm b/src/bluetooth/osx/osxbtsocketlistener.mm
index e3124dd1..5b004f94 100644
--- a/src/bluetooth/osx/osxbtsocketlistener.mm
+++ b/src/bluetooth/osx/osxbtsocketlistener.mm
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/bluetooth/osx/osxbtsocketlistener_p.h b/src/bluetooth/osx/osxbtsocketlistener_p.h
index e4fd8882..4a362763 100644
--- a/src/bluetooth/osx/osxbtsocketlistener_p.h
+++ b/src/bluetooth/osx/osxbtsocketlistener_p.h
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -34,6 +40,17 @@
#ifndef OSXBTSOCKETLISTENER_P_H
#define OSXBTSOCKETLISTENER_P_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include <QtCore/qglobal.h>
#include <Foundation/Foundation.h>
diff --git a/src/bluetooth/osx/osxbtutility.mm b/src/bluetooth/osx/osxbtutility.mm
index a5d3d936..f579b2a4 100644
--- a/src/bluetooth/osx/osxbtutility.mm
+++ b/src/bluetooth/osx/osxbtutility.mm
@@ -1,36 +1,43 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
+#include "qlowenergycharacteristicdata.h"
#include "qbluetoothaddress.h"
#include "osxbtutility_p.h"
#include "qbluetoothuuid.h"
@@ -305,6 +312,47 @@ ObjCStrongReference<NSData> data_from_bytearray(const QByteArray & qtData)
return result;
}
+// A small RAII class for a dispatch queue.
+class SerialDispatchQueue
+{
+public:
+ explicit SerialDispatchQueue(const char *label)
+ {
+ Q_ASSERT(label);
+
+ queue = dispatch_queue_create(label, DISPATCH_QUEUE_SERIAL);
+ if (!queue) {
+ qCCritical(QT_BT_OSX) << "failed to create dispatch queue with label"
+ << label;
+ }
+ }
+ ~SerialDispatchQueue()
+ {
+ if (queue)
+ dispatch_release(queue);
+ }
+
+ dispatch_queue_t data() const
+ {
+ return queue;
+ }
+private:
+ dispatch_queue_t queue;
+
+ Q_DISABLE_COPY(SerialDispatchQueue)
+};
+
+dispatch_queue_t qt_LE_queue()
+{
+ static const SerialDispatchQueue leQueue("qt-bluetooth-LE-queue");
+ return leQueue.data();
+}
+
+unsigned qt_LE_deviceInquiryLength()
+{
+ return 10;
+}
+
}
QT_END_NAMESPACE
diff --git a/src/bluetooth/osx/osxbtutility_p.h b/src/bluetooth/osx/osxbtutility_p.h
index 18d8732a..5e616b74 100644
--- a/src/bluetooth/osx/osxbtutility_p.h
+++ b/src/bluetooth/osx/osxbtutility_p.h
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -34,6 +40,17 @@
#ifndef OSXBTUTILITY_P_H
#define OSXBTUTILITY_P_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include <QtCore/qloggingcategory.h>
#include <QtCore/qscopedpointer.h>
#include <QtCore/qsysinfo.h>
@@ -47,6 +64,8 @@
QT_BEGIN_NAMESPACE
+class QLowEnergyCharacteristicData;
+class QBluetoothAddress;
class QBluetoothUuid;
namespace OSXBluetooth {
@@ -83,8 +102,7 @@ public:
}
};
-typedef ObjCScopedPointer<NSAutoreleasePool> AutoreleasePool;
-#define QT_BT_MAC_AUTORELEASEPOOL const OSXBluetooth::AutoreleasePool pool([[NSAutoreleasePool alloc] init])
+#define QT_BT_MAC_AUTORELEASEPOOL const QMacAutoReleasePool pool;
template<class T>
class ObjCStrongReference {
@@ -266,7 +284,7 @@ QString qt_address(NSString *address);
#ifndef QT_IOS_BLUETOOTH
-class QBluetoothAddress qt_address(const BluetoothDeviceAddress *address);
+QBluetoothAddress qt_address(const BluetoothDeviceAddress *address);
BluetoothDeviceAddress iobluetooth_address(const QBluetoothAddress &address);
ObjCStrongReference<IOBluetoothSDPUUID> iobluetooth_uuid(const QBluetoothUuid &uuid);
@@ -295,6 +313,10 @@ inline QSysInfo::MacVersion qt_OS_limit(QSysInfo::MacVersion osxVersion, QSysInf
#endif
}
+dispatch_queue_t qt_LE_queue();
+// LE scan, in seconds.
+unsigned qt_LE_deviceInquiryLength();
+
} // namespace OSXBluetooth
// Logging category for both OS X and iOS.
diff --git a/src/bluetooth/osx/uistrings.cpp b/src/bluetooth/osx/uistrings.cpp
index 5684533e..7260417f 100644
--- a/src/bluetooth/osx/uistrings.cpp
+++ b/src/bluetooth/osx/uistrings.cpp
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/bluetooth/osx/uistrings_p.h b/src/bluetooth/osx/uistrings_p.h
index 303bad89..999a8c6d 100644
--- a/src/bluetooth/osx/uistrings_p.h
+++ b/src/bluetooth/osx/uistrings_p.h
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -34,6 +40,17 @@
#ifndef TRANSLATIONS_H
#define TRANSLATIONS_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include <QtCore/QCoreApplication>
#include <QtCore/QString>