summaryrefslogtreecommitdiffstats
path: root/src/tools/sdpscanner/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/sdpscanner/main.cpp')
-rw-r--r--src/tools/sdpscanner/main.cpp140
1 files changed, 110 insertions, 30 deletions
diff --git a/src/tools/sdpscanner/main.cpp b/src/tools/sdpscanner/main.cpp
index 50870651..edca8fa3 100644
--- a/src/tools/sdpscanner/main.cpp
+++ b/src/tools/sdpscanner/main.cpp
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -34,6 +40,7 @@
#include <QtCore/QByteArray>
#include <QtCore/QDebug>
#include <stdio.h>
+#include <string>
#include <bluetooth/bluetooth.h>
#include <bluetooth/sdp.h>
#include <bluetooth/sdp_lib.h>
@@ -46,11 +53,14 @@
void usage()
{
fprintf(stderr, "Usage:\n");
- fprintf(stderr, "\tsdpscanner <remote bdaddr> <local bdaddr> [Options]\n\n");
+ fprintf(stderr, "\tsdpscanner <remote bdaddr> <local bdaddr> [Options] ({uuids})\n\n");
fprintf(stderr, "Performs an SDP scan on remote device, using the SDP server\n"
"represented by the local Bluetooth device.\n\n"
"Options:\n"
- " -p Show scan results in human-readable form\n");
+ " -p Show scan results in human-readable form\n"
+ " -u [list of uuids] List of uuids which should be scanned for.\n"
+ " Each uuid must be enclosed in {}.\n"
+ " If the list is empty PUBLIC_BROWSE_GROUP scan is used.\n");
}
#define BUFFER_SIZE 1024
@@ -269,6 +279,7 @@ int main(int argc, char **argv)
}
bool showHumanReadable = false;
+ std::vector<std::string> targetServices;
for (int i = 3; i < argc; i++) {
if (argv[i][0] != '-') {
@@ -281,12 +292,56 @@ int main(int argc, char **argv)
case 'p':
showHumanReadable = true;
break;
+ case 'u':
+ i++;
+
+ for ( ; i < argc && argv[i][0] == '{'; i++)
+ targetServices.push_back(argv[i]);
+
+ i--; // outer loop increments again
+ break;
default:
fprintf(stderr, "Wrong argument: %s\n", argv[i]);
usage();
return RETURN_USAGE;
+ }
+ }
+ std::vector<uuid_t> uuids;
+ for (std::vector<std::string>::const_iterator iter = targetServices.cbegin();
+ iter != targetServices.cend(); ++iter) {
+
+ uint128_t temp128;
+ uint16_t field1, field2, field3, field5;
+ uint32_t field0, field4;
+
+ fprintf(stderr, "Target scan for %s\n", (*iter).c_str());
+ if (sscanf((*iter).c_str(), "{%08x-%04hx-%04hx-%04hx-%08x%04hx}", &field0,
+ &field1, &field2, &field3, &field4, &field5) != 6) {
+ fprintf(stderr, "Skipping invalid uuid: %s\n", ((*iter).c_str()));
+ continue;
}
+
+ // we need uuid_t conversion based on
+ // http://www.spinics.net/lists/linux-bluetooth/msg20356.html
+ field0 = htonl(field0);
+ field4 = htonl(field4);
+ field1 = htons(field1);
+ field2 = htons(field2);
+ field3 = htons(field3);
+ field5 = htons(field5);
+
+ uint8_t* temp = (uint8_t*) &temp128;
+ memcpy(&temp[0], &field0, 4);
+ memcpy(&temp[4], &field1, 2);
+ memcpy(&temp[6], &field2, 2);
+ memcpy(&temp[8], &field3, 2);
+ memcpy(&temp[10], &field4, 4);
+ memcpy(&temp[14], &field5, 2);
+
+ uuid_t sdpUuid;
+ sdp_uuid128_create(&sdpUuid, &temp128);
+ uuids.push_back(sdpUuid);
}
sdp_session_t *session = sdp_connect( &local, &remote, SDP_RETRY_IF_BUSY);
@@ -301,27 +356,52 @@ int main(int argc, char **argv)
}
// set the filter for service matches
- uuid_t publicBrowseGroupUuid;
- sdp_uuid16_create(&publicBrowseGroupUuid, PUBLIC_BROWSE_GROUP);
- sdp_list_t *serviceFilter;
- serviceFilter = sdp_list_append(0, &publicBrowseGroupUuid);
+ if (uuids.empty()) {
+ fprintf(stderr, "Using PUBLIC_BROWSE_GROUP for SDP search\n");
+ uuid_t publicBrowseGroupUuid;
+ sdp_uuid16_create(&publicBrowseGroupUuid, PUBLIC_BROWSE_GROUP);
+ uuids.push_back(publicBrowseGroupUuid);
+ }
uint32_t attributeRange = 0x0000ffff; //all attributes
sdp_list_t *attributes;
attributes = sdp_list_append(0, &attributeRange);
- sdp_list_t *sdpResults, *previous;
- result = sdp_service_search_attr_req(session, serviceFilter,
+ sdp_list_t *sdpResults, *sdpIter;
+ sdp_list_t *totalResults = NULL;
+ sdp_list_t* serviceFilter;
+
+ for (uint i = 0; i < uuids.size(); ++i) {
+ serviceFilter = sdp_list_append(0, &uuids[i]);
+ result = sdp_service_search_attr_req(session, serviceFilter,
SDP_ATTR_REQ_RANGE,
attributes, &sdpResults);
- sdp_list_free(attributes, 0);
- sdp_list_free(serviceFilter, 0);
+ sdp_list_free(serviceFilter, 0);
+ if (result != 0) {
+ fprintf(stderr, "sdp_service_search_attr_req failed\n");
+ sdp_list_free(attributes, 0);
+ sdp_close(session);
+ return RETURN_SDP_ERROR;
+ }
- if (result != 0) {
- fprintf(stderr, "sdp_service_search_attr_req failed\n");
- sdp_close(session);
- return RETURN_SDP_ERROR;
+ if (!sdpResults)
+ continue;
+
+ if (!totalResults) {
+ totalResults = sdpResults;
+ sdpIter = totalResults;
+ } else {
+ // attach each new result list to the end of totalResults
+ sdpIter->next = sdpResults;
+ }
+
+ while (sdpIter->next) // skip to end of list
+ sdpIter = sdpIter->next;
}
+ sdp_list_free(attributes, 0);
+
+ // start XML generation from the front
+ sdpResults = totalResults;
QByteArray total;
while (sdpResults) {
@@ -330,9 +410,9 @@ int main(int argc, char **argv)
const QByteArray xml = parseSdpRecord(record);
total += xml;
- previous = sdpResults;
+ sdpIter = sdpResults;
sdpResults = sdpResults->next;
- free(previous);
+ free(sdpIter);
sdp_record_free(record);
}