summaryrefslogtreecommitdiffstats
path: root/src/bluetooth
diff options
context:
space:
mode:
Diffstat (limited to 'src/bluetooth')
-rw-r--r--src/bluetooth/bluetooth.pro2
-rw-r--r--src/bluetooth/bluez/bluez.pri13
-rw-r--r--src/bluetooth/bluez/bluez5_helper.cpp191
-rw-r--r--src/bluetooth/bluez/bluez5_helper_p.h8
-rw-r--r--src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp99
5 files changed, 36 insertions, 277 deletions
diff --git a/src/bluetooth/bluetooth.pro b/src/bluetooth/bluetooth.pro
index 95c7ae19..9caaf794 100644
--- a/src/bluetooth/bluetooth.pro
+++ b/src/bluetooth/bluetooth.pro
@@ -72,8 +72,6 @@ config_bluez:qtHaveModule(dbus) {
qbluetoothlocaldevice_bluez.cpp \
qbluetoothtransferreply_bluez.cpp
- CONFIG += link_pkgconfig
- PKGCONFIG_PRIVATE += bluez
} else:CONFIG(blackberry) {
DEFINES += QT_QNX_BLUETOOTH
diff --git a/src/bluetooth/bluez/bluez.pri b/src/bluetooth/bluez/bluez.pri
index 6079c267..be5a02a7 100644
--- a/src/bluetooth/bluez/bluez.pri
+++ b/src/bluetooth/bluez/bluez.pri
@@ -1,16 +1,3 @@
-linux-*: {
- # bluetooth.h is not standards compliant
- contains(QMAKE_CXXFLAGS, -std=c++0x) {
- QMAKE_CXXFLAGS -= -std=c++0x
- QMAKE_CXXFLAGS += -std=gnu++0x
- CONFIG -= c++11
- }
- c++11 {
- CONFIG -= c++11
- QMAKE_CXXFLAGS += -std=gnu++0x
- }
-}
-
HEADERS += bluez/manager_p.h \
bluez/adapter_p.h \
bluez/device_p.h \
diff --git a/src/bluetooth/bluez/bluez5_helper.cpp b/src/bluetooth/bluez/bluez5_helper.cpp
index c00ac5aa..4e810d55 100644
--- a/src/bluetooth/bluez/bluez5_helper.cpp
+++ b/src/bluetooth/bluez/bluez5_helper.cpp
@@ -46,8 +46,6 @@
#include "objectmanager_p.h"
#include "properties_p.h"
#include "adapter1_bluez5_p.h"
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
QT_BEGIN_NAMESPACE
@@ -271,194 +269,6 @@ void QtBluezDiscoveryManager::removeAdapterFromMonitoring(const QString &dbusPat
emit discoveryInterrupted(dbusPath);
}
-#define BUFFER_SIZE 1024
-
-static void parseAttributeValues(sdp_data_t *data, int indentation, QByteArray &xmlOutput)
-{
- if (!data)
- return;
-
- const int length = indentation*2 + 1;
- QByteArray indentString(length, ' ');
-
- char snBuffer[BUFFER_SIZE];
-
- xmlOutput.append(indentString);
-
- // deal with every dtd type
- switch (data->dtd) {
- case SDP_DATA_NIL:
- xmlOutput.append("<nil/>\n");
- break;
- case SDP_UINT8:
- qsnprintf(snBuffer, BUFFER_SIZE, "<uint8 value=\"0x%02x\"/>\n", data->val.uint8);
- xmlOutput.append(snBuffer);
- break;
- case SDP_UINT16:
- qsnprintf(snBuffer, BUFFER_SIZE, "<uint16 value=\"0x%04x\"/>\n", data->val.uint16);
- xmlOutput.append(snBuffer);
- break;
- case SDP_UINT32:
- qsnprintf(snBuffer, BUFFER_SIZE, "<uint32 value=\"0x%08x\"/>\n", data->val.uint32);
- xmlOutput.append(snBuffer);
- break;
- case SDP_UINT64:
- qsnprintf(snBuffer, BUFFER_SIZE, "<uint64 value=\"0x%016x\"/>\n", data->val.uint64);
- xmlOutput.append(snBuffer);
- break;
- case SDP_UINT128:
- xmlOutput.append("<uint128 value=\"0x");
- for (int i = 0; i < 16; i++)
- ::sprintf(&snBuffer[i * 2], "%02x", data->val.uint128.data[i]);
- xmlOutput.append(snBuffer);
- xmlOutput.append("\"/>\n");
- break;
- case SDP_INT8:
- qsnprintf(snBuffer, BUFFER_SIZE, "<int8 value=\"%d\"/>/n", data->val.int8);
- xmlOutput.append(snBuffer);
- break;
- case SDP_INT16:
- qsnprintf(snBuffer, BUFFER_SIZE, "<int16 value=\"%d\"/>/n", data->val.int16);
- xmlOutput.append(snBuffer);
- break;
- case SDP_INT32:
- qsnprintf(snBuffer, BUFFER_SIZE, "<int32 value=\"%d\"/>/n", data->val.int32);
- xmlOutput.append(snBuffer);
- break;
- case SDP_INT64:
- qsnprintf(snBuffer, BUFFER_SIZE, "<int64 value=\"%d\"/>/n", data->val.int64);
- xmlOutput.append(snBuffer);
- break;
- case SDP_INT128:
- xmlOutput.append("<int128 value=\"0x");
- for (int i = 0; i < 16; i++)
- ::sprintf(&snBuffer[i * 2], "%02x", data->val.int128.data[i]);
- xmlOutput.append(snBuffer);
- xmlOutput.append("\"/>\n");
- break;
- case SDP_UUID_UNSPEC:
- break;
- case SDP_UUID16:
- case SDP_UUID32:
- xmlOutput.append("<uuid value=\"0x");
- sdp_uuid2strn(&(data->val.uuid), snBuffer, BUFFER_SIZE);
- xmlOutput.append(snBuffer);
- xmlOutput.append("\"/>\n");
- break;
- case SDP_UUID128:
- xmlOutput.append("<uuid value=\"");
- sdp_uuid2strn(&(data->val.uuid), snBuffer, BUFFER_SIZE);
- xmlOutput.append(snBuffer);
- xmlOutput.append("\"/>\n");
- break;
- case SDP_TEXT_STR_UNSPEC:
- break;
- case SDP_TEXT_STR8:
- case SDP_TEXT_STR16:
- case SDP_TEXT_STR32:
- {
- xmlOutput.append("<text ");
- QByteArray text = QByteArray::fromRawData(data->val.str, data->unitSize);
-
- bool hasNonPrintableChar = false;
- for (int i = 0; i < text.count() && !hasNonPrintableChar; i++) {
- if (!isprint(text[i])) {
- hasNonPrintableChar = true;
- break;
- }
- }
-
- if (hasNonPrintableChar) {
- xmlOutput.append("encoding=\"hex\" value=\"");
- xmlOutput.append(text.toHex());
- } else {
- text.replace("&", "&amp");
- text.replace("<", "&lt");
- text.replace(">", "&gt");
- text.replace("\"", "&quot");
-
- xmlOutput.append("value=\"");
- xmlOutput.append(text);
- }
-
- xmlOutput.append("\"/>\n");
- break;
- }
- case SDP_BOOL:
- if (data->val.uint8)
- xmlOutput.append("<boolean value=\"true\"/>\n");
- else
- xmlOutput.append("<boolean value=\"false\"/>\n");
- break;
- case SDP_SEQ_UNSPEC:
- break;
- case SDP_SEQ8:
- case SDP_SEQ16:
- case SDP_SEQ32:
- xmlOutput.append("<sequence>\n");
- parseAttributeValues(data->val.dataseq, indentation + 1, xmlOutput);
- xmlOutput.append(indentString);
- xmlOutput.append("</sequence>\n");
- break;
- case SDP_ALT_UNSPEC:
- break;
- case SDP_ALT8:
- case SDP_ALT16:
- case SDP_ALT32:
- xmlOutput.append("<alternate>\n");
- parseAttributeValues(data->val.dataseq, indentation + 1, xmlOutput);
- xmlOutput.append(indentString);
- xmlOutput.append("</alternate>\n");
- break;
- case SDP_URL_STR_UNSPEC:
- break;
- case SDP_URL_STR8:
- case SDP_URL_STR16:
- case SDP_URL_STR32:
- strncpy(snBuffer, data->val.str, data->unitSize - 1);
- xmlOutput.append("<url value=\"");
- xmlOutput.append(snBuffer);
- xmlOutput.append("\"/>\n");
- break;
- default:
- qDebug(QT_BT_BLUEZ) << "Unknown dtd type";
- }
-
- parseAttributeValues(data->next, indentation, xmlOutput);
-}
-
-static void parseAttribute(void *value, void *extraData)
-{
- sdp_data_t *data = (sdp_data_t *) value;
- QByteArray *xmlOutput = static_cast<QByteArray *>(extraData);
-
- char buffer[BUFFER_SIZE];
-
- ::qsnprintf(buffer, BUFFER_SIZE, " <attribute id=\"0x%04x\">\n", data->attrId);
- xmlOutput->append(buffer);
-
- parseAttributeValues(data, 2, *xmlOutput);
-
- xmlOutput->append(" </attribute>\n");
-}
-
-// the resulting xml output is based on the already used xml parser
-QByteArray parseSdpRecord(sdp_record_t *record)
-{
- if (!record || !record->attrlist)
- return QByteArray();
-
- QByteArray xmlOutput;
-
- xmlOutput.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<record>\n");
-
- sdp_list_foreach(record->attrlist, parseAttribute, &xmlOutput);
- xmlOutput.append("</record>");
-
- return xmlOutput;
-}
-
-
/*!
Finds the path for the local adapter with \a wantedAddress or an empty string
if no local adapter with the given address can be found.
@@ -518,5 +328,4 @@ QString findAdapterForAddress(const QBluetoothAddress &wantedAddress, bool *ok =
return QString(); // nothing matching found
}
-
QT_END_NAMESPACE
diff --git a/src/bluetooth/bluez/bluez5_helper_p.h b/src/bluetooth/bluez/bluez5_helper_p.h
index d8d0ef01..4bec440e 100644
--- a/src/bluetooth/bluez/bluez5_helper_p.h
+++ b/src/bluetooth/bluez/bluez5_helper_p.h
@@ -46,10 +46,6 @@
#include <QtDBus/QtDBus>
#include <QtBluetooth/QBluetoothAddress>
-#ifndef NO_BLUEZ_INCLUDES
-#include <bluetooth/sdp.h>
-#endif
-
typedef QMap<QString, QVariantMap> InterfaceList;
typedef QMap<QDBusObjectPath, InterfaceList> ManagedObjectList;
@@ -60,10 +56,6 @@ QT_BEGIN_NAMESPACE
bool isBluez5();
-#ifndef NO_BLUEZ_INCLUDES
-QByteArray parseSdpRecord(sdp_record_t *record);
-#endif
-
QString findAdapterForAddress(const QBluetoothAddress &wantedAddress, bool *ok);
class QtBluezDiscoveryManagerPrivate;
diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp b/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp
index 4752a0ab..3610d7bc 100644
--- a/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp
+++ b/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp
@@ -49,11 +49,10 @@
#include "bluez/objectmanager_p.h"
#include "bluez/adapter1_bluez5_p.h"
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
-
+#include <QtCore/QFile>
+#include <QtCore/QLibraryInfo>
#include <QtCore/QLoggingCategory>
+#include <QtCore/QProcess>
#include <QtDBus/QDBusPendingCallWatcher>
#include <QtConcurrent/QtConcurrentRun>
@@ -195,76 +194,53 @@ void QBluetoothServiceDiscoveryAgentPrivate::startBluez5(const QBluetoothAddress
/*
* This function runs in a different thread. We need to be very careful what we
* access from here. That's why invokeMethod is used below.
+ *
+ * src/tools/sdpscanner performs an SDP scan. This is
+ * done out-of-process to avoid license issues. At this stage Bluez uses GPLv2.
*/
void QBluetoothServiceDiscoveryAgentPrivate::runSdpScan(
const QBluetoothAddress &remoteAddress, const QBluetoothAddress localAddress)
{
Q_Q(QBluetoothServiceDiscoveryAgent);
- // connect to SDP server
- bdaddr_t local, remote;
- convertAddress(localAddress.toUInt64(), local.b);
- convertAddress(remoteAddress.toUInt64(), remote.b);
-
- /* We use singleshot timer below because this function runs in a different
- * thread than the rest of this class.
- */
-
- sdp_session_t *session = sdp_connect( &local, &remote, SDP_RETRY_IF_BUSY);
- // try one more time if first attempt fails
- if (!session)
- session = sdp_connect( &local, &remote, SDP_RETRY_IF_BUSY);
+ const QString binPath = QLibraryInfo::location(QLibraryInfo::BinariesPath);
- qCDebug(QT_BT_BLUEZ) << "SDP for" << remoteAddress.toString() << session << qt_error_string(errno);
- if (!session) {
- if (singleDevice) {
- // was sole device without result -> error
- QMetaObject::invokeMethod(q, "_q_finishSdpScan", Qt::QueuedConnection,
+ QFileInfo fileInfo(binPath, QStringLiteral("sdpscanner"));
+ if (!fileInfo.exists() || !fileInfo.isExecutable()) {
+ QMetaObject::invokeMethod(q, "_q_finishSdpScan", Qt::QueuedConnection,
Q_ARG(QBluetoothServiceDiscoveryAgent::Error,
QBluetoothServiceDiscoveryAgent::InputOutputError),
Q_ARG(QString,
- QBluetoothServiceDiscoveryAgent::tr("Unable to access device")),
+ QBluetoothServiceDiscoveryAgent::tr("Unable to find sdpscanner")),
Q_ARG(QStringList, QStringList()));
- } else {
- // go to next device
- QMetaObject::invokeMethod(q, "_q_finishSdpScan", Qt::QueuedConnection,
- Q_ARG(QBluetoothServiceDiscoveryAgent::Error,
- QBluetoothServiceDiscoveryAgent::NoError),
- Q_ARG(QString, QString()),
- Q_ARG(QStringList, QStringList()));
- }
-
+ qCWarning(QT_BT_BLUEZ) << "Cannot find sdpscanner:"
+ << fileInfo.canonicalFilePath();
return;
}
+ QStringList arguments;
+ arguments << remoteAddress.toString() << localAddress.toString();
- // set the filter for service matches
- uuid_t publicBrowseGroupUuid;
- sdp_uuid16_create(&publicBrowseGroupUuid, QBluetoothUuid::PublicBrowseGroup);
- sdp_list_t *serviceFilter;
- serviceFilter = sdp_list_append(0, &publicBrowseGroupUuid);
-
- uint32_t attributeRange = 0x0000ffff; //all attributes
- sdp_list_t *attributes;
- attributes = sdp_list_append(0, &attributeRange);
+ QProcess process;
+ process.setProcessChannelMode(QProcess::ForwardedErrorChannel);
+ process.setReadChannel(QProcess::StandardOutput);
+ process.start(fileInfo.canonicalFilePath(), arguments);
+ process.waitForFinished();
- sdp_list_t* sdpResults;
- int result = sdp_service_search_attr_req(session, serviceFilter, SDP_ATTR_REQ_RANGE,
- attributes, &sdpResults);
- sdp_list_free(attributes, 0);
- sdp_list_free(serviceFilter, 0);
-
- if (result != 0) {
- qCDebug(QT_BT_BLUEZ) << "SDP search failed" << qt_error_string(errno);
- sdp_close(session);
+ if (process.exitStatus() != QProcess::NormalExit
+ || process.exitCode() != 0) {
+ qCWarning(QT_BT_BLUEZ) << "SDP scan failure"
+ << process.exitStatus() << process.exitCode()
+ << remoteAddress;
if (singleDevice) {
QMetaObject::invokeMethod(q, "_q_finishSdpScan", Qt::QueuedConnection,
Q_ARG(QBluetoothServiceDiscoveryAgent::Error,
QBluetoothServiceDiscoveryAgent::InputOutputError),
Q_ARG(QString,
- QBluetoothServiceDiscoveryAgent::tr("Unable to access device")),
+ QBluetoothServiceDiscoveryAgent::tr("Unable to perform SDP scan")),
Q_ARG(QStringList, QStringList()));
} else {
+ // go to next device
QMetaObject::invokeMethod(q, "_q_finishSdpScan", Qt::QueuedConnection,
Q_ARG(QBluetoothServiceDiscoveryAgent::Error,
QBluetoothServiceDiscoveryAgent::NoError),
@@ -274,23 +250,20 @@ void QBluetoothServiceDiscoveryAgentPrivate::runSdpScan(
return;
}
- qCDebug(QT_BT_BLUEZ) << "SDP search a success. Iterating results" << sdpResults;
QStringList xmlRecords;
- // process the results
- for ( ; sdpResults; sdpResults = sdpResults->next) {
- sdp_record_t *record = (sdp_record_t *) sdpResults->data;
+ int size, index = 0;
+ const QByteArray output = QByteArray::fromBase64(process.readAll());
+ const char *data = output.constData();
- QByteArray xml = parseSdpRecord(record);
- if (xml.isEmpty())
- continue;
-
- //qDebug() << xml;
- xmlRecords.append(QString::fromUtf8(xml));
+ // separate the individial SDP records
+ // each record starts with 4 byte size indicator
+ while (index < output.size()) {
+ memcpy(&size, &data[index], sizeof(int));
+ xmlRecords.append(QString::fromUtf8(output.mid(index+sizeof(int), size)));
+ index += sizeof(int) + size;
}
- sdp_close(session);
-
QMetaObject::invokeMethod(q, "_q_finishSdpScan", Qt::QueuedConnection,
Q_ARG(QBluetoothServiceDiscoveryAgent::Error,
QBluetoothServiceDiscoveryAgent::NoError),