summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Blasche <alexander.blasche@digia.com>2014-08-25 13:40:04 +0200
committerAlex Blasche <alexander.blasche@digia.com>2014-08-27 16:54:57 +0200
commit167faeec86ed4d9c9f099f5180784c7b0cb9aa42 (patch)
tree222fe4af432a6b77e13513847f618e2216881661
parent8a33a9b43dcc5e7f9a77237a660a3759286e6b86 (diff)
Fix L2CP socket connectionsv5.3.2
L2CP's psm (the RFCOMM port equivalent) was never published via SDP. Therefore the service client could not get the required information to connect to the server. After this patch Qt properly publishes the psm. Also, QBluetoothSocket::connect() initiated a service discovery to obtain the missing psm. Since the published SDP entry didn't contain one, protocolServiceMultiplexer() always returned 0 and another service discovery was initiated. This caused a crash inside QBluetoothSocket because the 1st QBluetoothServiceDiscoveryAgent instance was deleted in favor of the 2nd. The patch changes the client behavior such that it doesn't crash if the service discovery didn't turn up a valid psm/port. It improves the robustness in case of an error and avoids a second service discovery (which wouldn't turn up more information anyway). The bug only affected Bluez as it is the only platform supporting pure L2CP sockets. Last but not least a capability to test L2CP sockets was added to bttestui. Change-Id: I46c88a67c2baa4782ea908e645dcd4db9422dbba Reviewed-by: Fabian Bumberger <fbumberger@rim.com>
-rw-r--r--dist/changes-5.3.22
-rw-r--r--src/bluetooth/qbluetoothserver.cpp4
-rw-r--r--src/bluetooth/qbluetoothsocket.cpp4
-rw-r--r--tests/bttestui/btlocaldevice.cpp22
4 files changed, 23 insertions, 9 deletions
diff --git a/dist/changes-5.3.2 b/dist/changes-5.3.2
index 59a52917..e700e85e 100644
--- a/dist/changes-5.3.2
+++ b/dist/changes-5.3.2
@@ -45,3 +45,5 @@ Linux
-----
- Removed undesirable system header includes from the Bluez code base.
+ - Fixed incomplete SDP entries when using L2CP sockets and avoided
+ crash on client side when incomplete SDP entry is encountered.
diff --git a/src/bluetooth/qbluetoothserver.cpp b/src/bluetooth/qbluetoothserver.cpp
index 3123b032..667c3306 100644
--- a/src/bluetooth/qbluetoothserver.cpp
+++ b/src/bluetooth/qbluetoothserver.cpp
@@ -226,6 +226,8 @@ QBluetoothServiceInfo QBluetoothServer::listen(const QBluetoothUuid &uuid, const
QBluetoothServiceInfo::Sequence protocolDescriptorList;
QBluetoothServiceInfo::Sequence protocol;
protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::L2cap));
+ if (d->serverType == QBluetoothServiceInfo::L2capProtocol)
+ protocol << QVariant::fromValue(serverPort());
protocolDescriptorList.append(QVariant::fromValue(protocol));
protocol.clear();
//! [listen]
@@ -233,10 +235,10 @@ QBluetoothServiceInfo QBluetoothServer::listen(const QBluetoothUuid &uuid, const
//! [listen2]
protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm))
<< QVariant::fromValue(quint8(serverPort()));
+ protocolDescriptorList.append(QVariant::fromValue(protocol));
//! [listen2]
}
//! [listen3]
- protocolDescriptorList.append(QVariant::fromValue(protocol));
serviceInfo.setAttribute(QBluetoothServiceInfo::ProtocolDescriptorList,
protocolDescriptorList);
bool result = serviceInfo.registerService();
diff --git a/src/bluetooth/qbluetoothsocket.cpp b/src/bluetooth/qbluetoothsocket.cpp
index 0c514887..87456a2e 100644
--- a/src/bluetooth/qbluetoothsocket.cpp
+++ b/src/bluetooth/qbluetoothsocket.cpp
@@ -572,10 +572,12 @@ void QBluetoothSocket::serviceDiscovered(const QBluetoothServiceInfo &service)
{
Q_D(QBluetoothSocket);
qCDebug(QT_BT) << "FOUND SERVICE!" << service;
- if(service.protocolServiceMultiplexer() != 0 || service.serverChannel() != 0) {
+ if (service.protocolServiceMultiplexer() > 0 || service.serverChannel() > 0) {
connectToService(service, d->openMode);
d->discoveryAgent->deleteLater();
d->discoveryAgent = 0;
+ } else {
+ qCDebug(QT_BT) << "Could not find port/psm for potential remote service";
}
}
diff --git a/tests/bttestui/btlocaldevice.cpp b/tests/bttestui/btlocaldevice.cpp
index 8c85599f..a14709ee 100644
--- a/tests/bttestui/btlocaldevice.cpp
+++ b/tests/bttestui/btlocaldevice.cpp
@@ -49,6 +49,9 @@
//same uuid as examples/bluetooth/btchat
#define TEST_SERVICE_UUID "e8e10f95-1a70-4b27-9ccf-02010264e9c8"
+#define SOCKET_PROTOCOL QBluetoothServiceInfo::RfcommProtocol
+//#define SOCKET_PROTOCOL QBluetoothServiceInfo::L2capProtocol
+
BtLocalDevice::BtLocalDevice(QObject *parent) :
QObject(parent)
{
@@ -87,7 +90,7 @@ BtLocalDevice::BtLocalDevice(QObject *parent) :
connect(serviceAgent, SIGNAL(error(QBluetoothServiceDiscoveryAgent::Error)),
this, SLOT(serviceDiscoveryError(QBluetoothServiceDiscoveryAgent::Error)));
- socket = new QBluetoothSocket(this);
+ socket = new QBluetoothSocket(SOCKET_PROTOCOL, this);
connect(socket, SIGNAL(stateChanged(QBluetoothSocket::SocketState)),
this, SLOT(socketStateChanged(QBluetoothSocket::SocketState)));
connect(socket, SIGNAL(error(QBluetoothSocket::SocketError)),
@@ -96,7 +99,7 @@ BtLocalDevice::BtLocalDevice(QObject *parent) :
connect(socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
connect(socket, SIGNAL(readyRead()), this, SLOT(readData()));
- server = new QBluetoothServer(QBluetoothServiceInfo::RfcommProtocol, this);
+ server = new QBluetoothServer(SOCKET_PROTOCOL, this);
server->setSecurityFlags(QBluetooth::NoSecurity);
connect(server, SIGNAL(newConnection()), this, SLOT(serverNewConnection()));
connect(server, SIGNAL(error(QBluetoothServer::Error)),
@@ -537,16 +540,21 @@ void BtLocalDevice::serverListenPort()
QBluetoothServiceInfo::Sequence protocolDescriptorList;
QBluetoothServiceInfo::Sequence protocol;
protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::L2cap));
+ if (server->serverType() == QBluetoothServiceInfo::L2capProtocol)
+ protocol << QVariant::fromValue(server->serverPort());
protocolDescriptorList.append(QVariant::fromValue(protocol));
- protocol.clear();
- protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm))
- << QVariant::fromValue(quint8(server->serverPort()));
- protocolDescriptorList.append(QVariant::fromValue(protocol));
+
+ if (server->serverType() == QBluetoothServiceInfo::RfcommProtocol) {
+ protocol.clear();
+ protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm))
+ << QVariant::fromValue(quint8(server->serverPort()));
+ protocolDescriptorList.append(QVariant::fromValue(protocol));
+ }
serviceInfo.setAttribute(QBluetoothServiceInfo::ProtocolDescriptorList,
protocolDescriptorList);
//Register service
- qDebug() << "###### Registering service on" << localDevice->address().toString();
+ qDebug() << "###### Registering service on" << localDevice->address().toString() << server->serverPort();
bool result = serviceInfo.registerService(localDevice->address());
if (!result) {
server->close();