From dfee9aa22f2dbaae3476770d0ab65f26494fe451 Mon Sep 17 00:00:00 2001
From: Alex Blasche <alexander.blasche@qt.io>
Date: Thu, 11 Oct 2018 17:31:54 +0200
Subject: [PATCH] Fix the BluetoothProfileDescriptorStructure

As per spec this is meant to be a list/sequence within a sequence and
the version was missing too. For simplicity version 1.0 is used.

Fixes: QTBUG-58529
Change-Id: I57090148aadf60ea1fbbb207ff0a4ae61e06caf2
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
---
 examples/bluetooth/btchat/chatserver.cpp        | 10 +++++++---
 src/bluetooth/qbluetoothserver.cpp              |  9 +++++++--
 src/bluetooth/qbluetoothserver_osx.mm           |  9 +++++++--
 .../qbluetoothservicediscoveryagent_android.cpp | 17 +++++++++++++----
 .../tst_qbluetoothservicediscoveryagent.cpp     |  6 ++++--
 tests/bttestui/btlocaldevice.cpp                |  9 +++++++--
 6 files changed, 45 insertions(+), 15 deletions(-)

diff --git a/examples/bluetooth/btchat/chatserver.cpp b/examples/bluetooth/btchat/chatserver.cpp
index 683dfb94..d078a32c 100644
--- a/examples/bluetooth/btchat/chatserver.cpp
+++ b/examples/bluetooth/btchat/chatserver.cpp
@@ -85,13 +85,17 @@ void ChatServer::startServer(const QBluetoothAddress& localAdapter)
 
     //serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceRecordHandle, (uint)0x00010010);
 
+    QBluetoothServiceInfo::Sequence profileSequence;
     QBluetoothServiceInfo::Sequence classId;
-
     classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
+    classId << QVariant::fromValue(quint16(0x100));
+    profileSequence.append(QVariant::fromValue(classId));
     serviceInfo.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList,
-                             classId);
+                             profileSequence);
 
-    classId.prepend(QVariant::fromValue(QBluetoothUuid(serviceUuid)));
+    classId.clear();
+    classId << QVariant::fromValue(QBluetoothUuid(serviceUuid));
+    classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
 
     serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId);
 
diff --git a/src/bluetooth/qbluetoothserver.cpp b/src/bluetooth/qbluetoothserver.cpp
index d9e42adf..8f760eed 100644
--- a/src/bluetooth/qbluetoothserver.cpp
+++ b/src/bluetooth/qbluetoothserver.cpp
@@ -217,13 +217,18 @@ QBluetoothServiceInfo QBluetoothServer::listen(const QBluetoothUuid &uuid, const
     serviceInfo.setAttribute(QBluetoothServiceInfo::BrowseGroupList,
                              browseSequence);
 
+    QBluetoothServiceInfo::Sequence profileSequence;
     QBluetoothServiceInfo::Sequence classId;
     classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
+    classId << QVariant::fromValue(quint16(0x100));
+    profileSequence.append(QVariant::fromValue(classId));
     serviceInfo.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList,
-                             classId);
+                             profileSequence);
 
+    classId.clear();
     //Android requires custom uuid to be set as service class
-    classId.prepend(QVariant::fromValue(uuid));
+    classId << QVariant::fromValue(uuid);
+    classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
     serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId);
     serviceInfo.setServiceUuid(uuid);
 
diff --git a/src/bluetooth/qbluetoothserver_osx.mm b/src/bluetooth/qbluetoothserver_osx.mm
index d7f29ed3..a6768432 100644
--- a/src/bluetooth/qbluetoothserver_osx.mm
+++ b/src/bluetooth/qbluetoothserver_osx.mm
@@ -380,11 +380,16 @@ QBluetoothServiceInfo QBluetoothServer::listen(const QBluetoothUuid &uuid, const
     serviceInfo.setAttribute(QSInfo::BrowseGroupList,
                              QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup));
 
+    QSInfo::Sequence profileSequence;
     QSInfo::Sequence classId;
     classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
-    serviceInfo.setAttribute(QSInfo::BluetoothProfileDescriptorList, classId);
+    classId << QVariant::fromValue(quint16(0x100));
+    profileSequence.append(QVariant::fromValue(classId));
+    serviceInfo.setAttribute(QSInfo::BluetoothProfileDescriptorList, profileSequence);
 
