diff options
author | Alex Blasche <alexander.blasche@theqtcompany.com> | 2015-11-11 07:34:02 +0100 |
---|---|---|
committer | Alex Blasche <alexander.blasche@theqtcompany.com> | 2015-11-11 07:34:08 +0100 |
commit | 1ebd4d02a67a162411af88b26c899bfb8cf871ca (patch) | |
tree | eaf773acf877561751578c4f99db073b01d71f28 | |
parent | 90c2fe20adfc65004b230a549af68c579f7152fb (diff) | |
parent | 34904f021fbee34ec51c732fa28a5bd7ffabdde8 (diff) |
Merge remote-tracking branch 'gerrit/5.6' into dev
Change-Id: I9303c9e168afa9bea87a63abe8774c8f2fee5f3e
-rw-r--r-- | src/bluetooth/bluez/bluez_data_p.h | 4 | ||||
-rw-r--r-- | src/bluetooth/bluez/hcimanager.cpp | 8 | ||||
-rw-r--r-- | src/bluetooth/doc/qtbluetooth.qdocconf | 2 | ||||
-rw-r--r-- | src/bluetooth/osx/osxbtledeviceinquiry.mm | 110 | ||||
-rw-r--r-- | src/bluetooth/osx/osxbtledeviceinquiry_p.h | 12 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothsocket.cpp | 3 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothsocket_bluez.cpp | 32 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothsocket_p.h | 7 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller.cpp | 6 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_bluez.cpp | 14 | ||||
-rw-r--r-- | src/bluetooth/qlowenergyservice.cpp | 2 | ||||
-rw-r--r-- | src/nfc/doc/qtnfc.qdocconf | 2 | ||||
-rw-r--r-- | src/nfc/doc/src/nfc-android.qdoc | 2 |
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. |