1 /* $NetBSD: print.c,v 1.4 2009/08/20 11:07:42 plunky Exp $ */
4 * Copyright (c) 2009 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __RCSID("$NetBSD: print.c,v 1.4 2009/08/20 11:07:42 plunky Exp $");
51 void (*print
)(sdp_data_t
*);
66 static const char *string_uuid(uuid_t
*);
67 static const char *string_vis(int, const char *, size_t);
69 static void print_hexdump(const char *, const uint8_t *, size_t);
70 static bool print_attribute(uint16_t, sdp_data_t
*, attr_t
*, int);
71 static bool print_universal_attribute(uint16_t, sdp_data_t
*);
72 static bool print_language_attribute(uint16_t, sdp_data_t
*);
73 static bool print_service_attribute(uint16_t, sdp_data_t
*);
75 static void print_bool(sdp_data_t
*);
76 static void print_uint8d(sdp_data_t
*);
77 static void print_uint8x(sdp_data_t
*);
78 static void print_uint16d(sdp_data_t
*);
79 static void print_uint16x(sdp_data_t
*);
80 static void print_uint32x(sdp_data_t
*);
81 static void print_uint32d(sdp_data_t
*);
82 static void print_uuid(sdp_data_t
*);
83 static void print_uuid_list(sdp_data_t
*);
84 static void print_string(sdp_data_t
*);
85 static void print_url(sdp_data_t
*);
86 static void print_profile_version(sdp_data_t
*);
87 static void print_language_string(sdp_data_t
*);
89 static void print_service_class_id_list(sdp_data_t
*);
90 static void print_protocol_descriptor(sdp_data_t
*);
91 static void print_protocol_descriptor_list(sdp_data_t
*);
92 static void print_language_base_attribute_id_list(sdp_data_t
*);
93 static void print_service_availability(sdp_data_t
*);
94 static void print_bluetooth_profile_descriptor_list(sdp_data_t
*);
95 static void print_additional_protocol_descriptor_lists(sdp_data_t
*);
96 static void print_sds_version_number_list(sdp_data_t
*);
97 static void print_ct_network(sdp_data_t
*);
98 static void print_asrc_features(sdp_data_t
*);
99 static void print_asink_features(sdp_data_t
*);
100 static void print_avrcp_features(sdp_data_t
*);
101 static void print_supported_data_stores(sdp_data_t
*);
102 static void print_supported_formats(sdp_data_t
*);
103 static void print_hid_version(sdp_data_t
*);
104 static void print_hid_device_subclass(sdp_data_t
*);
105 static void print_hid_descriptor_list(sdp_data_t
*);
106 static void print_security_description(sdp_data_t
*);
107 static void print_hf_features(sdp_data_t
*);
108 static void print_hfag_network(sdp_data_t
*);
109 static void print_hfag_features(sdp_data_t
*);
110 static void print_net_access_type(sdp_data_t
*);
111 static void print_pnp_source(sdp_data_t
*);
112 static void print_mas_types(sdp_data_t
*);
113 static void print_supported_repositories(sdp_data_t
*);
115 static void print_rfcomm(sdp_data_t
*);
116 static void print_bnep(sdp_data_t
*);
117 static void print_avctp(sdp_data_t
*);
118 static void print_avdtp(sdp_data_t
*);
119 static void print_l2cap(sdp_data_t
*);
121 attr_t protocol_list
[] = {
122 { 0x0001, "SDP", NULL
},
123 { 0x0002, "UDP", NULL
},
124 { 0x0003, "RFCOMM", print_rfcomm
},
125 { 0x0004, "TCP", NULL
},
126 { 0x0005, "TCS_BIN", NULL
},
127 { 0x0006, "TCS_AT", NULL
},
128 { 0x0008, "OBEX", NULL
},
129 { 0x0009, "IP", NULL
},
130 { 0x000a, "FTP", NULL
},
131 { 0x000c, "HTTP", NULL
},
132 { 0x000e, "WSP", NULL
},
133 { 0x000f, "BNEP", print_bnep
},
134 { 0x0010, "UPNP", NULL
},
135 { 0x0011, "HIDP", NULL
},
136 { 0x0012, "HARDCOPY_CONTROL_CHANNEL", NULL
},
137 { 0x0014, "HARDCOPY_DATA_CHANNEL", NULL
},
138 { 0x0016, "HARDCOPY_NOTIFICATION", NULL
},
139 { 0x0017, "AVCTP", print_avctp
},
140 { 0x0019, "AVDTP", print_avdtp
},
141 { 0x001b, "CMTP", NULL
},
142 { 0x001d, "UDI_C_PLANE", NULL
},
143 { 0x001e, "MCAP_CONTROL_CHANNEL", NULL
},
144 { 0x001f, "MCAP_DATA_CHANNEL", NULL
},
145 { 0x0100, "L2CAP", print_l2cap
},
148 attr_t universal_attrs
[] = {
149 { 0x0000, "ServiceRecordHandle", print_uint32x
},
150 { 0x0001, "ServiceClassIDList", print_service_class_id_list
},
151 { 0x0002, "ServiceRecordState", print_uint32x
},
152 { 0x0003, "ServiceID", print_uuid
},
153 { 0x0004, "ProtocolDescriptorList", print_protocol_descriptor_list
},
154 { 0x0005, "BrowseGroupList", print_uuid_list
},
155 { 0x0006, "LanguageBaseAttributeIDList", print_language_base_attribute_id_list
},
156 { 0x0007, "ServiceInfoTimeToLive", print_uint32d
},
157 { 0x0008, "ServiceAvailability", print_service_availability
},
158 { 0x0009, "BluetoothProfileDescriptorList", print_bluetooth_profile_descriptor_list
},
159 { 0x000a, "DocumentationURL", print_url
},
160 { 0x000b, "ClientExecutableURL", print_url
},
161 { 0x000c, "IconURL", print_url
},
162 { 0x000d, "AdditionalProtocolDescriptorLists", print_additional_protocol_descriptor_lists
},
165 attr_t language_attrs
[] = { /* Language Attribute Offsets */
166 { 0x0000, "ServiceName", print_language_string
},
167 { 0x0001, "ServiceDescription", print_language_string
},
168 { 0x0002, "ProviderName", print_language_string
},
171 attr_t sds_attrs
[] = { /* Service Discovery Server */
172 { 0x0200, "VersionNumberList", print_sds_version_number_list
},
173 { 0x0201, "ServiceDatabaseState", print_uint32x
},
176 attr_t bgd_attrs
[] = { /* Browse Group Descriptor */
177 { 0x0200, "GroupID", print_uuid
},
180 attr_t ct_attrs
[] = { /* Cordless Telephony */
181 { 0x0301, "ExternalNetwork", print_ct_network
},
184 attr_t asrc_attrs
[] = { /* Audio Source */
185 { 0x0311, "SupportedFeatures", print_asrc_features
},
188 attr_t asink_attrs
[] = { /* Audio Sink */
189 { 0x0311, "SupportedFeatures", print_asink_features
},
192 attr_t avrcp_attrs
[] = { /* Audio Video Remote Control Profile */
193 { 0x0311, "SupportedFeatures", print_avrcp_features
},
196 attr_t lan_attrs
[] = { /* LAN Access Using PPP */
197 { 0x0200, "IPSubnet", print_string
},
200 attr_t dun_attrs
[] = { /* Dialup Networking */
201 { 0x0305, "AudioFeedbackSupport", print_bool
},
204 attr_t irmc_sync_attrs
[] = { /* IrMC Sync */
205 { 0x0301, "SupportedDataStoresList", print_supported_data_stores
},
208 attr_t opush_attrs
[] = { /* Object Push */
209 { 0x0303, "SupportedFormatsList", print_supported_formats
},
212 attr_t hset_attrs
[] = { /* Headset */
213 { 0x0302, "RemoteAudioVolumeControl", print_bool
},
216 attr_t fax_attrs
[] = { /* Fax */
217 { 0x0302, "FAXClass1", print_bool
},
218 { 0x0303, "FAXClass2.0", print_bool
},
219 { 0x0304, "FAXClass2", print_bool
},
220 { 0x0305, "AudioFeedbackSupport", print_bool
},
223 attr_t panu_attrs
[] = { /* Personal Area Networking User */
224 { 0x030a, "SecurityDescription", print_security_description
},
227 attr_t nap_attrs
[] = { /* Network Access Point */
228 { 0x030a, "SecurityDescription", print_security_description
},
229 { 0x030b, "NetAccessType", print_net_access_type
},
230 { 0x030c, "MaxNetAccessRate", print_uint32d
},
231 { 0x030d, "IPv4Subnet", print_string
},
232 { 0x030e, "IPv6Subnet", print_string
},
235 attr_t gn_attrs
[] = { /* Group Network */
236 { 0x030a, "SecurityDescription", print_security_description
},
237 { 0x030d, "IPv4Subnet", print_string
},
238 { 0x030e, "IPv6Subnet", print_string
},
241 attr_t hf_attrs
[] = { /* Handsfree */
242 { 0x0311, "SupportedFeatures", print_hf_features
},
245 attr_t hfag_attrs
[] = { /* Handsfree Audio Gateway */
246 { 0x0301, "Network", print_hfag_network
},
247 { 0x0311, "SupportedFeatures", print_hfag_features
},
250 attr_t hid_attrs
[] = { /* Human Interface Device */
251 { 0x0200, "HIDDeviceReleaseNumber", print_hid_version
},
252 { 0x0201, "HIDParserVersion", print_hid_version
},
253 { 0x0202, "HIDDeviceSubClass", print_hid_device_subclass
},
254 { 0x0203, "HIDCountryCode", print_uint8x
},
255 { 0x0204, "HIDVirtualCable", print_bool
},
256 { 0x0205, "HIDReconnectInitiate", print_bool
},
257 { 0x0206, "HIDDescriptorList", print_hid_descriptor_list
},
258 { 0x0207, "HIDLANGIDBaseList", NULL
},
259 { 0x0208, "HIDSDPDisable", print_bool
},
260 { 0x0209, "HIDBatteryPower", print_bool
},
261 { 0x020a, "HIDRemoteWake", print_bool
},
262 { 0x020b, "HIDProfileVersion", print_profile_version
},
263 { 0x020c, "HIDSupervisionTimeout", print_uint16d
},
264 { 0x020d, "HIDNormallyConnectable", print_bool
},
265 { 0x020e, "HIDBootDevice", print_bool
},
268 attr_t pnp_attrs
[] = { /* Device ID */
269 { 0x0200, "SpecificationID", print_profile_version
},
270 { 0x0201, "VendorID", print_uint16x
},
271 { 0x0202, "ProductID", print_uint16x
},
272 { 0x0203, "Version", print_hid_version
},
273 { 0x0204, "PrimaryRecord", print_bool
},
274 { 0x0205, "VendorIDSource", print_pnp_source
},
277 attr_t mas_attrs
[] = { /* Message Access Server */
278 { 0x0315, "InstanceID", print_uint8d
},
279 { 0x0316, "SupportedMessageTypes", print_mas_types
},
282 attr_t pse_attrs
[] = { /* Phonebook Access Server */
283 { 0x0314, "SupportedRepositories", print_supported_repositories
},
286 #define A(a) a, __arraycount(a)
287 service_t service_list
[] = {
288 { 0x1000, "Service Discovery Server", A(sds_attrs
) },
289 { 0x1001, "Browse Group Descriptor", A(bgd_attrs
) },
290 { 0x1002, "Public Browse Root", NULL
, 0 },
291 { 0x1101, "Serial Port", NULL
, 0 },
292 { 0x1102, "LAN Access Using PPP", A(lan_attrs
) },
293 { 0x1103, "Dialup Networking", A(dun_attrs
) },
294 { 0x1104, "IrMC Sync", A(irmc_sync_attrs
) },
295 { 0x1105, "Object Push", A(opush_attrs
) },
296 { 0x1106, "File Transfer", NULL
, 0 },
297 { 0x1107, "IrMC Sync Command", NULL
, 0 },
298 { 0x1108, "Headset", A(hset_attrs
) },
299 { 0x1109, "Cordless Telephony", A(ct_attrs
) },
300 { 0x110a, "Audio Source", A(asrc_attrs
) },
301 { 0x110b, "Audio Sink", A(asink_attrs
) },
302 { 0x110c, "A/V Remote Control Target", A(avrcp_attrs
) },
303 { 0x110d, "Advanced Audio Distribution", NULL
, 0 },
304 { 0x110e, "A/V Remote Control", A(avrcp_attrs
) },
305 { 0x110f, "Video Conferencing", NULL
, 0 },
306 { 0x1110, "Intercom", NULL
, 0 },
307 { 0x1111, "Fax", A(fax_attrs
) },
308 { 0x1112, "Headset Audio Gateway", NULL
, 0 },
309 { 0x1113, "WAP", NULL
, 0 },
310 { 0x1114, "WAP Client", NULL
, 0 },
311 { 0x1115, "Personal Area Networking User", A(panu_attrs
) },
312 { 0x1116, "Network Access Point", A(nap_attrs
) },
313 { 0x1117, "Group Network", A(gn_attrs
) },
314 { 0x1118, "Direct Printing", NULL
, 0 },
315 { 0x1119, "Reference Printing", NULL
, 0 },
316 { 0x111a, "Imaging", NULL
, 0 },
317 { 0x111b, "Imaging Responder", NULL
, 0 },
318 { 0x111c, "Imaging Automatic Archive", NULL
, 0 },
319 { 0x111d, "Imaging Referenced Objects", NULL
, 0 },
320 { 0x111e, "Handsfree", A(hf_attrs
) },
321 { 0x111f, "Handsfree Audio Gateway", A(hfag_attrs
) },
322 { 0x1120, "Direct Printing Reference Objects", NULL
, 0 },
323 { 0x1121, "Reflected User Interface", NULL
, 0 },
324 { 0x1122, "Basic Printing", NULL
, 0 },
325 { 0x1123, "Printing Status", NULL
, 0 },
326 { 0x1124, "Human Interface Device", A(hid_attrs
) },
327 { 0x1125, "Hardcopy Cable Replacement", NULL
, 0 },
328 { 0x1126, "Hardcopy Cable Replacement Print", NULL
, 0 },
329 { 0x1127, "Hardcopy Cable Replacement Scan", NULL
, 0 },
330 { 0x1128, "Common ISDN Access", NULL
, 0 },
331 { 0x1129, "Video Conferencing GW", NULL
, 0 },
332 { 0x112a, "UDI MT", NULL
, 0 },
333 { 0x112b, "UDI TA", NULL
, 0 },
334 { 0x112c, "Audio/Video", NULL
, 0 },
335 { 0x112d, "SIM Access", NULL
, 0 },
336 { 0x112e, "Phonebook Access Client", NULL
, 0 },
337 { 0x112f, "Phonebook Access Server", A(pse_attrs
) },
338 { 0x1130, "Phonebook Access", NULL
, 0 },
339 { 0x1131, "Headset HS", NULL
, 0 },
340 { 0x1132, "Message Access Server", A(mas_attrs
) },
341 { 0x1133, "Message Notification Server", NULL
, 0 },
342 { 0x1134, "Message Access Profile", NULL
, 0 },
343 { 0x1200, "PNP Information", A(pnp_attrs
) },
344 { 0x1201, "Generic Networking", NULL
, 0 },
345 { 0x1202, "Generic File Transfer", NULL
, 0 },
346 { 0x1203, "Generic Audio", NULL
, 0 },
347 { 0x1204, "Generic Telephony", NULL
, 0 },
348 { 0x1205, "UPNP", NULL
, 0 },
349 { 0x1206, "UPNP IP", NULL
, 0 },
350 { 0x1300, "UPNP IP PAN", NULL
, 0 },
351 { 0x1301, "UPNP IP LAP", NULL
, 0 },
352 { 0x1302, "UPNP IP L2CAP", NULL
, 0 },
353 { 0x1303, "Video Source", NULL
, 0 },
354 { 0x1304, "Video Sink", NULL
, 0 },
355 { 0x1305, "Video Distribution", NULL
, 0 },
356 { 0x1400, "HDP", NULL
, 0 },
357 { 0x1401, "HDP Source", NULL
, 0 },
358 { 0x1402, "HDP Sink", NULL
, 0 },
362 /* extracted Service Class ID List */
363 #define MAX_SERVICES 16
364 static size_t nservices
;
365 static uint16_t service_class
[MAX_SERVICES
];
367 /* extracted Language Base Attribute ID List */
368 #define MAX_LANGUAGES 16
369 static int nlanguages
;
370 static language_t language
[MAX_LANGUAGES
];
374 sdp_get_uint8(sdp_data_t
*d
, uint8_t *vp
)
378 if (sdp_data_type(d
) != SDP_DATA_UINT8
379 || !sdp_get_uint(d
, &v
))
387 sdp_get_uint16(sdp_data_t
*d
, uint16_t *vp
)
391 if (sdp_data_type(d
) != SDP_DATA_UINT16
392 || !sdp_get_uint(d
, &v
))
400 sdp_get_uint32(sdp_data_t
*d
, uint32_t *vp
)
404 if (sdp_data_type(d
) != SDP_DATA_UINT32
405 || !sdp_get_uint(d
, &v
))
413 print_record(sdp_data_t
*rec
)
422 while (sdp_get_attr(rec
, &id
, &value
)) {
424 printf("AttributeID 0x%04x:\n", id
);
425 print_hexdump(" ", value
.next
, value
.end
- value
.next
);
427 printf("AttributeID 0x%04x:\n", id
);
428 sdp_data_print(&value
, 4);
429 } else if (print_universal_attribute(id
, &value
)
430 || print_language_attribute(id
, &value
)
431 || print_service_attribute(id
, &value
)) {
432 if (value
.next
!= value
.end
)
433 printf(" [additional data ignored]\n");
435 printf("AttributeID 0x%04x:\n", id
);
436 sdp_data_print(&value
, 4);
442 string_uuid(uuid_t
*uuid
)
451 if (!uuid_equal(&u
, &BLUETOOTH_BASE_UUID
, NULL
)) {
452 snprintf(buf
, sizeof(buf
),
453 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
454 uuid
->time_low
, uuid
->time_mid
, uuid
->time_hi_and_version
,
455 uuid
->clock_seq_hi_and_reserved
, uuid
->clock_seq_low
,
456 uuid
->node
[0], uuid
->node
[1], uuid
->node
[2],
457 uuid
->node
[3], uuid
->node
[4], uuid
->node
[5]);
463 for (i
= 0; i
< __arraycount(service_list
); i
++) {
464 if (uuid
->time_low
== service_list
[i
].class) {
465 desc
= service_list
[i
].desc
;
470 for (i
= 0; i
< __arraycount(protocol_list
); i
++) {
471 if (uuid
->time_low
== protocol_list
[i
].id
) {
472 desc
= protocol_list
[i
].desc
;
477 if (!Nflag
&& desc
) {
478 snprintf(buf
, sizeof(buf
), "%s", desc
);
482 snprintf(buf
, sizeof(buf
), "%s%s(0x%*.*x)",
483 (desc
== NULL
? "" : desc
),
484 (desc
== NULL
? "" : " "),
485 (uuid
->time_low
> UINT16_MAX
? 8 : 4),
486 (uuid
->time_low
> UINT16_MAX
? 8 : 4),
493 string_vis(int style
, const char *src
, size_t len
)
499 while (len
> 0 && (dst
+ 5) < (buf
+ sizeof(buf
))) {
500 dst
= vis(dst
, src
[0], style
, (len
> 1 ? src
[1] : 0));
509 print_hexdump(const char *title
, const uint8_t *data
, size_t len
)
514 n
= printf("%s", title
);
518 printf("\n%*s", n
, "");
522 printf(" 0x%02x", *data
++);
529 print_attribute(uint16_t id
, sdp_data_t
*value
, attr_t
*attr
, int count
)
533 for (i
= 0; i
< count
; i
++) {
534 if (id
== attr
[i
].id
) {
535 printf("%s", attr
[i
].desc
);
541 printf("0x%04x + ", language
[current
].base
);
543 printf("0x%04x)", id
);
548 if (attr
[i
].print
== NULL
) {
550 sdp_data_print(value
, 4);
551 value
->next
= value
->end
;
553 (attr
[i
].print
)(value
);
564 print_universal_attribute(uint16_t id
, sdp_data_t
*value
)
567 return print_attribute(id
, value
,
568 universal_attrs
, __arraycount(universal_attrs
));
572 print_language_attribute(uint16_t id
, sdp_data_t
*value
)
576 for (current
= 0; current
< nlanguages
&& !done
; current
++)
577 done
= print_attribute(id
- language
[current
].base
, value
,
578 language_attrs
, __arraycount(language_attrs
));
585 print_service_attribute(uint16_t id
, sdp_data_t
*value
)
589 for (i
= 0; i
< nservices
; i
++) {
590 for (j
= 0; j
< __arraycount(service_list
); j
++) {
591 if (service_class
[i
] == service_list
[j
].class)
592 return print_attribute(id
, value
,
593 service_list
[j
].attrs
,
594 service_list
[j
].nattr
);
602 print_bool(sdp_data_t
*data
)
606 if (!sdp_get_bool(data
, &v
))
609 printf("%s\n", (v
? "true" : "false"));
613 print_uint8d(sdp_data_t
*data
)
617 if (!sdp_get_uint8(data
, &v
))
624 print_uint8x(sdp_data_t
*data
)
628 if (!sdp_get_uint8(data
, &v
))
631 printf("0x%02x\n", v
);
635 print_uint16d(sdp_data_t
*data
)
639 if (!sdp_get_uint16(data
, &v
))
646 print_uint16x(sdp_data_t
*data
)
650 if (!sdp_get_uint16(data
, &v
))
653 printf("0x%04x\n", v
);
657 print_uint32x(sdp_data_t
*data
)
661 if (!sdp_get_uint32(data
, &v
))
664 printf("0x%08x\n", v
);
668 print_uint32d(sdp_data_t
*data
)
672 if (!sdp_get_uint32(data
, &v
))
679 print_uuid(sdp_data_t
*data
)
683 if (!sdp_get_uuid(data
, &uuid
))
686 printf("%s\n", string_uuid(&uuid
));
690 print_uuid_list(sdp_data_t
*data
)
695 if (!sdp_get_seq(data
, &seq
))
699 while (sdp_get_uuid(&seq
, &uuid
))
700 printf(" %s\n", string_uuid(&uuid
));
702 if (seq
.next
!= seq
.end
)
703 printf(" [additional data]\n");
707 print_string(sdp_data_t
*data
)
712 if (!sdp_get_str(data
, &str
, &len
))
715 printf("\"%s\"\n", string_vis(VIS_CSTYLE
, str
, len
));
719 print_url(sdp_data_t
*data
)
724 if (!sdp_get_url(data
, &url
, &len
))
727 printf("\"%s\"\n", string_vis(VIS_HTTPSTYLE
, url
, len
));
731 print_profile_version(sdp_data_t
*data
)
735 if (!sdp_get_uint16(data
, &v
))
738 printf("v%d.%d\n", (v
>> 8), (v
& 0xff));
742 * This should only be called through print_language_attribute() which
743 * sets codeset of the string to be printed.
746 print_language_string(sdp_data_t
*data
)
748 char buf
[50], *dst
, *src
;
750 size_t n
, srcleft
, dstleft
;
752 if (!sdp_get_str(data
, &src
, &srcleft
))
756 dstleft
= sizeof(buf
);
758 ih
= iconv_open(nl_langinfo(CODESET
), language
[current
].codeset
);
759 if (ih
== (iconv_t
)-1) {
760 printf("Can't convert %s string\n", language
[current
].codeset
);
764 n
= iconv(ih
, (const char **)&src
, &srcleft
, &dst
, &dstleft
);
769 printf("(%s) ", language
[current
].codeset
);
771 printf("\"%.*s%s\n", (int)(sizeof(buf
) - dstleft
), buf
,
772 (srcleft
> 0 ? " ..." : "\""));
776 print_service_class_id_list(sdp_data_t
*data
)
781 if (!sdp_get_seq(data
, &seq
))
785 while (sdp_get_uuid(&seq
, &uuid
)) {
786 printf(" %s\n", string_uuid(&uuid
));
788 if (nservices
< MAX_SERVICES
) {
789 service_class
[nservices
] = uuid
.time_low
;
791 if (uuid_equal(&uuid
, &BLUETOOTH_BASE_UUID
, NULL
))
796 if (seq
.next
!= seq
.end
)
797 printf(" [additional data]\n");
801 print_protocol_descriptor(sdp_data_t
*data
)
806 if (!sdp_get_uuid(data
, &uuid
))
811 if (uuid_equal(&u0
, &BLUETOOTH_BASE_UUID
, NULL
)) {
812 for (i
= 0; i
< __arraycount(protocol_list
); i
++) {
813 if (uuid
.time_low
== protocol_list
[i
].id
) {
814 printf(" %s", protocol_list
[i
].desc
);
817 printf(" (0x%04x)", protocol_list
[i
].id
);
819 if (protocol_list
[i
].print
)
820 (protocol_list
[i
].print
)(data
);
822 if (data
->next
!= data
->end
)
823 printf(" [additional data ignored]");
831 printf(" %s\n", string_uuid(&uuid
));
832 sdp_data_print(data
, 4);
833 data
->next
= data
->end
;
837 print_protocol_descriptor_list(sdp_data_t
*data
)
839 sdp_data_t seq
, proto
;
842 sdp_get_alt(data
, data
); /* strip [optional] alt header */
844 while (sdp_get_seq(data
, &seq
))
845 while (sdp_get_seq(&seq
, &proto
))
846 print_protocol_descriptor(&proto
);
850 print_language_base_attribute_id_list(sdp_data_t
*data
)
857 if (!sdp_get_seq(data
, &list
))
861 while (list
.next
< list
.end
) {
863 * ISO-639-1 natural language values are published at
864 * http://www.loc.gov/standards/iso639-2/php/code-list.php
866 if (!sdp_get_uint16(&list
, &v
))
870 if (!islower((int)lang
[0]) || !islower((int)lang
[1]))
874 * MIBenum values are published at
875 * http://www.iana.org/assignments/character-sets
877 if (!sdp_get_uint16(&list
, &v
))
881 case 3: codeset
= "US-ASCII"; break;
882 case 4: codeset
= "ISO-8859-1"; break;
883 case 5: codeset
= "ISO-8859-2"; break;
884 case 106: codeset
= "UTF-8"; break;
885 case 1013: codeset
= "UTF-16BE"; break;
886 case 1014: codeset
= "UTF-16LE"; break;
887 default: codeset
= "Unknown"; break;
890 if (!sdp_get_uint16(&list
, &v
))
893 printf(" %.2s.%s base 0x%04x\n", lang
, codeset
, v
);
895 if (nlanguages
< MAX_LANGUAGES
) {
896 language
[nlanguages
].base
= v
;
897 language
[nlanguages
].codeset
= codeset
;
902 if (list
.next
!= list
.end
)
903 printf(" [additional data]\n");
907 print_service_availability(sdp_data_t
*data
)
911 if (!sdp_get_uint8(data
, &v
))
914 printf("%d/%d\n", v
, UINT8_MAX
);
918 print_bluetooth_profile_descriptor_list(sdp_data_t
*data
)
920 sdp_data_t seq
, profile
;
924 if (!sdp_get_seq(data
, &seq
))
928 while (seq
.next
< seq
.end
) {
929 if (!sdp_get_seq(&seq
, &profile
)
930 || !sdp_get_uuid(&profile
, &uuid
)
931 || !sdp_get_uint16(&profile
, &v
))
934 printf(" %s, v%d.%d", string_uuid(&uuid
),
935 (v
>> 8), (v
& 0xff));
937 if (profile
.next
!= profile
.end
)
938 printf(" [additional profile data]");
943 if (seq
.next
!= seq
.end
)
944 printf(" [additional data]\n");
948 print_additional_protocol_descriptor_lists(sdp_data_t
*data
)
950 sdp_data_t seq
, stack
, proto
;
953 sdp_get_seq(data
, &seq
);
955 while (sdp_get_seq(&seq
, &stack
))
956 while (sdp_get_seq(&stack
, &proto
))
957 print_protocol_descriptor(&proto
);
959 if (seq
.next
!= seq
.end
)
960 printf(" [additional data]\n");
964 print_sds_version_number_list(sdp_data_t
*data
)
970 if (!sdp_get_seq(data
, &list
))
974 while (sdp_get_uint16(&list
, &v
)) {
975 printf("%sv%d.%d", sep
, (v
>> 8), (v
& 0xff));
979 if (list
.next
!= list
.end
)
980 printf(" [additional data]");
986 print_ct_network(sdp_data_t
*data
)
990 if (!sdp_get_uint8(data
, &v
))
994 case 0x01: printf("PSTN"); break;
995 case 0x02: printf("ISDN"); break;
996 case 0x03: printf("GSM"); break;
997 case 0x04: printf("CDMA"); break;
998 case 0x05: printf("Analogue Cellular"); break;
999 case 0x06: printf("Packet Switched"); break;
1000 case 0x07: printf("Other"); break;
1001 default: printf("0x%02x", v
); break;
1008 print_asrc_features(sdp_data_t
*data
)
1012 if (!sdp_get_uint16(data
, &v
))
1016 printf("(0x%04x)", v
);
1019 if (v
& (1<<0)) printf(" Player\n");
1020 if (v
& (1<<1)) printf(" Microphone\n");
1021 if (v
& (1<<2)) printf(" Tuner\n");
1022 if (v
& (1<<3)) printf(" Mixer\n");
1026 print_asink_features(sdp_data_t
*data
)
1030 if (!sdp_get_uint16(data
, &v
))
1034 printf("(0x%04x)", v
);
1037 if (v
& (1<<0)) printf(" Headphone\n");
1038 if (v
& (1<<1)) printf(" Speaker\n");
1039 if (v
& (1<<2)) printf(" Recorder\n");
1040 if (v
& (1<<3)) printf(" Amplifier\n");
1044 print_avrcp_features(sdp_data_t
*data
)
1048 if (!sdp_get_uint16(data
, &v
))
1052 printf("(0x%04x)", v
);
1055 if (v
& (1<<0)) printf(" Category 1\n");
1056 if (v
& (1<<1)) printf(" Category 2\n");
1057 if (v
& (1<<2)) printf(" Category 3\n");
1058 if (v
& (1<<3)) printf(" Category 4\n");
1062 print_supported_data_stores(sdp_data_t
*data
)
1068 if (!sdp_get_seq(data
, &list
))
1072 while (sdp_get_uint8(&list
, &v
)) {
1077 case 0x01: printf("Phonebook"); break;
1078 case 0x03: printf("Calendar"); break;
1079 case 0x05: printf("Notes"); break;
1080 case 0x06: printf("Messages"); break;
1081 default: printf("0x%02x", v
); break;
1085 if (list
.next
!= list
.end
)
1086 printf(" [additional data]");
1092 print_supported_formats(sdp_data_t
*data
)
1098 if (!sdp_get_seq(data
, &list
))
1102 while (sdp_get_uint8(&list
, &v
)) {
1107 case 0x01: printf("vCard 2.1"); break;
1108 case 0x02: printf("vCard 3.0"); break;
1109 case 0x03: printf("vCal 1.0"); break;
1110 case 0x04: printf("iCal 2.0"); break;
1111 case 0x05: printf("vNote"); break;
1112 case 0x06: printf("vMessage"); break;
1113 case 0xff: printf("Any"); break;
1114 default: printf("0x%02x", v
); break;
1118 if (list
.next
!= list
.end
)
1119 printf(" [additional data]");
1125 print_hid_version(sdp_data_t
*data
)
1129 if (!sdp_get_uint16(data
, &v
))
1132 printf("v%d.%d.%d\n",
1133 ((v
& 0xff00) >> 8), ((v
& 0x00f0) >> 4), (v
& 0x000f));
1137 print_hid_device_subclass(sdp_data_t
*data
)
1141 if (!sdp_get_uint8(data
, &v
))
1144 switch ((v
& 0x3c) >> 2) {
1145 case 1: printf("Joystick"); break;
1146 case 2: printf("Gamepad"); break;
1147 case 3: printf("Remote Control"); break;
1148 case 4: printf("Sensing Device"); break;
1149 case 5: printf("Digitiser Tablet"); break;
1150 case 6: printf("Card Reader"); break;
1151 default: printf("Peripheral"); break;
1154 if (v
& 0x40) printf(" <Keyboard>");
1155 if (v
& 0x80) printf(" <Mouse>");
1161 print_hid_descriptor_list(sdp_data_t
*data
)
1163 sdp_data_t list
, seq
;
1170 if (!sdp_get_seq(data
, &list
))
1174 while (list
.next
< list
.end
) {
1175 if (!sdp_get_seq(&list
, &seq
)
1176 || !sdp_get_uint8(&seq
, &type
)
1177 || !sdp_get_str(&seq
, &str
, &len
))
1181 case 0x22: name
= "Report"; break;
1182 case 0x23: name
= "Physical Descriptor"; break;
1183 default: name
= ""; break;
1186 printf(" Type 0x%02x: %s\n", type
, name
);
1187 print_hexdump(" Data", (uint8_t *)str
, len
);
1189 if (seq
.next
!= seq
.end
)
1190 printf(" [additional data]\n");
1195 print_security_description(sdp_data_t
*data
)
1199 if (!sdp_get_uint16(data
, &v
))
1203 case 0x0000: printf("None"); break;
1204 case 0x0001: printf("Service-level Security"); break;
1205 case 0x0002: printf("802.1x Security"); break;
1206 default: printf("0x%04x", v
); break;
1213 print_hf_features(sdp_data_t
*data
)
1217 if (!sdp_get_uint16(data
, &v
))
1221 printf("(0x%04x)", v
);
1224 if (v
& (1<<0)) printf(" Echo Cancellation/Noise Reduction\n");
1225 if (v
& (1<<1)) printf(" Call Waiting\n");
1226 if (v
& (1<<2)) printf(" Caller Line Identification\n");
1227 if (v
& (1<<3)) printf(" Voice Recognition\n");
1228 if (v
& (1<<4)) printf(" Volume Control\n");
1232 print_hfag_network(sdp_data_t
*data
)
1236 if (!sdp_get_uint8(data
, &v
))
1240 case 0x01: printf("Ability to reject a call"); break;
1241 case 0x02: printf("No ability to reject a call"); break;
1242 default: printf("0x%02x", v
); break;
1249 print_hfag_features(sdp_data_t
*data
)
1253 if (!sdp_get_uint16(data
, &v
))
1257 printf("(0x%04x)", v
);
1260 if (v
& (1<<0)) printf(" 3 Way Calling\n");
1261 if (v
& (1<<1)) printf(" Echo Cancellation/Noise Reduction\n");
1262 if (v
& (1<<2)) printf(" Voice Recognition\n");
1263 if (v
& (1<<3)) printf(" In-band Ring Tone\n");
1264 if (v
& (1<<4)) printf(" Voice Tags\n");
1268 print_net_access_type(sdp_data_t
*data
)
1272 if (!sdp_get_uint16(data
, &v
))
1276 case 0x0000: printf("PSTN"); break;
1277 case 0x0001: printf("ISDN"); break;
1278 case 0x0002: printf("DSL"); break;
1279 case 0x0003: printf("Cable Modem"); break;
1280 case 0x0004: printf("10Mb Ethernet"); break;
1281 case 0x0005: printf("100Mb Ethernet"); break;
1282 case 0x0006: printf("4Mb Token Ring"); break;
1283 case 0x0007: printf("16Mb Token Ring"); break;
1284 case 0x0008: printf("100Mb Token Ring"); break;
1285 case 0x0009: printf("FDDI"); break;
1286 case 0x000a: printf("GSM"); break;
1287 case 0x000b: printf("CDMA"); break;
1288 case 0x000c: printf("GPRS"); break;
1289 case 0x000d: printf("3G Cellular"); break;
1290 case 0xfffe: printf("other"); break;
1291 default: printf("0x%04x", v
); break;
1298 print_pnp_source(sdp_data_t
*data
)
1302 if (!sdp_get_uint16(data
, &v
))
1306 case 0x0001: printf("Bluetooth SIG"); break;
1307 case 0x0002: printf("USB Implementers Forum"); break;
1308 default: printf("0x%04x", v
); break;
1315 print_mas_types(sdp_data_t
*data
)
1319 if (!sdp_get_uint8(data
, &v
))
1323 printf("(0x%02x)", v
);
1326 if (v
& (1<<0)) printf(" EMAIL\n");
1327 if (v
& (1<<1)) printf(" SMS_GSM\n");
1328 if (v
& (1<<2)) printf(" SMS_CDMA\n");
1329 if (v
& (1<<3)) printf(" MMS\n");
1333 print_supported_repositories(sdp_data_t
*data
)
1337 if (!sdp_get_uint8(data
, &v
))
1341 printf("(0x%02x)", v
);
1344 if (v
& (1<<0)) printf(" Local Phonebook\n");
1345 if (v
& (1<<1)) printf(" SIM Card\n");
1349 print_rfcomm(sdp_data_t
*data
)
1353 if (sdp_get_uint8(data
, &v
))
1354 printf(" (channel %d)", v
);
1358 print_bnep(sdp_data_t
*data
)
1364 if (!sdp_get_uint16(data
, &v
)
1365 || !sdp_get_seq(data
, &seq
))
1368 printf(" (v%d.%d", (v
>> 8), (v
& 0xff));
1370 while (sdp_get_uint16(&seq
, &v
)) {
1375 case 0x0800: printf("IPv4"); break;
1376 case 0x0806: printf("ARP"); break;
1377 case 0x8100: printf("802.1Q"); break;
1378 case 0x86dd: printf("IPv6"); break;
1379 default: printf("0x%04x", v
); break;
1384 if (seq
.next
!= seq
.end
)
1385 printf(" [additional data]");
1389 print_avctp(sdp_data_t
*data
)
1393 if (sdp_get_uint16(data
, &v
))
1394 printf(" (v%d.%d)", (v
>> 8), (v
& 0xff));
1398 print_avdtp(sdp_data_t
*data
)
1402 if (sdp_get_uint16(data
, &v
))
1403 printf(" (v%d.%d)", (v
>> 8), (v
& 0xff));
1407 print_l2cap(sdp_data_t
*data
)
1411 if (sdp_get_uint16(data
, &v
))
1412 printf(" (PSM 0x%04x)", v
);