summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlex Blasche <alexander.blasche@theqtcompany.com>2015-11-11 07:34:02 +0100
committerAlex Blasche <alexander.blasche@theqtcompany.com>2015-11-11 07:34:08 +0100
commit1ebd4d02a67a162411af88b26c899bfb8cf871ca (patch)
treeeaf773acf877561751578c4f99db073b01d71f28 /src
parent90c2fe20adfc65004b230a549af68c579f7152fb (diff)
parent34904f021fbee34ec51c732fa28a5bd7ffabdde8 (diff)
Merge remote-tracking branch 'gerrit/5.6' into dev
Diffstat (limited to 'src')
-rw-r--r--src/bluetooth/bluez/bluez_data_p.h4
-rw-r--r--src/bluetooth/bluez/hcimanager.cpp8
-rw-r--r--src/bluetooth/doc/qtbluetooth.qdocconf2
-rw-r--r--src/bluetooth/osx/osxbtledeviceinquiry.mm110
-rw-r--r--src/bluetooth/osx/osxbtledeviceinquiry_p.h12
-rw-r--r--src/bluetooth/qbluetoothsocket.cpp3
-rw-r--r--src/bluetooth/qbluetoothsocket_bluez.cpp32
-rw-r--r--src/bluetooth/qbluetoothsocket_p.h7
-rw-r--r--src/bluetooth/qlowenergycontroller.cpp6
-rw-r--r--src/bluetooth/qlowenergycontroller_bluez.cpp14
-rw-r--r--src/bluetooth/qlowenergyservice.cpp2
-rw-r--r--src/nfc/doc/qtnfc.qdocconf2
-rw-r--r--src/nfc/doc/src/nfc-android.qdoc2
13 files changed, 125 insertions, 79 deletions
diff --git a/src/bluetooth/bluez/bluez_data_p.h b/src/bluetooth/bluez/bluez_data_p.h
index dc12dda2..3722b80d 100644
--- a/src/bluetooth/bluez/bluez_data_p.h
+++ b/src/bluetooth/bluez/bluez_data_p.h
@@ -50,6 +50,8 @@
#include <sys/socket.h>
#include <QtBluetooth/QBluetoothUuid>
+QT_BEGIN_NAMESPACE
+
#define BTPROTO_L2CAP 0
#define BTPROTO_HCI 1
#define BTPROTO_RFCOMM 3
@@ -331,4 +333,6 @@ typedef struct {
} __attribute__ ((packed)) evt_encrypt_change;
#define EVT_ENCRYPT_CHANGE_SIZE 4
+QT_END_NAMESPACE
+
#endif // BLUEZ_DATA_P_H
diff --git a/src/bluetooth/bluez/hcimanager.cpp b/src/bluetooth/bluez/hcimanager.cpp
index bf2754f5..30511ae5 100644
--- a/src/bluetooth/bluez/hcimanager.cpp
+++ b/src/bluetooth/bluez/hcimanager.cpp
@@ -219,12 +219,8 @@ QBluetoothAddress HciManager::addressForConnectionHandle(quint16 handle) const
}
for (int i = 0; i < infoList->conn_num; i++) {
- if (info[i].handle == handle) {
- quint64 converted;
- convertAddress(info[i].bdaddr.b, converted);
-
- return QBluetoothAddress(converted);
- }
+ if (info[i].handle == handle)
+ return QBluetoothAddress(convertAddress(info[i].bdaddr.b));
}
return QBluetoothAddress();
diff --git a/src/bluetooth/doc/qtbluetooth.qdocconf b/src/bluetooth/doc/qtbluetooth.qdocconf
index 52061d7e..a4b86e95 100644
--- a/src/bluetooth/doc/qtbluetooth.qdocconf
+++ b/src/bluetooth/doc/qtbluetooth.qdocconf
@@ -4,7 +4,7 @@ project = QtBluetooth
description = Qt Bluetooth Reference Documentation
version = $QT_VERSION
-examplesinstallpath = bluetooth
+examplesinstallpath = qtconnectivity/bluetooth
qhp.projects = QtBluetooth
diff --git a/src/bluetooth/osx/osxbtledeviceinquiry.mm b/src/bluetooth/osx/osxbtledeviceinquiry.mm
index c46c68fc..28bfd1bc 100644
--- a/src/bluetooth/osx/osxbtledeviceinquiry.mm
+++ b/src/bluetooth/osx/osxbtledeviceinquiry.mm
@@ -110,6 +110,7 @@ using namespace QT_NAMESPACE;
@interface QT_MANGLE_NAMESPACE(OSXBTLEDeviceInquiry) (PrivateAPI) <CBCentralManagerDelegate, CBPeripheralDelegate>
// "Timeout" callback to stop a scan.
- (void)stopScan;
+- (void)handlePoweredOffAfterDelay;
@end
@implementation QT_MANGLE_NAMESPACE(OSXBTLEDeviceInquiry)
@@ -130,9 +131,8 @@ using namespace QT_NAMESPACE;
delegate = aDelegate;
peripherals = [[NSMutableDictionary alloc] init];
manager = nil;
- pendingStart = false;
+ scanPhase = noActivity;
cancelled = false;
- isActive = false;
}
return self;
@@ -144,7 +144,7 @@ using namespace QT_NAMESPACE;
if (manager) {
[manager setDelegate:nil];
- if (isActive)
+ if (scanPhase == activeScan)
[manager stopScan];
[manager release];
}
@@ -158,17 +158,37 @@ using namespace QT_NAMESPACE;
// 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(scanPhase == activeScan, 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;
+ scanPhase = noActivity;
delegate->LEdeviceInquiryFinished();
}
+- (void)handlePoweredOffAfterDelay
+{
+ // If we are here, this means:
+ // we received 'PoweredOff' while scanPhase == startingScan
+ // and no 'PoweredOn' after this.
+
+ Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
+ Q_ASSERT_X(scanPhase == startingScan, Q_FUNC_INFO, "invalid state");
+
+ scanPhase = noActivity;
+ if (cancelled) {
+ // Timeout happened before
+ // the second status update, but after 'stop'.
+ delegate->LEdeviceInquiryFinished();
+ } else {
+ // Timeout and no 'stop' between 'start'
+ // and 'centralManagerDidUpdateStatus':
+ delegate->LEnotSupported();
+ }
+}
+
- (bool)start
{
Q_ASSERT_X(![self isActive], Q_FUNC_INFO, "LE device scan is already active");
@@ -189,7 +209,7 @@ using namespace QT_NAMESPACE;
}
startTime = QTime();
- pendingStart = true;
+ scanPhase = startingScan;
manager = [CBCentralManager alloc];
manager = [manager initWithDelegate:self queue:nil];
if (!manager) {
@@ -204,18 +224,27 @@ using namespace QT_NAMESPACE;
{
Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
+ const CBCentralManagerState state = central.state;
+
+ if (scanPhase == startingScan && (state == CBCentralManagerStatePoweredOn
+ || state == CBCentralManagerStateUnsupported
+ || state == CBCentralManagerStateUnauthorized
+ || state == CBCentralManagerStatePoweredOff)) {
+ // We probably had 'PoweredOff' before,
+ // cancel the previous handlePoweredOffAfterDelay.
+ [NSObject cancelPreviousPerformRequestsWithTarget:self];
+ }
+
if (cancelled) {
- Q_ASSERT_X(!isActive, Q_FUNC_INFO, "isActive is true");
- pendingStart = false;
+ Q_ASSERT_X(scanPhase != activeScan, Q_FUNC_INFO, "in 'activeScan' phase");
+ scanPhase = noActivity;
delegate->LEdeviceInquiryFinished();
return;
}
- const CBCentralManagerState state = central.state;
if (state == CBCentralManagerStatePoweredOn) {
- if (pendingStart) {
- pendingStart = false;
- isActive = true;
+ if (scanPhase == startingScan) {
+ scanPhase = activeScan;
#ifndef Q_OS_OSX
const NSTimeInterval timeout([QT_MANGLE_NAMESPACE(OSXBTLEDeviceInquiry) inquiryLength] / 1000);
Q_ASSERT_X(timeout > 0., Q_FUNC_INFO, "invalid scan timeout");
@@ -225,27 +254,33 @@ using namespace QT_NAMESPACE;
[manager scanForPeripheralsWithServices:nil options:nil];
} // Else we ignore.
} else if (state == CBCentralManagerStateUnsupported || state == CBCentralManagerStateUnauthorized) {
- if (pendingStart) {
- pendingStart = false;
+ if (scanPhase == startingScan) {
+ scanPhase = noActivity;
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.
+ } else if (scanPhase == activeScan) {
+ // Cancel stopScan:
[NSObject cancelPreviousPerformRequestsWithTarget:self];
- isActive = false;
+
+ scanPhase = noActivity;
[manager stopScan];
delegate->LEdeviceInquiryError(QBluetoothDeviceDiscoveryAgent::PoweredOffError);
}
} else if (state == CBCentralManagerStatePoweredOff) {
- if (pendingStart) {
- pendingStart = false;
+ if (scanPhase == startingScan) {
+#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.
+ [self performSelector:@selector(handlePoweredOffAfterDelay) withObject:nil afterDelay:30.];
+ return;
+#endif
+ scanPhase = noActivity;
delegate->LEnotSupported();
- } else if (isActive) {
- // We were able to start (isActive == true), so we had
- // powered ON and now the adapter is OFF.
+ } else if (scanPhase == activeScan) {
+ // Cancel stopScan:
[NSObject cancelPreviousPerformRequestsWithTarget:self];
- isActive = false;
+
+ scanPhase = noActivity;
[manager stopScan];
delegate->LEdeviceInquiryError(QBluetoothDeviceDiscoveryAgent::PoweredOffError);
} // Else we ignore.
@@ -259,25 +294,28 @@ 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.
}
}
- (void)stop
{
- [NSObject cancelPreviousPerformRequestsWithTarget:self];
+ if (scanPhase != startingScan) {
+ // startingScan means either no selector at all,
+ // or handlePoweredOffAfterDelay and we do not want to cancel it yet,
+ // waiting for DidUpdateState or handlePoweredOffAfterDelay, whoever
+ // fires first ...
+ [NSObject cancelPreviousPerformRequestsWithTarget:self];
+ }
- if (pendingStart || cancelled) {
- // We have to wait for a status update.
+ if (scanPhase == startingScan || cancelled) {
+ // We have to wait for a status update or handlePoweredOffAfterDelay.
cancelled = true;
return;
}
- if (isActive) {
+ if (scanPhase == activeScan) {
[manager stopScan];
- isActive = false;
+ scanPhase = noActivity;
delegate->LEdeviceInquiryFinished();
}
}
@@ -290,7 +328,7 @@ using namespace QT_NAMESPACE;
using namespace OSXBluetooth;
- if (!isActive)
+ if (scanPhase != activeScan)
return;
Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
@@ -335,7 +373,7 @@ using namespace QT_NAMESPACE;
- (bool)isActive
{
- return pendingStart || isActive;
+ return scanPhase == startingScan || scanPhase == activeScan;
}
- (const QTime&)startTime
diff --git a/src/bluetooth/osx/osxbtledeviceinquiry_p.h b/src/bluetooth/osx/osxbtledeviceinquiry_p.h
index ca70bcc1..cb86cd14 100644
--- a/src/bluetooth/osx/osxbtledeviceinquiry_p.h
+++ b/src/bluetooth/osx/osxbtledeviceinquiry_p.h
@@ -86,6 +86,13 @@ public:
QT_END_NAMESPACE
// Bluetooth Low Energy scan for iOS and OS X.
+// Strong enum would be quite handy ...
+enum LEScanPhase
+{
+ noActivity,
+ startingScan,
+ activeScan
+};
@interface QT_MANGLE_NAMESPACE(OSXBTLEDeviceInquiry) : NSObject
{// Protocols are adopted in the mm file.
@@ -95,11 +102,8 @@ QT_END_NAMESPACE
NSMutableDictionary *peripherals; // Found devices.
CBCentralManager *manager;
- // pending - waiting for a status update first.
- bool pendingStart;
+ LEScanPhase scanPhase;
bool cancelled;
- // scan actually started.
- bool isActive;
QTime startTime;
}
diff --git a/src/bluetooth/qbluetoothsocket.cpp b/src/bluetooth/qbluetoothsocket.cpp
index 97ee7dc2..f6cbf4e9 100644
--- a/src/bluetooth/qbluetoothsocket.cpp
+++ b/src/bluetooth/qbluetoothsocket.cpp
@@ -72,6 +72,9 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT)
If the \l {QBluetoothServiceInfo::Protocol}{Protocol} is not supported on a platform, calling
\l connectToService() will emit a \l {QBluetoothSocket::UnsupportedProtocolError}{UnsupportedProtocolError} error.
+ \note QBluetoothSocket does not support synchronous read and write operations. Functions such
+ as \l waitForReadyRead() and \l waitForBytesWritten() are not implemented. I/O operations should be
+ performed using \l readyRead(), \l read() and \l write().
*/
/*!
diff --git a/src/bluetooth/qbluetoothsocket_bluez.cpp b/src/bluetooth/qbluetoothsocket_bluez.cpp
index 71f26296..43933f26 100644
--- a/src/bluetooth/qbluetoothsocket_bluez.cpp
+++ b/src/bluetooth/qbluetoothsocket_bluez.cpp
@@ -309,20 +309,14 @@ QBluetoothAddress QBluetoothSocketPrivate::localAddress() const
sockaddr_rc addr;
socklen_t addrLength = sizeof(addr);
- if (::getsockname(socket, reinterpret_cast<sockaddr *>(&addr), &addrLength) == 0) {
- quint64 bdaddr;
- convertAddress(addr.rc_bdaddr.b, bdaddr);
- return QBluetoothAddress(bdaddr);
- }
+ if (::getsockname(socket, reinterpret_cast<sockaddr *>(&addr), &addrLength) == 0)
+ return QBluetoothAddress(convertAddress(addr.rc_bdaddr.b));
} else if (socketType == QBluetoothServiceInfo::L2capProtocol) {
sockaddr_l2 addr;
socklen_t addrLength = sizeof(addr);
- if (::getsockname(socket, reinterpret_cast<sockaddr *>(&addr), &addrLength) == 0) {
- quint64 bdaddr;
- convertAddress(addr.l2_bdaddr.b, bdaddr);
- return QBluetoothAddress(bdaddr);
- }
+ if (::getsockname(socket, reinterpret_cast<sockaddr *>(&addr), &addrLength) == 0)
+ return QBluetoothAddress(convertAddress(addr.l2_bdaddr.b));
}
return QBluetoothAddress();
@@ -358,7 +352,7 @@ QString QBluetoothSocketPrivate::peerName() const
if (::getpeername(socket, reinterpret_cast<sockaddr *>(&addr), &addrLength) < 0)
return QString();
- convertAddress(addr.rc_bdaddr.b, bdaddr);
+ convertAddress(addr.rc_bdaddr.b, &bdaddr);
} else if (socketType == QBluetoothServiceInfo::L2capProtocol) {
sockaddr_l2 addr;
socklen_t addrLength = sizeof(addr);
@@ -366,7 +360,7 @@ QString QBluetoothSocketPrivate::peerName() const
if (::getpeername(socket, reinterpret_cast<sockaddr *>(&addr), &addrLength) < 0)
return QString();
- convertAddress(addr.l2_bdaddr.b, bdaddr);
+ convertAddress(addr.l2_bdaddr.b, &bdaddr);
} else {
qCWarning(QT_BT_BLUEZ) << "peerName() called on socket of unknown type";
return QString();
@@ -441,20 +435,14 @@ QBluetoothAddress QBluetoothSocketPrivate::peerAddress() const
sockaddr_rc addr;
socklen_t addrLength = sizeof(addr);
- if (::getpeername(socket, reinterpret_cast<sockaddr *>(&addr), &addrLength) == 0) {
- quint64 bdaddr;
- convertAddress(addr.rc_bdaddr.b, bdaddr);
- return QBluetoothAddress(bdaddr);
- }
+ if (::getpeername(socket, reinterpret_cast<sockaddr *>(&addr), &addrLength) == 0)
+ return QBluetoothAddress(convertAddress(addr.rc_bdaddr.b));
} else if (socketType == QBluetoothServiceInfo::L2capProtocol) {
sockaddr_l2 addr;
socklen_t addrLength = sizeof(addr);
- if (::getpeername(socket, reinterpret_cast<sockaddr *>(&addr), &addrLength) == 0) {
- quint64 bdaddr;
- convertAddress(addr.l2_bdaddr.b, bdaddr);
- return QBluetoothAddress(bdaddr);
- }
+ if (::getpeername(socket, reinterpret_cast<sockaddr *>(&addr), &addrLength) == 0)
+ return QBluetoothAddress(convertAddress(addr.l2_bdaddr.b));
}
return QBluetoothAddress();
diff --git a/src/bluetooth/qbluetoothsocket_p.h b/src/bluetooth/qbluetoothsocket_p.h
index 23f3cf72..80db02a2 100644
--- a/src/bluetooth/qbluetoothsocket_p.h
+++ b/src/bluetooth/qbluetoothsocket_p.h
@@ -220,14 +220,17 @@ static inline void convertAddress(quint64 from, quint8 (&to)[6])
to[5] = (from >> 40) & 0xff;
}
-static inline void convertAddress(quint8 (&from)[6], quint64 &to)
+static inline quint64 convertAddress(quint8 (&from)[6], quint64 *to = 0)
{
- to = (quint64(from[0]) << 0) |
+ const quint64 result = (quint64(from[0]) << 0) |
(quint64(from[1]) << 8) |
(quint64(from[2]) << 16) |
(quint64(from[3]) << 24) |
(quint64(from[4]) << 32) |
(quint64(from[5]) << 40);
+ if (to)
+ *to = result;
+ return result;
}
QT_END_NAMESPACE
diff --git a/src/bluetooth/qlowenergycontroller.cpp b/src/bluetooth/qlowenergycontroller.cpp
index 99a3724e..62e8f7e3 100644
--- a/src/bluetooth/qlowenergycontroller.cpp
+++ b/src/bluetooth/qlowenergycontroller.cpp
@@ -222,8 +222,12 @@ void QLowEnergyControllerPrivate::setError(
case QLowEnergyController::NetworkError:
errorString = QLowEnergyController::tr("Error occurred during connection I/O");
break;
+ case QLowEnergyController::ConnectionError:
+ errorString = QLowEnergyController::tr("Error occurred trying to connect to remote device.");
+ break;
+ case QLowEnergyController::NoError:
+ return;
case QLowEnergyController::UnknownError:
- default:
errorString = QLowEnergyController::tr("Unknown Error");
break;
}
diff --git a/src/bluetooth/qlowenergycontroller_bluez.cpp b/src/bluetooth/qlowenergycontroller_bluez.cpp
index a7b2e794..18d0f5a1 100644
--- a/src/bluetooth/qlowenergycontroller_bluez.cpp
+++ b/src/bluetooth/qlowenergycontroller_bluez.cpp
@@ -106,8 +106,10 @@
#define ATT_ERROR_INVAL_ATTR_VALUE_LEN 0x0D
#define ATT_ERROR_UNLIKELY 0x0E
#define ATT_ERROR_INSUF_ENCRYPTION 0x0F
-#define ATT_ERROR_APPLICATION 0x10
+#define ATT_ERROR_UNSUPPRTED_GROUP_TYPE 0x10
#define ATT_ERROR_INSUF_RESOURCES 0x11
+#define ATT_ERROR_APPLICATION_START 0x80
+#define ATT_ERROR_APPLICATION_END 0x9f
#define APPEND_VALUE true
#define NEW_VALUE false
@@ -176,12 +178,16 @@ static void dumpErrorInformation(const QByteArray &response)
errorString = QStringLiteral("unlikely error"); break;
case ATT_ERROR_INSUF_ENCRYPTION:
errorString = QStringLiteral("needs encryption - permissions"); break;
- case ATT_ERROR_APPLICATION:
- errorString = QStringLiteral("application error"); break;
+ case ATT_ERROR_UNSUPPRTED_GROUP_TYPE:
+ errorString = QStringLiteral("unsupported group type"); break;
case ATT_ERROR_INSUF_RESOURCES:
errorString = QStringLiteral("insufficient resources to complete request"); break;
default:
- errorString = QStringLiteral("unknown error code"); break;
+ if (errorCode >= ATT_ERROR_APPLICATION_START && errorCode <= ATT_ERROR_APPLICATION_END)
+ errorString = QStringLiteral("application error");
+ else
+ errorString = QStringLiteral("unknown error code");
+ break;
}
qCDebug(QT_BT_BLUEZ) << "Error1:" << errorString
diff --git a/src/bluetooth/qlowenergyservice.cpp b/src/bluetooth/qlowenergyservice.cpp
index 9fb8e47c..9cccbc93 100644
--- a/src/bluetooth/qlowenergyservice.cpp
+++ b/src/bluetooth/qlowenergyservice.cpp
@@ -390,7 +390,7 @@ QLowEnergyService::~QLowEnergyService()
\l {QLowEnergyController::createServiceObject()} should be used to obtain
service instances for each of the UUIDs.
- \sa createServiceObject()
+ \sa {QLowEnergyController::}{createServiceObject()}
*/
QList<QBluetoothUuid> QLowEnergyService::includedServices() const
{
diff --git a/src/nfc/doc/qtnfc.qdocconf b/src/nfc/doc/qtnfc.qdocconf
index 61ed15b6..8b0ba092 100644
--- a/src/nfc/doc/qtnfc.qdocconf
+++ b/src/nfc/doc/qtnfc.qdocconf
@@ -4,7 +4,7 @@ project = QtNfc
description = Qt NFC Reference Documentation
version = $QT_VERSION
-examplesinstallpath = nfc
+examplesinstallpath = qtconnectivity/nfc
qhp.projects = QtNfc
diff --git a/src/nfc/doc/src/nfc-android.qdoc b/src/nfc/doc/src/nfc-android.qdoc
index e7c43423..7288b78a 100644
--- a/src/nfc/doc/src/nfc-android.qdoc
+++ b/src/nfc/doc/src/nfc-android.qdoc
@@ -48,7 +48,7 @@ This means the application has to provide an AndroidManifest.xml file with prope
\endcode
When the application is started it has to register an message handler with
-\l registerNdefMessageHandler().
+\l {QNearFieldManager::}{registerNdefMessageHandler()}
The first NDEF message arriving in the handler is the message that started the application.
See the \l {corkboard}{CorkBoard} application for an example.