38 const int length = indentation*2 + 1;
43 xmlOutput.append(indentString);
48 xmlOutput.append(
"<nil/>\n");
52 xmlOutput.append(snBuffer);
56 xmlOutput.append(snBuffer);
60 xmlOutput.append(snBuffer);
64 xmlOutput.append(snBuffer);
67 xmlOutput.append(
"<uint128 value=\"0x");
68 for (
int i = 0;
i < 16;
i++)
69 ::sprintf(&snBuffer[
i * 2],
"%02x",
data->val.uint128.data[
i]);
70 xmlOutput.append(snBuffer);
71 xmlOutput.append(
"\"/>\n");
75 xmlOutput.append(snBuffer);
79 xmlOutput.append(snBuffer);
83 xmlOutput.append(snBuffer);
87 xmlOutput.append(snBuffer);
90 xmlOutput.append(
"<int128 value=\"0x");
91 for (
int i = 0;
i < 16;
i++)
92 ::sprintf(&snBuffer[
i * 2],
"%02x",
data->val.int128.data[
i]);
93 xmlOutput.append(snBuffer);
94 xmlOutput.append(
"\"/>\n");
100 xmlOutput.append(
"<uuid value=\"0x");
102 xmlOutput.append(snBuffer);
103 xmlOutput.append(
"\"/>\n");
106 xmlOutput.append(
"<uuid value=\"");
108 xmlOutput.append(snBuffer);
109 xmlOutput.append(
"\"/>\n");
111 case SDP_TEXT_STR_UNSPEC:
117 xmlOutput.append(
"<text ");
120 bool hasNonPrintableChar =
false;
122 if (
text[
i] ==
'\0') {
125 }
else if (!isprint(
text[
i])) {
126 hasNonPrintableChar =
true;
128 if (firstNullIdx > 0)
134 if (hasNonPrintableChar) {
135 xmlOutput.append(
"encoding=\"hex\" value=\"");
136 xmlOutput.append(
text.toHex());
143 xmlOutput.
append(
"value=\"");
147 xmlOutput.
append(
"\"/>\n");
152 xmlOutput.
append(
"<boolean value=\"true\"/>\n");
154 xmlOutput.
append(
"<boolean value=\"false\"/>\n");
161 xmlOutput.
append(
"<sequence>\n");
163 xmlOutput.append(indentString);
164 xmlOutput.append(
"</sequence>\n");
171 xmlOutput.append(
"<alternate>\n");
173 xmlOutput.append(indentString);
174 xmlOutput.append(
"</alternate>\n");
176 case SDP_URL_STR_UNSPEC:
182 xmlOutput.append(
"<url value=\"");
189 xmlOutput.append(
"\"/>\n");
193 fprintf(stderr,
"Unknown dtd type\n");
238 fprintf(stderr,
"SDP for %s %s\n", argv[1], argv[2]);
242 int result = str2ba(argv[1], &remote);
244 fprintf(stderr,
"Invalid remote address: %s\n", argv[1]);
248 result = str2ba(argv[2], &local);
250 fprintf(stderr,
"Invalid local address: %s\n", argv[2]);
254 bool showHumanReadable =
false;
255 std::vector<std::string> targetServices;
257 for (
int i = 3;
i < argc;
i++) {
258 if (argv[
i][0] !=
'-') {
266 showHumanReadable =
true;
271 for ( ;
i < argc && argv[
i][0] ==
'{';
i++)
272 targetServices.push_back(argv[
i]);
277 fprintf(stderr,
"Wrong argument: %s\n", argv[
i]);
283 std::vector<uuid_t> uuids;
284 for (std::vector<std::string>::const_iterator
iter = targetServices.cbegin();
285 iter != targetServices.cend(); ++
iter) {
288 uint16_t field1, field2, field3, field5;
289 uint32_t field0, field4;
291 fprintf(stderr,
"Target scan for %s\n", (*iter).c_str());
292 if (sscanf((*iter).c_str(),
"{%08x-%04hx-%04hx-%04hx-%08x%04hx}", &field0,
293 &field1, &field2, &field3, &field4, &field5) != 6) {
294 fprintf(stderr,
"Skipping invalid uuid: %s\n", ((*iter).c_str()));
300 field0 = htonl(field0);
301 field4 = htonl(field4);
302 field1 = htons(field1);
303 field2 = htons(field2);
304 field3 = htons(field3);
305 field5 = htons(field5);
307 uint8_t* temp = (uint8_t*) &temp128;
308 memcpy(&temp[0], &field0, 4);
309 memcpy(&temp[4], &field1, 2);
310 memcpy(&temp[6], &field2, 2);
311 memcpy(&temp[8], &field3, 2);
312 memcpy(&temp[10], &field4, 4);
313 memcpy(&temp[14], &field5, 2);
316 sdp_uuid128_create(&sdpUuid, &temp128);
317 uuids.push_back(sdpUuid);
320 sdp_session_t *session = sdp_connect( &local, &remote, SDP_RETRY_IF_BUSY);
323 session = sdp_connect( &local, &remote, SDP_RETRY_IF_BUSY);
327 fprintf(stderr,
"Cannot establish sdp session\n");
333 fprintf(stderr,
"Using PUBLIC_BROWSE_GROUP for SDP search\n");
334 uuid_t publicBrowseGroupUuid;
335 sdp_uuid16_create(&publicBrowseGroupUuid, PUBLIC_BROWSE_GROUP);
336 uuids.push_back(publicBrowseGroupUuid);
339 uint32_t attributeRange = 0x0000ffff;
340 sdp_list_t *attributes;
341 attributes = sdp_list_append(
nullptr, &attributeRange);
343 sdp_list_t *sdpResults, *sdpIter;
344 sdp_list_t *totalResults =
nullptr;
345 sdp_list_t* serviceFilter;
347 for (uuid_t &uuid : uuids) {
348 serviceFilter = sdp_list_append(
nullptr, &uuid);
349 result = sdp_service_search_attr_req(session, serviceFilter,
351 attributes, &sdpResults);
352 sdp_list_free(serviceFilter,
nullptr);
354 fprintf(stderr,
"sdp_service_search_attr_req failed\n");
355 sdp_list_free(attributes,
nullptr);
364 totalResults = sdpResults;
365 sdpIter = totalResults;
368 sdpIter->next = sdpResults;
371 while (sdpIter->next)
372 sdpIter = sdpIter->next;
374 sdp_list_free(attributes,
nullptr);
377 sdpResults = totalResults;
381 sdp_record_t *
record = (sdp_record_t *) sdpResults->data;
386 sdpIter = sdpResults;
387 sdpResults = sdpResults->next;
393 if (showHumanReadable)