diff options
author | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2018-10-10 15:41:45 +0200 |
---|---|---|
committer | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2018-10-11 07:44:07 +0000 |
commit | c9ed3c49e3884ffad899d7ae28b2480691824228 (patch) | |
tree | 2258a7f62e229dc4293a9c3a12f2a115f92dea51 /src/bluetooth/osx | |
parent | db8c876c7478114a888947ce1f36e8a2a80e8ed2 (diff) |
SDP records: handle ServiceID and ServiceClassIDList correctly (IOBluetooth)v5.12.0-beta2
We previously failed to correctly extract service ID and service
class ID list. As a result, service discovery agent working with
uuid filter and in MinimalDiscovery mode would fail to find anything,
without filtering - would probably end up in services not having
any valid service ID or ID list.
Task-number: QTBUG-71052
Change-Id: I6b5a36399abfaf66297abe4a38efa7659cbb2aa0
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'src/bluetooth/osx')
-rw-r--r-- | src/bluetooth/osx/osxbtsdpinquiry.mm | 79 |
1 files changed, 74 insertions, 5 deletions
diff --git a/src/bluetooth/osx/osxbtsdpinquiry.mm b/src/bluetooth/osx/osxbtsdpinquiry.mm index 6df2d16e..23d1bd84 100644 --- a/src/bluetooth/osx/osxbtsdpinquiry.mm +++ b/src/bluetooth/osx/osxbtsdpinquiry.mm @@ -53,6 +53,64 @@ SDPInquiryDelegate::~SDPInquiryDelegate() { } +namespace { + +QBluetoothUuid sdp_element_to_uuid(IOBluetoothSDPDataElement *element) +{ + QT_BT_MAC_AUTORELEASEPOOL; + + if (!element || [element getTypeDescriptor] != kBluetoothSDPDataElementTypeUUID) + return {}; + + return qt_uuid([[element getUUIDValue] getUUIDWithLength:16]); +} + +QBluetoothUuid extract_service_ID(IOBluetoothSDPServiceRecord *record) +{ + Q_ASSERT(record); + + QT_BT_MAC_AUTORELEASEPOOL; + + return sdp_element_to_uuid([record getAttributeDataElement:kBluetoothSDPAttributeIdentifierServiceID]); +} + +QVector<QBluetoothUuid> extract_service_class_ID_list(IOBluetoothSDPServiceRecord *record) +{ + Q_ASSERT(record); + + QT_BT_MAC_AUTORELEASEPOOL; + + IOBluetoothSDPDataElement *const idList = [record getAttributeDataElement:kBluetoothSDPAttributeIdentifierServiceClassIDList]; + if (!idList || [idList getTypeDescriptor] != kBluetoothSDPDataElementTypeDataElementSequence) + return {}; + + QVector<QBluetoothUuid> uuids; + NSArray *const arr = [idList getArrayValue]; + for (IOBluetoothSDPDataElement *dataElement in arr) { + const auto qtUuid = sdp_element_to_uuid(dataElement); + if (!qtUuid.isNull()) + uuids.push_back(qtUuid); + } + + return uuids; +} + +QBluetoothServiceInfo::Sequence service_class_ID_list_to_sequence(const QVector<QBluetoothUuid> &uuids) +{ + if (uuids.isEmpty()) + return {}; + + QBluetoothServiceInfo::Sequence sequence; + for (const auto &uuid : uuids) { + Q_ASSERT(!uuid.isNull()); + sequence.append(QVariant::fromValue(uuid)); + } + + return sequence; +} + +} // unnamed namespace + QVariant extract_attribute_value(IOBluetoothSDPDataElement *dataElement) { Q_ASSERT_X(dataElement, Q_FUNC_INFO, "invalid data element (nil)"); @@ -72,7 +130,7 @@ QVariant extract_attribute_value(IOBluetoothSDPDataElement *dataElement) case kBluetoothSDPDataElementTypeSignedInt: return [[dataElement getNumberValue] intValue]; case kBluetoothSDPDataElementTypeUUID: - return QVariant::fromValue(qt_uuid([[dataElement getUUIDValue] getUUIDWithLength:16])); + return QVariant::fromValue(sdp_element_to_uuid(dataElement)); case kBluetoothSDPDataElementTypeString: case kBluetoothSDPDataElementTypeURL: return QString::fromNSString([dataElement getStringValue]); @@ -110,6 +168,15 @@ void extract_service_record(IOBluetoothSDPServiceRecord *record, QBluetoothServi const QVariant attributeValue = OSXBluetooth::extract_attribute_value(element); serviceInfo.setAttribute(attributeID, attributeValue); } + + const QBluetoothUuid serviceUuid = extract_service_ID(record); + if (!serviceUuid.isNull()) + serviceInfo.setServiceUuid(serviceUuid); + + const QVector<QBluetoothUuid> uuids(extract_service_class_ID_list(record)); + const auto sequence = service_class_ID_list_to_sequence(uuids); + if (!sequence.isEmpty()) + serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceClassIds, sequence); } QList<QBluetoothUuid> extract_services_uuids(IOBluetoothDevice *device) @@ -124,11 +191,13 @@ QList<QBluetoothUuid> extract_services_uuids(IOBluetoothDevice *device) NSArray * const records = device.services; for (IOBluetoothSDPServiceRecord *record in records) { - IOBluetoothSDPDataElement *const element = - [record getAttributeDataElement:kBluetoothSDPAttributeIdentifierServiceClassIDList]; + const QBluetoothUuid serviceID = extract_service_ID(record); + if (!serviceID.isNull()) + uuids.push_back(serviceID); - if (element && [element getTypeDescriptor] == kBluetoothSDPDataElementTypeUUID) - uuids.append(qt_uuid([[element getUUIDValue] getUUIDWithLength:16])); + const QVector<QBluetoothUuid> idList(extract_service_class_ID_list(record)); + if (idList.size()) + uuids.append(idList.toList()); } return uuids; |