diff options
author | Alex Blasche <alexander.blasche@digia.com> | 2014-08-25 13:40:04 +0200 |
---|---|---|
committer | Alex Blasche <alexander.blasche@digia.com> | 2014-08-27 16:54:57 +0200 |
commit | 167faeec86ed4d9c9f099f5180784c7b0cb9aa42 (patch) | |
tree | 222fe4af432a6b77e13513847f618e2216881661 | |
parent | 8a33a9b43dcc5e7f9a77237a660a3759286e6b86 (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.2 | 2 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothserver.cpp | 4 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothsocket.cpp | 4 | ||||
-rw-r--r-- | tests/bttestui/btlocaldevice.cpp | 22 |
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(); |