-    classId.prepend(QVariant::fromValue(uuid));
+    classId.clear();
+    classId << QVariant::fromValue(uuid);
+    classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
     serviceInfo.setAttribute(QSInfo::ServiceClassIds, classId);
     serviceInfo.setServiceUuid(uuid);
 
diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp b/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp
index ac2b1906..f8201c86 100644
--- a/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp
+++ b/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp
@@ -370,12 +370,18 @@ void QBluetoothServiceDiscoveryAgentPrivate::populateDiscoveredServices(const QB
                      << QVariant::fromValue(0);
             protocolDescriptorList.append(QVariant::fromValue(protocol));
 
-            //set SPP service class uuid
+            QBluetoothServiceInfo::Sequence profileSequence;
             QBluetoothServiceInfo::Sequence classId;
             classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
+            classId << QVariant::fromValue(quint16(0x100));
+            profileSequence.append(QVariant::fromValue(classId));
             serviceInfo.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList,
-                                     classId);
-            classId.prepend(QVariant::fromValue(uuids.at(i)));
+                                     profileSequence);
+
+            classId.clear();
+            //set SPP service class uuid
+            classId << QVariant::fromValue(uuids.at(i));
+            classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
             serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId);
 
             serviceInfo.setServiceName(QBluetoothServiceDiscoveryAgent::tr("Serial Port Profile"));
@@ -387,10 +393,13 @@ void QBluetoothServiceDiscoveryAgentPrivate::populateDiscoveredServices(const QB
                      << QVariant::fromValue(0);
             protocolDescriptorList.append(QVariant::fromValue(protocol));
 
+            QBluetoothServiceInfo::Sequence profileSequence;
             QBluetoothServiceInfo::Sequence classId;
             classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
+            classId << QVariant::fromValue(quint16(0x100));
+            profileSequence.append(QVariant::fromValue(classId));
             serviceInfo.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList,
-                                     classId);
+                                     profileSequence);
 
             //also we need to set the custom uuid to the SPP uuid
             //otherwise QBluetoothSocket::connectToService() would fail due to a missing service uuid
diff --git a/tests/auto/qbluetoothservicediscoveryagent/tst_qbluetoothservicediscoveryagent.cpp b/tests/auto/qbluetoothservicediscoveryagent/tst_qbluetoothservicediscoveryagent.cpp
index 25764703..9bac6791 100644
--- a/tests/auto/qbluetoothservicediscoveryagent/tst_qbluetoothservicediscoveryagent.cpp
+++ b/tests/auto/qbluetoothservicediscoveryagent/tst_qbluetoothservicediscoveryagent.cpp
@@ -289,11 +289,13 @@ void tst_QBluetoothServiceDiscoveryAgent::tst_serviceDiscoveryAdapters()
         serviceInfo.setAttribute(QBluetoothServiceInfo::BrowseGroupList,
                                  QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup));
 
+        QBluetoothServiceInfo::Sequence profileSequence;
         QBluetoothServiceInfo::Sequence classId;
         classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
-        serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId);
+        classId << QVariant::fromValue(quint16(0x100));
+        profileSequence.append(QVariant::fromValue(classId));
         serviceInfo.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList,
-                                 classId);
+                                 profileSequence);
 
         serviceInfo.setServiceUuid(uuid);
 
diff --git a/tests/bttestui/btlocaldevice.cpp b/tests/bttestui/btlocaldevice.cpp
index 3f0ebdaf..d7590b70 100644
--- a/tests/bttestui/btlocaldevice.cpp
+++ b/tests/bttestui/btlocaldevice.cpp
@@ -576,12 +576,17 @@ void BtLocalDevice::serverListenPort()
         if (!ret)
             return;
 
+        QBluetoothServiceInfo::Sequence profileSequence;
         QBluetoothServiceInfo::Sequence classId;
         classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
+        classId << QVariant::fromValue(quint16(0x100));
+        profileSequence.append(QVariant::fromValue(classId));
         serviceInfo.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList,
-                                 classId);
+                                 profileSequence);
 
-        classId.prepend(QVariant::fromValue(QBluetoothUuid(QString(TEST_SERVICE_UUID))));
+        classId.clear();
+        classId << QVariant::fromValue(QBluetoothUuid(QString(TEST_SERVICE_UUID)));
+        classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
         serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId);
 
         // Service name, description and provider
-- 
GitLab