diff options
author | Alex Blasche <alexander.blasche@digia.com> | 2014-05-07 16:56:17 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-05-22 09:07:46 +0200 |
commit | 26e9cf5bc608c7b50fc27a73442966b3880f0825 (patch) | |
tree | d5a845e0052c5f65b159a7442724b10ecba7e4d6 /src/bluetooth/bluez | |
parent | 91914f0c1f69f3cd79518333cf088a141bb721a0 (diff) |
Service discovery via Bluez5
At the same time we shift the ServiceClassUUID to service name mapping
to QBluetoothUuid. It was used by Android and now Bluez 5 uses it too.
Task-number: QTBUG-32085
Change-Id: I9f2d4dc4e2997683485f2ba7aaefb646cb72fb75
Reviewed-by: Aaron McCarthy <mccarthy.aaron@gmail.com>
Diffstat (limited to 'src/bluetooth/bluez')
-rw-r--r-- | src/bluetooth/bluez/bluez5_helper.cpp | 188 | ||||
-rw-r--r-- | src/bluetooth/bluez/bluez5_helper_p.h | 3 |
2 files changed, 191 insertions, 0 deletions
diff --git a/src/bluetooth/bluez/bluez5_helper.cpp b/src/bluetooth/bluez/bluez5_helper.cpp index 7a20abac..c995d948 100644 --- a/src/bluetooth/bluez/bluez5_helper.cpp +++ b/src/bluetooth/bluez/bluez5_helper.cpp @@ -46,6 +46,7 @@ #include "objectmanager_p.h" #include "properties_p.h" #include "adapter1_bluez5_p.h" +#include <bluetooth/sdp_lib.h> QT_BEGIN_NAMESPACE @@ -269,4 +270,191 @@ 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; +} + QT_END_NAMESPACE diff --git a/src/bluetooth/bluez/bluez5_helper_p.h b/src/bluetooth/bluez/bluez5_helper_p.h index 49abc4af..2429c09c 100644 --- a/src/bluetooth/bluez/bluez5_helper_p.h +++ b/src/bluetooth/bluez/bluez5_helper_p.h @@ -44,6 +44,7 @@ #include <QtCore/QObject> #include <QtDBus/QtDBus> +#include <bluetooth/sdp.h> typedef QMap<QString, QVariantMap> InterfaceList; typedef QMap<QDBusObjectPath, InterfaceList> ManagedObjectList; @@ -55,6 +56,8 @@ QT_BEGIN_NAMESPACE bool isBluez5(); +QByteArray parseSdpRecord(sdp_record_t *record); + class QtBluezDiscoveryManagerPrivate; class QtBluezDiscoveryManager : public QObject { |