summaryrefslogtreecommitdiffstats
path: root/src/bluetooth/osx
diff options
context:
space:
mode:
authorTimur Pocheptsov <timur.pocheptsov@qt.io>2016-11-08 13:20:05 +0100
committerTimur Pocheptsov <timur.pocheptsov@qt.io>2016-11-08 12:46:03 +0000
commit85a626e83fa90bfae09be28e32c957f6bab2d861 (patch)
tree40dbbef8846439e919aee37dda7367239b906c56 /src/bluetooth/osx
parent3375871a93f8d366f1eca5b823e4337af3aecd8c (diff)
LE device scan - use advertisement data (iOS/macOS)
Things like services uuids can be quite useful and we should extract them. Also, do not ignore the device discovered the second time as it was done in the past, the logic updating QBluetoothDeviceInfo with new info (if needed) is already in the device discovery agent. Change-Id: I89e735dae26848eb95395cf96099efd5b56b18b3 Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'src/bluetooth/osx')
-rw-r--r--src/bluetooth/osx/osxbtledeviceinquiry.mm61
-rw-r--r--src/bluetooth/osx/osxbtledeviceinquiry_p.h1
2 files changed, 50 insertions, 12 deletions
diff --git a/src/bluetooth/osx/osxbtledeviceinquiry.mm b/src/bluetooth/osx/osxbtledeviceinquiry.mm
index 8b924d82..2dabd0c1 100644
--- a/src/bluetooth/osx/osxbtledeviceinquiry.mm
+++ b/src/bluetooth/osx/osxbtledeviceinquiry.mm
@@ -69,6 +69,46 @@ const int timeStepMS = 100;
const int powerOffTimeoutMS = 30000;
const qreal powerOffTimeStepS = 30. / 100.;
+struct AdvertisementData {
+ // That's what CoreBluetooth has:
+ // CBAdvertisementDataLocalNameKey
+ // CBAdvertisementDataTxPowerLevelKey
+ // CBAdvertisementDataServiceUUIDsKey
+ // CBAdvertisementDataServiceDataKey
+ // CBAdvertisementDataManufacturerDataKey
+ // CBAdvertisementDataOverflowServiceUUIDsKey
+ // CBAdvertisementDataIsConnectable
+ // CBAdvertisementDataSolicitedServiceUUIDsKey
+
+ // For now, we "parse":
+ QString localName;
+ QList<QBluetoothUuid> serviceUuids;
+ // TODO: other keys probably?
+ AdvertisementData(NSDictionary *AdvertisementData);
+};
+
+AdvertisementData::AdvertisementData(NSDictionary *advertisementData)
+{
+ if (!advertisementData)
+ return;
+
+ // ... constant CBAdvertisementDataLocalNameKey ...
+ // NSString containing the local name of a peripheral.
+ NSObject *value = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey];
+ if (value && [value isKindOfClass:[NSString class]])
+ localName = QString::fromNSString(static_cast<NSString *>(value));
+
+ // ... constant CBAdvertisementDataServiceUUIDsKey ...
+ // A list of one or more CBUUID objects, representing CBService UUIDs.
+
+ value = [advertisementData objectForKey:CBAdvertisementDataServiceUUIDsKey];
+ if (value && [value isKindOfClass:[NSArray class]]) {
+ NSArray *uuids = static_cast<NSArray *>(value);
+ for (CBUUID *cbUuid in uuids)
+ serviceUuids << qt_uuid(cbUuid);
+ }
+}
+
}
QT_END_NAMESPACE
@@ -90,7 +130,6 @@ QT_USE_NAMESPACE
if (self = [super init]) {
Q_ASSERT(aNotifier);
notifier = aNotifier;
- uuids.reset([[NSMutableSet alloc] init]);
internalState = InquiryStarting;
inquiryTimeoutMS = OSXBluetooth::defaultLEScanTimeoutMS;
}
@@ -300,8 +339,6 @@ QT_USE_NAMESPACE
advertisementData:(NSDictionary *)advertisementData
RSSI:(NSNumber *)RSSI
{
- Q_UNUSED(advertisementData);
-
using namespace OSXBluetooth;
if (central != manager)
@@ -320,14 +357,6 @@ QT_USE_NAMESPACE
return;
}
- if ([uuids containsObject:peripheral.identifier]) {
- // TODO: my understanding of the same peripheral reported many times seems
- // to be outdated or even wrong - nowadays it's reported twice and the
- // second time (AFAIK) more info can be extracted ...
- return;
- }
-
- [uuids addObject:peripheral.identifier];
deviceUuid = OSXBluetooth::qt_uuid(peripheral.identifier);
if (deviceUuid.isNull()) {
@@ -339,10 +368,20 @@ QT_USE_NAMESPACE
if (peripheral.name)
name = QString::fromNSString(peripheral.name);
+ const AdvertisementData qtAdvData(advertisementData);
+ if (!name.size()) // Probably, it's not possible to have one and not the other.
+ name = qtAdvData.localName;
+
// TODO: fix 'classOfDevice' (0 for now).
QBluetoothDeviceInfo newDeviceInfo(deviceUuid, name, 0);
if (RSSI)
newDeviceInfo.setRssi([RSSI shortValue]);
+
+ if (qtAdvData.serviceUuids.size()) {
+ newDeviceInfo.setServiceUuids(qtAdvData.serviceUuids,
+ QBluetoothDeviceInfo::DataIncomplete);
+ }
+
// CoreBluetooth scans only for LE devices.
newDeviceInfo.setCoreConfigurations(QBluetoothDeviceInfo::LowEnergyCoreConfiguration);
emit notifier->deviceDiscovered(newDeviceInfo);
diff --git a/src/bluetooth/osx/osxbtledeviceinquiry_p.h b/src/bluetooth/osx/osxbtledeviceinquiry_p.h
index b58904e6..fc787a6d 100644
--- a/src/bluetooth/osx/osxbtledeviceinquiry_p.h
+++ b/src/bluetooth/osx/osxbtledeviceinquiry_p.h
@@ -93,7 +93,6 @@ enum LEInquiryState
@interface QT_MANGLE_NAMESPACE(OSXBTLEDeviceInquiry) : NSObject
{
LECBManagerNotifier *notifier;
- ObjCScopedPointer<NSMutableSet> uuids;
ObjCScopedPointer<CBCentralManager> manager;
QList<QBluetoothDeviceInfo> devices;