summaryrefslogtreecommitdiffstats
path: root/src/bluetooth/osx
diff options
context:
space:
mode:
authorTimur Pocheptsov <Timur.Pocheptsov@digia.com>2014-11-07 15:29:59 +0100
committerTimur Pocheptsov <Timur.Pocheptsov@digia.com>2014-11-13 14:12:18 +0100
commit53dad9ebc8e1caa8c13a8b964ecdede381067340 (patch)
tree18b27fb9a3898a9c37a92763be5163ee7bd3f6a8 /src/bluetooth/osx
parent720137353b3d6ecb6a07d1f5486ab20306be8134 (diff)
QLowEnergyController - service discovery (OS X, iOS)
Implement discoverServices and delegate's methods to work with a service discovery on a peripheral. - CBUUID (it's internal data) can be only 2 bytes long (16-bit shortened UUID) despite of the docs saying 'CBUUID is a 16-bit UUID'. - property 'isPrimary' did not exist prior to 10.9 SDK (OS X). Change-Id: If692d147c0479ed69a331514617e3ef2a986cdf4 Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
Diffstat (limited to 'src/bluetooth/osx')
-rw-r--r--src/bluetooth/osx/osxbtcentralmanager.mm35
-rw-r--r--src/bluetooth/osx/osxbtcentralmanagerdelegate_p.h2
-rw-r--r--src/bluetooth/osx/osxbtutility.mm29
3 files changed, 60 insertions, 6 deletions
diff --git a/src/bluetooth/osx/osxbtcentralmanager.mm b/src/bluetooth/osx/osxbtcentralmanager.mm
index d2e45832..32fad1db 100644
--- a/src/bluetooth/osx/osxbtcentralmanager.mm
+++ b/src/bluetooth/osx/osxbtcentralmanager.mm
@@ -252,6 +252,20 @@ using namespace QT_NAMESPACE;
- (void)discoverServices
{
+ Q_ASSERT_X(peripheral, "-discoverServices", "invalid peripheral (nil)");
+ Q_ASSERT_X(managerState == OSXBluetooth::CentralManagerIdle,
+ "-discoverServices", "invalid state");
+
+ // From Apple's docs:
+ //
+ //"If the servicesUUIDs parameter is nil, all the available
+ //services of the peripheral are returned; setting the
+ //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];
}
- (bool)discoverServiceDetails:(const QBluetoothUuid &)serviceUuid
@@ -425,7 +439,26 @@ using namespace QT_NAMESPACE;
- (void)peripheral:(CBPeripheral *)aPeripheral didDiscoverServices:(NSError *)error
{
Q_UNUSED(aPeripheral)
- Q_UNUSED(error)
+
+
+ if (managerState != OSXBluetooth::CentralManagerDiscovering) {
+ // Canceled by -disconnectFromDevice.
+ return;
+ }
+
+ managerState = OSXBluetooth::CentralManagerIdle;
+
+ if (error) {
+ // NSLog, not qCDebug/Warning - to print the error.
+ NSLog(@"-peripheral:didDiscoverServices:, failed with error %@", error);
+ // TODO: better error mapping required.
+ delegate->error(QLowEnergyController::UnknownError);
+ } else {
+ QT_BT_MAC_AUTORELEASEPOOL;
+
+ OSXBluetooth::ObjCStrongReference<NSArray> services(peripheral.services, true);
+ delegate->serviceDiscoveryFinished(services);
+ }
}
diff --git a/src/bluetooth/osx/osxbtcentralmanagerdelegate_p.h b/src/bluetooth/osx/osxbtcentralmanagerdelegate_p.h
index 65b5e61f..196e14d0 100644
--- a/src/bluetooth/osx/osxbtcentralmanagerdelegate_p.h
+++ b/src/bluetooth/osx/osxbtcentralmanagerdelegate_p.h
@@ -54,6 +54,8 @@
// and later in the delegate's -centralManagerDidUpdateState: we are trying to finally release
// a manager. Otherwise, this thing dies even with ARC.
+// TODO: can not reproduce this crash anymore ... probably, this class will be removed soon.
+
@interface QT_MANGLE_NAMESPACE(OSXBTCentralManagerTransientDelegate) : NSObject<CBCentralManagerDelegate>
{
CBCentralManager *manager;
diff --git a/src/bluetooth/osx/osxbtutility.mm b/src/bluetooth/osx/osxbtutility.mm
index 74ee84e6..69e94434 100644
--- a/src/bluetooth/osx/osxbtutility.mm
+++ b/src/bluetooth/osx/osxbtutility.mm
@@ -165,19 +165,38 @@ QString qt_error_string(IOReturn errorCode)
QBluetoothUuid qt_uuid(CBUUID *uuid)
{
+ // Apples' docs say "128 bit" and "16-bit UUIDs are implicitly
+ // pre-filled with the Bluetooth Base UUID."
+ // But Core Bluetooth can return CBUUID objects of length 2
+ // (16-bit, so they are not pre-filled?).
+
if (!uuid)
return QBluetoothUuid();
QT_BT_MAC_AUTORELEASEPOOL;
- if (uuid.data.length != 16) // TODO: warning?
+ if (uuid.data.length == 2) {
+ // TODO: this is .. UGLY :)
+ quint16 qtUuidData = 0;
+ const quint8 *const source = static_cast<const quint8 *>(uuid.data.bytes);
+ std::copy(source, source + 2, &qtUuidData);
+
+ return QBluetoothUuid(qtUuidData);
+ } else if (uuid.data.length == 16) {
+ quint128 qtUuidData = {};
+ const quint8 *const source = static_cast<const quint8 *>(uuid.data.bytes);
+ std::copy(source, source + 16, qtUuidData.data);
+
+ return QBluetoothUuid(qtUuidData);
+ } else {
+ qCDebug(QT_BT_OSX) << "qt_uuid, invalid CBUUID, 2 or 16 bytes expected, but got "
+ << uuid.data.length << " bytes length";
return QBluetoothUuid();
+ }
- quint128 qtUuidData = {};
- const quint8 *const source = static_cast<const quint8 *>(uuid.data.bytes);
- std::copy(source, source + 16, qtUuidData.data);
+ if (uuid.data.length != 16) // TODO: warning?
+ return QBluetoothUuid();
- return QBluetoothUuid(qtUuidData);
}
CFStrongReference<CFUUIDRef> cf_uuid(const QBluetoothUuid &qtUuid)