diff options
Diffstat (limited to 'src/bluetooth')
-rw-r--r-- | src/bluetooth/bluetooth.pro | 2 | ||||
-rw-r--r-- | src/bluetooth/bluez/bluez.pri | 13 | ||||
-rw-r--r-- | src/bluetooth/bluez/bluez5_helper.cpp | 191 | ||||
-rw-r--r-- | src/bluetooth/bluez/bluez5_helper_p.h | 8 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp | 99 |
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("&", "&"); - text.replace("<", "<"); - text.replace(">", ">"); - text.replace("\"", """); - - 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), |