Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/usr.sbin/bluetooth/sdpcontrol/search.c
104428 views
1
/*-
2
* search.c
3
*
4
* SPDX-License-Identifier: BSD-2-Clause
5
*
6
* Copyright (c) 2001-2003 Maksim Yevmenkin <[email protected]>
7
* All rights reserved.
8
*
9
* Redistribution and use in source and binary forms, with or without
10
* modification, are permitted provided that the following conditions
11
* are met:
12
* 1. Redistributions of source code must retain the above copyright
13
* notice, this list of conditions and the following disclaimer.
14
* 2. Redistributions in binary form must reproduce the above copyright
15
* notice, this list of conditions and the following disclaimer in the
16
* documentation and/or other materials provided with the distribution.
17
*
18
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
* SUCH DAMAGE.
29
*
30
* $Id: search.c,v 1.2 2003/09/08 17:35:15 max Exp $
31
*/
32
33
#include <sys/param.h>
34
#include <netinet/in.h>
35
#define L2CAP_SOCKET_CHECKED
36
#include <bluetooth.h>
37
#include <ctype.h>
38
#include <sdp.h>
39
#include <stdio.h>
40
#include <stdlib.h>
41
#include "sdpcontrol.h"
42
43
/* List of the attributes we are looking for */
44
static uint32_t attrs[] =
45
{
46
SDP_ATTR_RANGE( SDP_ATTR_SERVICE_RECORD_HANDLE,
47
SDP_ATTR_SERVICE_RECORD_HANDLE),
48
SDP_ATTR_RANGE( SDP_ATTR_SERVICE_CLASS_ID_LIST,
49
SDP_ATTR_SERVICE_CLASS_ID_LIST),
50
SDP_ATTR_RANGE( SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST,
51
SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST),
52
SDP_ATTR_RANGE( SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST,
53
SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST)
54
};
55
#define attrs_len nitems(attrs)
56
57
/* Buffer for the attributes */
58
#define NRECS 25 /* request this much records from the SDP server */
59
#define BSIZE 256 /* one attribute buffer size */
60
static uint8_t buffer[NRECS * attrs_len][BSIZE];
61
62
/* SDP attributes */
63
static sdp_attr_t values[NRECS * attrs_len];
64
#define values_len nitems(values)
65
66
/*
67
* Print Service Class ID List
68
*
69
* The ServiceClassIDList attribute consists of a data element sequence in
70
* which each data element is a UUID representing the service classes that
71
* a given service record conforms to. The UUIDs are listed in order from
72
* the most specific class to the most general class. The ServiceClassIDList
73
* must contain at least one service class UUID.
74
*/
75
76
static void
77
print_service_class_id_list(uint8_t const *start, uint8_t const *end)
78
{
79
uint32_t type, len, value;
80
81
if (end - start < 2) {
82
fprintf(stderr, "Invalid Service Class ID List. " \
83
"Too short, len=%zd\n", end - start);
84
return;
85
}
86
87
SDP_GET8(type, start);
88
switch (type) {
89
case SDP_DATA_SEQ8:
90
SDP_GET8(len, start);
91
break;
92
93
case SDP_DATA_SEQ16:
94
SDP_GET16(len, start);
95
break;
96
97
case SDP_DATA_SEQ32:
98
SDP_GET32(len, start);
99
break;
100
101
default:
102
fprintf(stderr, "Invalid Service Class ID List. " \
103
"Not a sequence, type=%#x\n", type);
104
return;
105
/* NOT REACHED */
106
}
107
108
if (len > (end - start)) {
109
fprintf(stderr, "Invalid Service Class ID List. " \
110
"Too long len=%d\n", len);
111
return;
112
}
113
114
while (start < end) {
115
SDP_GET8(type, start);
116
switch (type) {
117
case SDP_DATA_UUID16:
118
SDP_GET16(value, start);
119
fprintf(stdout, "\t%s (%#4.4x)\n",
120
sdp_uuid2desc(value), value);
121
break;
122
123
case SDP_DATA_UUID32:
124
SDP_GET32(value, start);
125
fprintf(stdout, "\t%#8.8x\n", value);
126
break;
127
128
case SDP_DATA_UUID128: {
129
int128_t uuid;
130
131
SDP_GET_UUID128(&uuid, start);
132
fprintf(stdout, "\t%#8.8x-%4.4x-%4.4x-%4.4x-%4.4x%8.8x\n",
133
ntohl(*(uint32_t *)&uuid.b[0]),
134
ntohs(*(uint16_t *)&uuid.b[4]),
135
ntohs(*(uint16_t *)&uuid.b[6]),
136
ntohs(*(uint16_t *)&uuid.b[8]),
137
ntohs(*(uint16_t *)&uuid.b[10]),
138
ntohl(*(uint32_t *)&uuid.b[12]));
139
} break;
140
141
default:
142
fprintf(stderr, "Invalid Service Class ID List. " \
143
"Not a UUID, type=%#x\n", type);
144
return;
145
/* NOT REACHED */
146
}
147
}
148
} /* print_service_class_id_list */
149
150
/*
151
* Print Protocol Descriptor List
152
*
153
* If the ProtocolDescriptorList describes a single stack, it takes the form
154
* of a data element sequence in which each element of the sequence is a
155
* protocol descriptor. Each protocol descriptor is, in turn, a data element
156
* sequence whose first element is a UUID identifying the protocol and whose
157
* successive elements are protocol-specific parameters. The protocol
158
* descriptors are listed in order from the lowest layer protocol to the
159
* highest layer protocol used to gain access to the service. If it is possible
160
* for more than one kind of protocol stack to be used to gain access to the
161
* service, the ProtocolDescriptorList takes the form of a data element
162
* alternative where each member is a data element sequence as described above.
163
*/
164
165
static void
166
print_protocol_descriptor(uint8_t const *start, uint8_t const *end)
167
{
168
union {
169
uint8_t uint8;
170
uint16_t uint16;
171
uint32_t uint32;
172
uint64_t uint64;
173
int128_t int128;
174
} value;
175
uint32_t type, len, param;
176
177
/* Get Protocol UUID */
178
SDP_GET8(type, start);
179
switch (type) {
180
case SDP_DATA_UUID16:
181
SDP_GET16(value.uint16, start);
182
fprintf(stdout, "\t%s (%#4.4x)\n", sdp_uuid2desc(value.uint16),
183
value.uint16);
184
break;
185
186
case SDP_DATA_UUID32:
187
SDP_GET32(value.uint32, start);
188
fprintf(stdout, "\t%#8.8x\n", value.uint32);
189
break;
190
191
case SDP_DATA_UUID128:
192
SDP_GET_UUID128(&value.int128, start);
193
fprintf(stdout, "\t%#8.8x-%4.4x-%4.4x-%4.4x-%4.4x%8.8x\n",
194
ntohl(*(uint32_t *)&value.int128.b[0]),
195
ntohs(*(uint16_t *)&value.int128.b[4]),
196
ntohs(*(uint16_t *)&value.int128.b[6]),
197
ntohs(*(uint16_t *)&value.int128.b[8]),
198
ntohs(*(uint16_t *)&value.int128.b[10]),
199
ntohl(*(uint32_t *)&value.int128.b[12]));
200
break;
201
202
default:
203
fprintf(stderr, "Invalid Protocol Descriptor. " \
204
"Not a UUID, type=%#x\n", type);
205
return;
206
/* NOT REACHED */
207
}
208
209
/* Protocol specific parameters */
210
for (param = 1; start < end; param ++) {
211
fprintf(stdout, "\t\tProtocol specific parameter #%d: ", param);
212
213
SDP_GET8(type, start);
214
switch (type) {
215
case SDP_DATA_NIL:
216
fprintf(stdout, "nil\n");
217
break;
218
219
case SDP_DATA_UINT8:
220
case SDP_DATA_INT8:
221
case SDP_DATA_BOOL:
222
SDP_GET8(value.uint8, start);
223
fprintf(stdout, "u/int8/bool %u\n", value.uint8);
224
break;
225
226
case SDP_DATA_UINT16:
227
case SDP_DATA_INT16:
228
case SDP_DATA_UUID16:
229
SDP_GET16(value.uint16, start);
230
fprintf(stdout, "u/int/uuid16 %u\n", value.uint16);
231
break;
232
233
case SDP_DATA_UINT32:
234
case SDP_DATA_INT32:
235
case SDP_DATA_UUID32:
236
SDP_GET32(value.uint32, start);
237
fprintf(stdout, "u/int/uuid32 %u\n", value.uint32);
238
break;
239
240
case SDP_DATA_UINT64:
241
case SDP_DATA_INT64:
242
SDP_GET64(value.uint64, start);
243
fprintf(stdout, "u/int64 %ju\n", value.uint64);
244
break;
245
246
case SDP_DATA_UINT128:
247
case SDP_DATA_INT128:
248
SDP_GET128(&value.int128, start);
249
fprintf(stdout, "u/int128 %#8.8x%8.8x%8.8x%8.8x\n",
250
*(uint32_t *)&value.int128.b[0],
251
*(uint32_t *)&value.int128.b[4],
252
*(uint32_t *)&value.int128.b[8],
253
*(uint32_t *)&value.int128.b[12]);
254
break;
255
256
case SDP_DATA_UUID128:
257
SDP_GET_UUID128(&value.int128, start);
258
fprintf(stdout, "uuid128 %#8.8x-%4.4x-%4.4x-%4.4x-%4.4x%8.8x\n",
259
ntohl(*(uint32_t *)&value.int128.b[0]),
260
ntohs(*(uint16_t *)&value.int128.b[4]),
261
ntohs(*(uint16_t *)&value.int128.b[6]),
262
ntohs(*(uint16_t *)&value.int128.b[8]),
263
ntohs(*(uint16_t *)&value.int128.b[10]),
264
ntohl(*(uint32_t *)&value.int128.b[12]));
265
break;
266
267
case SDP_DATA_STR8:
268
case SDP_DATA_URL8:
269
SDP_GET8(len, start);
270
for (; start < end && len > 0; start ++, len --)
271
fprintf(stdout, "%c", *start);
272
fprintf(stdout, "\n");
273
break;
274
275
case SDP_DATA_STR16:
276
case SDP_DATA_URL16:
277
SDP_GET16(len, start);
278
for (; start < end && len > 0; start ++, len --)
279
fprintf(stdout, "%c", *start);
280
fprintf(stdout, "\n");
281
break;
282
283
case SDP_DATA_STR32:
284
case SDP_DATA_URL32:
285
SDP_GET32(len, start);
286
for (; start < end && len > 0; start ++, len --)
287
fprintf(stdout, "%c", *start);
288
fprintf(stdout, "\n");
289
break;
290
291
case SDP_DATA_SEQ8:
292
case SDP_DATA_ALT8:
293
SDP_GET8(len, start);
294
for (; start < end && len > 0; start ++, len --)
295
fprintf(stdout, "%#2.2x ", *start);
296
fprintf(stdout, "\n");
297
break;
298
299
case SDP_DATA_SEQ16:
300
case SDP_DATA_ALT16:
301
SDP_GET16(len, start);
302
for (; start < end && len > 0; start ++, len --)
303
fprintf(stdout, "%#2.2x ", *start);
304
fprintf(stdout, "\n");
305
break;
306
307
case SDP_DATA_SEQ32:
308
case SDP_DATA_ALT32:
309
SDP_GET32(len, start);
310
for (; start < end && len > 0; start ++, len --)
311
fprintf(stdout, "%#2.2x ", *start);
312
fprintf(stdout, "\n");
313
break;
314
315
default:
316
fprintf(stderr, "Invalid Protocol Descriptor. " \
317
"Unknown data type: %#02x\n", type);
318
return;
319
/* NOT REACHED */
320
}
321
}
322
} /* print_protocol_descriptor */
323
324
static void
325
print_protocol_descriptor_list(uint8_t const *start, uint8_t const *end)
326
{
327
uint32_t type, len;
328
329
if (end - start < 2) {
330
fprintf(stderr, "Invalid Protocol Descriptor List. " \
331
"Too short, len=%zd\n", end - start);
332
return;
333
}
334
335
SDP_GET8(type, start);
336
switch (type) {
337
case SDP_DATA_SEQ8:
338
SDP_GET8(len, start);
339
break;
340
341
case SDP_DATA_SEQ16:
342
SDP_GET16(len, start);
343
break;
344
345
case SDP_DATA_SEQ32:
346
SDP_GET32(len, start);
347
break;
348
349
default:
350
fprintf(stderr, "Invalid Protocol Descriptor List. " \
351
"Not a sequence, type=%#x\n", type);
352
return;
353
/* NOT REACHED */
354
}
355
356
if (len > (end - start)) {
357
fprintf(stderr, "Invalid Protocol Descriptor List. " \
358
"Too long, len=%d\n", len);
359
return;
360
}
361
362
while (start < end) {
363
SDP_GET8(type, start);
364
switch (type) {
365
case SDP_DATA_SEQ8:
366
SDP_GET8(len, start);
367
break;
368
369
case SDP_DATA_SEQ16:
370
SDP_GET16(len, start);
371
break;
372
373
case SDP_DATA_SEQ32:
374
SDP_GET32(len, start);
375
break;
376
377
default:
378
fprintf(stderr, "Invalid Protocol Descriptor List. " \
379
"Not a sequence, type=%#x\n", type);
380
return;
381
/* NOT REACHED */
382
}
383
384
if (len > (end - start)) {
385
fprintf(stderr, "Invalid Protocol Descriptor List. " \
386
"Too long, len=%d\n", len);
387
return;
388
}
389
390
print_protocol_descriptor(start, start + len);
391
start += len;
392
}
393
} /* print_protocol_descriptor_list */
394
395
/*
396
* Print Bluetooth Profile Descriptor List
397
*
398
* The BluetoothProfileDescriptorList attribute consists of a data element
399
* sequence in which each element is a profile descriptor that contains
400
* information about a Bluetooth profile to which the service represented by
401
* this service record conforms. Each profile descriptor is a data element
402
* sequence whose first element is the UUID assigned to the profile and whose
403
* second element is a 16-bit profile version number. Each version of a profile
404
* is assigned a 16-bit unsigned integer profile version number, which consists
405
* of two 8-bit fields. The higher-order 8 bits contain the major version
406
* number field and the lower-order 8 bits contain the minor version number
407
* field.
408
*/
409
410
static void
411
print_bluetooth_profile_descriptor_list(uint8_t const *start, uint8_t const *end)
412
{
413
uint32_t type, len, value;
414
415
if (end - start < 2) {
416
fprintf(stderr, "Invalid Bluetooth Profile Descriptor List. " \
417
"Too short, len=%zd\n", end - start);
418
return;
419
}
420
421
SDP_GET8(type, start);
422
switch (type) {
423
case SDP_DATA_SEQ8:
424
SDP_GET8(len, start);
425
break;
426
427
case SDP_DATA_SEQ16:
428
SDP_GET16(len, start);
429
break;
430
431
case SDP_DATA_SEQ32:
432
SDP_GET32(len, start);
433
break;
434
435
default:
436
fprintf(stderr, "Invalid Bluetooth Profile Descriptor List. " \
437
"Not a sequence, type=%#x\n", type);
438
return;
439
/* NOT REACHED */
440
}
441
442
if (len > (end - start)) {
443
fprintf(stderr, "Invalid Bluetooth Profile Descriptor List. " \
444
"Too long, len=%d\n", len);
445
return;
446
}
447
448
while (start < end) {
449
SDP_GET8(type, start);
450
switch (type) {
451
case SDP_DATA_SEQ8:
452
SDP_GET8(len, start);
453
break;
454
455
case SDP_DATA_SEQ16:
456
SDP_GET16(len, start);
457
break;
458
459
case SDP_DATA_SEQ32:
460
SDP_GET32(len, start);
461
break;
462
463
default:
464
fprintf(stderr, "Invalid Bluetooth Profile " \
465
"Descriptor List. " \
466
"Not a sequence, type=%#x\n", type);
467
return;
468
/* NOT REACHED */
469
}
470
471
if (len > (end - start)) {
472
fprintf(stderr, "Invalid Bluetooth Profile " \
473
"Descriptor List. " \
474
"Too long, len=%d\n", len);
475
return;
476
}
477
478
/* Get UUID */
479
SDP_GET8(type, start);
480
switch (type) {
481
case SDP_DATA_UUID16:
482
SDP_GET16(value, start);
483
fprintf(stdout, "\t%s (%#4.4x) ",
484
sdp_uuid2desc(value), value);
485
break;
486
487
case SDP_DATA_UUID32:
488
SDP_GET32(value, start);
489
fprintf(stdout, "\t%#8.8x ", value);
490
break;
491
492
case SDP_DATA_UUID128: {
493
int128_t uuid;
494
495
SDP_GET_UUID128(&uuid, start);
496
fprintf(stdout, "\t%#8.8x-%4.4x-%4.4x-%4.4x-%4.4x%8.8x ",
497
ntohl(*(uint32_t *)&uuid.b[0]),
498
ntohs(*(uint16_t *)&uuid.b[4]),
499
ntohs(*(uint16_t *)&uuid.b[6]),
500
ntohs(*(uint16_t *)&uuid.b[8]),
501
ntohs(*(uint16_t *)&uuid.b[10]),
502
ntohl(*(uint32_t *)&uuid.b[12]));
503
} break;
504
505
default:
506
fprintf(stderr, "Invalid Bluetooth Profile " \
507
"Descriptor List. " \
508
"Not a UUID, type=%#x\n", type);
509
return;
510
/* NOT REACHED */
511
}
512
513
/* Get version */
514
SDP_GET8(type, start);
515
if (type != SDP_DATA_UINT16) {
516
fprintf(stderr, "Invalid Bluetooth Profile " \
517
"Descriptor List. " \
518
"Invalid version type=%#x\n", type);
519
return;
520
}
521
522
SDP_GET16(value, start);
523
fprintf(stdout, "ver. %d.%d\n",
524
(value >> 8) & 0xff, value & 0xff);
525
}
526
} /* print_bluetooth_profile_descriptor_list */
527
528
/* Perform SDP search command */
529
static int
530
do_sdp_search(void *xs, int argc, char **argv)
531
{
532
char *ep = NULL;
533
int32_t n, type, value;
534
uint16_t service;
535
536
/* Parse command line arguments */
537
switch (argc) {
538
case 1:
539
n = strtoul(argv[0], &ep, 16);
540
if (*ep != 0) {
541
switch (tolower(argv[0][0])) {
542
case 'c': /* CIP/CTP */
543
switch (tolower(argv[0][1])) {
544
case 'i':
545
service = SDP_SERVICE_CLASS_COMMON_ISDN_ACCESS;
546
break;
547
548
case 't':
549
service = SDP_SERVICE_CLASS_CORDLESS_TELEPHONY;
550
break;
551
552
default:
553
return (USAGE);
554
/* NOT REACHED */
555
}
556
break;
557
558
case 'd': /* DialUp Networking */
559
service = SDP_SERVICE_CLASS_DIALUP_NETWORKING;
560
break;
561
562
case 'f': /* Fax/OBEX File Transfer */
563
switch (tolower(argv[0][1])) {
564
case 'a':
565
service = SDP_SERVICE_CLASS_FAX;
566
break;
567
568
case 't':
569
service = SDP_SERVICE_CLASS_OBEX_FILE_TRANSFER;
570
break;
571
572
default:
573
return (USAGE);
574
/* NOT REACHED */
575
}
576
break;
577
578
case 'g': /* GN */
579
service = SDP_SERVICE_CLASS_GN;
580
break;
581
582
case 'h': /* Headset/HID */
583
switch (tolower(argv[0][1])) {
584
case 'i':
585
service = SDP_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE;
586
break;
587
588
case 's':
589
service = SDP_SERVICE_CLASS_HEADSET;
590
break;
591
592
default:
593
return (USAGE);
594
/* NOT REACHED */
595
}
596
break;
597
598
case 'l': /* LAN Access Using PPP */
599
service = SDP_SERVICE_CLASS_LAN_ACCESS_USING_PPP;
600
break;
601
602
case 'n': /* NAP */
603
service = SDP_SERVICE_CLASS_NAP;
604
break;
605
606
case 'o': /* OBEX Object Push */
607
service = SDP_SERVICE_CLASS_OBEX_OBJECT_PUSH;
608
break;
609
610
case 's': /* Serial Port */
611
service = SDP_SERVICE_CLASS_SERIAL_PORT;
612
break;
613
614
default:
615
return (USAGE);
616
/* NOT REACHED */
617
}
618
} else
619
service = (uint16_t) n;
620
break;
621
622
default:
623
return (USAGE);
624
}
625
626
/* Initialize attribute values array */
627
for (n = 0; n < values_len; n ++) {
628
values[n].flags = SDP_ATTR_INVALID;
629
values[n].attr = 0;
630
values[n].vlen = BSIZE;
631
values[n].value = buffer[n];
632
}
633
634
/* Do SDP Service Search Attribute Request */
635
n = sdp_search(xs, 1, &service, attrs_len, attrs, values_len, values);
636
if (n != 0)
637
return (ERROR);
638
639
/* Print attributes values */
640
for (n = 0; n < values_len; n ++) {
641
if (values[n].flags != SDP_ATTR_OK)
642
break;
643
644
switch (values[n].attr) {
645
case SDP_ATTR_SERVICE_RECORD_HANDLE:
646
fprintf(stdout, "\n");
647
if (values[n].vlen == 5) {
648
SDP_GET8(type, values[n].value);
649
if (type == SDP_DATA_UINT32) {
650
SDP_GET32(value, values[n].value);
651
fprintf(stdout, "Record Handle: " \
652
"%#8.8x\n", value);
653
} else
654
fprintf(stderr, "Invalid type=%#x " \
655
"Record Handle " \
656
"attribute!\n", type);
657
} else
658
fprintf(stderr, "Invalid size=%d for Record " \
659
"Handle attribute\n",
660
values[n].vlen);
661
break;
662
663
case SDP_ATTR_SERVICE_CLASS_ID_LIST:
664
fprintf(stdout, "Service Class ID List:\n");
665
print_service_class_id_list(values[n].value,
666
values[n].value + values[n].vlen);
667
break;
668
669
case SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST:
670
fprintf(stdout, "Protocol Descriptor List:\n");
671
print_protocol_descriptor_list(values[n].value,
672
values[n].value + values[n].vlen);
673
break;
674
675
case SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST:
676
fprintf(stdout, "Bluetooth Profile Descriptor List:\n");
677
print_bluetooth_profile_descriptor_list(values[n].value,
678
values[n].value + values[n].vlen);
679
break;
680
681
default:
682
fprintf(stderr, "Unexpected attribute ID=%#4.4x\n",
683
values[n].attr);
684
break;
685
}
686
}
687
688
return (OK);
689
} /* do_sdp_search */
690
691
/* Perform SDP browse command */
692
static int
693
do_sdp_browse(void *xs, int argc, char **argv)
694
{
695
#undef _STR
696
#undef STR
697
#define _STR(x) #x
698
#define STR(x) _STR(x)
699
700
static char const * const av[] = {
701
STR(SDP_SERVICE_CLASS_PUBLIC_BROWSE_GROUP),
702
NULL
703
};
704
705
switch (argc) {
706
case 0:
707
argc = 1;
708
argv = (char **) av;
709
/* FALL THROUGH */
710
case 1:
711
return (do_sdp_search(xs, argc, argv));
712
}
713
714
return (USAGE);
715
} /* do_sdp_browse */
716
717
/* List of SDP commands */
718
struct sdp_command sdp_commands[] = {
719
{
720
"Browse [<Group>]",
721
"Browse for services. The <Group> parameter is a 16-bit UUID of the group\n" \
722
"to browse. If omitted <Group> is set to Public Browse Group.\n\n" \
723
"\t<Group> - xxxx; 16-bit UUID of the group to browse\n",
724
do_sdp_browse
725
},
726
{
727
"Search <Service>",
728
"Search for the <Service>. The <Service> parameter is a 16-bit UUID of the\n" \
729
"service to search for. For some services it is possible to use service name\n"\
730
"instead of service UUID\n\n" \
731
"\t<Service> - xxxx; 16-bit UUID of the service to search for\n\n" \
732
"\tKnown service names\n" \
733
"\t===================\n" \
734
"\tCIP - Common ISDN Access\n" \
735
"\tCTP - Cordless Telephony\n" \
736
"\tDUN - DialUp Networking\n" \
737
"\tFAX - Fax\n" \
738
"\tFTRN - OBEX File Transfer\n" \
739
"\tGN - GN\n" \
740
"\tHID - Human Interface Device\n" \
741
"\tHSET - Headset\n" \
742
"\tLAN - LAN Access Using PPP\n" \
743
"\tNAP - Network Access Point\n" \
744
"\tOPUSH - OBEX Object Push\n" \
745
"\tSP - Serial Port\n",
746
do_sdp_search
747
},
748
{ NULL, NULL, NULL }
749
};
750
751
752