diff options
author | Alex Blasche <alexander.blasche@theqtcompany.com> | 2016-06-09 15:00:36 +0200 |
---|---|---|
committer | Alex Blasche <alexander.blasche@theqtcompany.com> | 2016-06-09 15:00:43 +0200 |
commit | 6d9a7006e81fc9ef6140bfc62696d1b270aaae08 (patch) | |
tree | d7ce8d417f32ab73543740beab3cdee36b4fdfaf /src/tools/sdpscanner/main.cpp | |
parent | bde54c522b76eeb933296aa1a9e159facbf8e529 (diff) | |
parent | 74916ede2ff34c2040db9cabbb5a6ee81442a7e8 (diff) |
Merge remote-tracking branch 'gerrit/5.6' into 5.7
Change-Id: Id8dffff9bb75db396aabf6da2a3acb78505a6476
Diffstat (limited to 'src/tools/sdpscanner/main.cpp')
-rw-r--r-- | src/tools/sdpscanner/main.cpp | 106 |
1 files changed, 90 insertions, 16 deletions
diff --git a/src/tools/sdpscanner/main.cpp b/src/tools/sdpscanner/main.cpp index bf978c0d..edca8fa3 100644 --- a/src/tools/sdpscanner/main.cpp +++ b/src/tools/sdpscanner/main.cpp @@ -40,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> @@ -52,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 @@ -275,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] != '-') { @@ -287,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); @@ -307,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) { @@ -336,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); } |