diff options
Diffstat (limited to 'src/bluetooth/qbluetoothservicediscoveryagent_android.cpp')
-rw-r--r-- | src/bluetooth/qbluetoothservicediscoveryagent_android.cpp | 91 |
1 files changed, 50 insertions, 41 deletions
diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp b/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp index ddc53421..3ab0d580 100644 --- a/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp +++ b/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp @@ -47,6 +47,7 @@ #include <QtBluetooth/QBluetoothServiceDiscoveryAgent> #include "qbluetoothservicediscoveryagent_p.h" +#include "qbluetoothsocket_android_p.h" #include "android/servicediscoverybroadcastreceiver_p.h" #include "android/localdevicebroadcastreceiver_p.h" @@ -335,42 +336,62 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_processFetchedUuids( void QBluetoothServiceDiscoveryAgentPrivate::populateDiscoveredServices(const QBluetoothDeviceInfo &remoteDevice, const QList<QBluetoothUuid> &uuids) { - /* Android doesn't provide decent SDP data. A list of uuids is close to meaning-less + /* Android doesn't provide decent SDP data. A flat list of uuids is all we get. * * The following approach is chosen: * - If we see an SPP service class and we see - * one or more custom uuids we match them up. Such services will always be SPP services. + * one or more custom uuids we match them up. Such services will always + * be SPP services. There is the chance that a custom uuid is eronously + * mapped as being an SPP service. In addition, the SPP uuid will be mapped as + * standalone SPP service. * - If we see a custom uuid but no SPP uuid then we return - * BluetoothServiceInfo instance with just a servuceUuid (no service class set) + * BluetoothServiceInfo instance with just a serviceUuid (no service class set) + * - If we don't find any custom uuid but the SPP uuid, we return a + * BluetoothServiceInfo instance where classId and serviceUuid() are set to SPP. * - Any other service uuid will stand on its own. * */ Q_Q(QBluetoothServiceDiscoveryAgent); //find SPP and custom uuid - QBluetoothUuid uuid; - int sppIndex = -1; + bool haveSppClass = false; QVector<int> customUuids; for (int i = 0; i < uuids.count(); i++) { - uuid = uuids.at(i); + const QBluetoothUuid uuid = uuids.at(i); if (uuid.isNull()) continue; //check for SPP protocol bool ok = false; - quint16 uuid16 = uuid.toUInt16(&ok); - if (ok && uuid16 == QBluetoothUuid::SerialPort) - sppIndex = i; + auto uuid16 = uuid.toUInt16(&ok); + haveSppClass |= ok && uuid16 == QBluetoothUuid::SerialPort; //check for custom uuid if (uuid.minimumSize() == 16) customUuids.append(i); } + auto rfcommProtocolDescriptorList = []() -> QBluetoothServiceInfo::Sequence { + QBluetoothServiceInfo::Sequence protocol; + protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm)) + << QVariant::fromValue(0); + return protocol; + }; + + auto sppProfileDescriptorList = []() -> QBluetoothServiceInfo::Sequence { + QBluetoothServiceInfo::Sequence profileSequence; + QBluetoothServiceInfo::Sequence classId; + classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort)); + classId << QVariant::fromValue(quint16(0x100)); + profileSequence.append(QVariant::fromValue(classId)); + return profileSequence; + }; + for (int i = 0; i < uuids.count(); i++) { - if (i == sppIndex && !customUuids.isEmpty()) + const QBluetoothUuid &uuid = uuids.at(i); + if (uuid.isNull()) continue; QBluetoothServiceInfo serviceInfo; @@ -383,52 +404,38 @@ void QBluetoothServiceDiscoveryAgentPrivate::populateDiscoveredServices(const QB protocolDescriptorList.append(QVariant::fromValue(protocol)); } - if (customUuids.contains(i) && sppIndex > -1) { + if (customUuids.contains(i) && haveSppClass) { //we have a custom uuid of service class type SPP //set rfcomm protocol - QBluetoothServiceInfo::Sequence protocol; - protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm)) - << QVariant::fromValue(0); - protocolDescriptorList.append(QVariant::fromValue(protocol)); + protocolDescriptorList.append(QVariant::fromValue(rfcommProtocolDescriptorList())); - QBluetoothServiceInfo::Sequence profileSequence; - QBluetoothServiceInfo::Sequence classId; - classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort)); - classId << QVariant::fromValue(quint16(0x100)); - profileSequence.append(QVariant::fromValue(classId)); + //set SPP profile descriptor list serviceInfo.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList, - profileSequence); + sppProfileDescriptorList()); - classId.clear(); + QBluetoothServiceInfo::Sequence classId; //set SPP service class uuid - classId << QVariant::fromValue(uuids.at(i)); + classId << QVariant::fromValue(uuid); classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort)); serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId); serviceInfo.setServiceName(QBluetoothServiceDiscoveryAgent::tr("Serial Port Profile")); - serviceInfo.setServiceUuid(uuids.at(i)); - } else if (sppIndex == i && customUuids.isEmpty()) { + serviceInfo.setServiceUuid(uuid); + } else if (uuid == QBluetoothUuid{QBluetoothUuid::SerialPort}) { //set rfcomm protocol - QBluetoothServiceInfo::Sequence protocol; - protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm)) - << QVariant::fromValue(0); - protocolDescriptorList.append(QVariant::fromValue(protocol)); + protocolDescriptorList.append(QVariant::fromValue(rfcommProtocolDescriptorList())); - QBluetoothServiceInfo::Sequence profileSequence; - QBluetoothServiceInfo::Sequence classId; - classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort)); - classId << QVariant::fromValue(quint16(0x100)); - profileSequence.append(QVariant::fromValue(classId)); + //set SPP profile descriptor list serviceInfo.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList, - profileSequence); + sppProfileDescriptorList()); //also we need to set the custom uuid to the SPP uuid //otherwise QBluetoothSocket::connectToService() would fail due to a missing service uuid - serviceInfo.setServiceUuid(uuids.at(i)); + serviceInfo.setServiceUuid(uuid); } else if (customUuids.contains(i)) { //custom uuid but no serial port - serviceInfo.setServiceUuid(uuids.at(i)); + serviceInfo.setServiceUuid(uuid); } serviceInfo.setAttribute(QBluetoothServiceInfo::ProtocolDescriptorList, protocolDescriptorList); @@ -439,18 +446,20 @@ void QBluetoothServiceDiscoveryAgentPrivate::populateDiscoveredServices(const QB if (!customUuids.contains(i)) { //if we don't have custom uuid use it as class id as well QBluetoothServiceInfo::Sequence classId; - classId << QVariant::fromValue(uuids.at(i)); + classId << QVariant::fromValue(uuid); serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId); - QBluetoothUuid::ServiceClassUuid clsId - = static_cast<QBluetoothUuid::ServiceClassUuid>(uuids.at(i).toUInt16()); + auto clsId = QBluetoothUuid::ServiceClassUuid(uuid.toUInt16()); serviceInfo.setServiceName(QBluetoothUuid::serviceClassToString(clsId)); } //Check if the service is in the uuidFilter if (!uuidFilter.isEmpty()) { bool match = uuidFilter.contains(serviceInfo.serviceUuid()); - for (const auto &uuid : qAsConst(uuidFilter)) + match |= uuidFilter.contains(QBluetoothSocketPrivateAndroid::reverseUuid(serviceInfo.serviceUuid())); + for (const auto &uuid : qAsConst(uuidFilter)) { match |= serviceInfo.serviceClassUuids().contains(uuid); + match |= serviceInfo.serviceClassUuids().contains(QBluetoothSocketPrivateAndroid::reverseUuid(uuid)); + } if (!match) continue; |