1*9f6b0b0bSrillig /* $NetBSD: print.c,v 1.24 2021/08/27 17:41:39 rillig Exp $ */
2384153c1Splunky
3384153c1Splunky /*-
4384153c1Splunky * Copyright (c) 2009 The NetBSD Foundation, Inc.
5384153c1Splunky * All rights reserved.
6384153c1Splunky *
7384153c1Splunky * This code is derived from software contributed to The NetBSD Foundation
8384153c1Splunky * by Iain Hibbert.
9384153c1Splunky *
10384153c1Splunky * Redistribution and use in source and binary forms, with or without
11384153c1Splunky * modification, are permitted provided that the following conditions
12384153c1Splunky * are met:
13384153c1Splunky * 1. Redistributions of source code must retain the above copyright
14384153c1Splunky * notice, this list of conditions and the following disclaimer.
15384153c1Splunky * 2. Redistributions in binary form must reproduce the above copyright
16384153c1Splunky * notice, this list of conditions and the following disclaimer in the
17384153c1Splunky * documentation and/or other materials provided with the distribution.
18384153c1Splunky *
19384153c1Splunky * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20384153c1Splunky * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21384153c1Splunky * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22384153c1Splunky * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23384153c1Splunky * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24384153c1Splunky * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25384153c1Splunky * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26384153c1Splunky * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27384153c1Splunky * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28384153c1Splunky * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29384153c1Splunky * POSSIBILITY OF SUCH DAMAGE.
30384153c1Splunky */
31384153c1Splunky
32384153c1Splunky #include <sys/cdefs.h>
33*9f6b0b0bSrillig __RCSID("$NetBSD: print.c,v 1.24 2021/08/27 17:41:39 rillig Exp $");
34384153c1Splunky
35384153c1Splunky #include <ctype.h>
36384153c1Splunky #include <iconv.h>
37384153c1Splunky #include <langinfo.h>
38384153c1Splunky #include <sdp.h>
39384153c1Splunky #include <stdbool.h>
40384153c1Splunky #include <stdio.h>
41384153c1Splunky #include <stdlib.h>
42384153c1Splunky #include <string.h>
43384153c1Splunky #include <uuid.h>
44384153c1Splunky #include <vis.h>
45384153c1Splunky
46384153c1Splunky #include "sdpquery.h"
47384153c1Splunky
48384153c1Splunky typedef struct {
49384153c1Splunky uint16_t id;
50384153c1Splunky const char * desc;
51384153c1Splunky void (*print)(sdp_data_t *);
52384153c1Splunky } attr_t;
53384153c1Splunky
54384153c1Splunky typedef struct {
55384153c1Splunky uint16_t class;
56384153c1Splunky const char * desc;
57384153c1Splunky attr_t * attrs;
58384153c1Splunky size_t nattr;
59384153c1Splunky } service_t;
60384153c1Splunky
61384153c1Splunky typedef struct {
62384153c1Splunky uint16_t base;
63384153c1Splunky const char * codeset;
64384153c1Splunky } language_t;
65384153c1Splunky
66384153c1Splunky static const char *string_uuid(uuid_t *);
671803dc4bSplunky static const char *string_vis(const char *, size_t);
68384153c1Splunky
69384153c1Splunky static void print_hexdump(const char *, const uint8_t *, size_t);
702424b4a6Splunky static bool print_attribute(uint16_t, sdp_data_t *, attr_t *, size_t);
71384153c1Splunky static bool print_universal_attribute(uint16_t, sdp_data_t *);
72384153c1Splunky static bool print_language_attribute(uint16_t, sdp_data_t *);
73384153c1Splunky static bool print_service_attribute(uint16_t, sdp_data_t *);
74384153c1Splunky
75384153c1Splunky static void print_bool(sdp_data_t *);
76018ad52aSplunky static void print_uint8d(sdp_data_t *);
77384153c1Splunky static void print_uint8x(sdp_data_t *);
78384153c1Splunky static void print_uint16d(sdp_data_t *);
79447afe8dSplunky static void print_uint16x(sdp_data_t *);
80384153c1Splunky static void print_uint32d(sdp_data_t *);
8112d25979Splunky static void print_uint32x(sdp_data_t *);
82384153c1Splunky static void print_uuid(sdp_data_t *);
83384153c1Splunky static void print_uuid_list(sdp_data_t *);
84384153c1Splunky static void print_string(sdp_data_t *);
859a6467a3Splunky static void print_string_list(sdp_data_t *);
86384153c1Splunky static void print_url(sdp_data_t *);
87384153c1Splunky static void print_profile_version(sdp_data_t *);
88a54eea1cSplunky static void print_codeset_string(const char *, size_t, const char *);
89384153c1Splunky static void print_language_string(sdp_data_t *);
90a54eea1cSplunky static void print_utf8_string(sdp_data_t *);
91384153c1Splunky
92384153c1Splunky static void print_service_class_id_list(sdp_data_t *);
93384153c1Splunky static void print_protocol_descriptor(sdp_data_t *);
94384153c1Splunky static void print_protocol_descriptor_list(sdp_data_t *);
95384153c1Splunky static void print_language_base_attribute_id_list(sdp_data_t *);
96384153c1Splunky static void print_service_availability(sdp_data_t *);
97384153c1Splunky static void print_bluetooth_profile_descriptor_list(sdp_data_t *);
98384153c1Splunky static void print_additional_protocol_descriptor_lists(sdp_data_t *);
99384153c1Splunky static void print_sds_version_number_list(sdp_data_t *);
100384153c1Splunky static void print_ct_network(sdp_data_t *);
101384153c1Splunky static void print_asrc_features(sdp_data_t *);
102384153c1Splunky static void print_asink_features(sdp_data_t *);
103384153c1Splunky static void print_avrcp_features(sdp_data_t *);
104384153c1Splunky static void print_supported_data_stores(sdp_data_t *);
105384153c1Splunky static void print_supported_formats(sdp_data_t *);
106d82c7103Splunky static void print_wap_addr(sdp_data_t *);
107d82c7103Splunky static void print_wap_gateway(sdp_data_t *);
108d82c7103Splunky static void print_wap_type(sdp_data_t *);
109384153c1Splunky static void print_hid_version(sdp_data_t *);
110384153c1Splunky static void print_hid_device_subclass(sdp_data_t *);
111384153c1Splunky static void print_hid_descriptor_list(sdp_data_t *);
112e8fd30ebSplunky static void print_hid_langid_base_list(sdp_data_t *);
113384153c1Splunky static void print_security_description(sdp_data_t *);
114384153c1Splunky static void print_hf_features(sdp_data_t *);
115384153c1Splunky static void print_hfag_network(sdp_data_t *);
116384153c1Splunky static void print_hfag_features(sdp_data_t *);
117384153c1Splunky static void print_net_access_type(sdp_data_t *);
118447afe8dSplunky static void print_pnp_source(sdp_data_t *);
119018ad52aSplunky static void print_mas_types(sdp_data_t *);
120d82c7103Splunky static void print_map_features(sdp_data_t *);
121d82c7103Splunky static void print_pse_repositories(sdp_data_t *);
122d82c7103Splunky static void print_pse_features(sdp_data_t *);
123d82c7103Splunky static void print_hdp_features(sdp_data_t *);
124d82c7103Splunky static void print_hdp_specification(sdp_data_t *);
125d82c7103Splunky static void print_mcap_procedures(sdp_data_t *);
126c7407d62Splunky static void print_character_repertoires(sdp_data_t *);
12712d25979Splunky static void print_bip_capabilities(sdp_data_t *);
12812d25979Splunky static void print_bip_features(sdp_data_t *);
12912d25979Splunky static void print_bip_functions(sdp_data_t *);
13012d25979Splunky static void print_bip_capacity(sdp_data_t *);
131f88159b8Splunky static void print_1284id(sdp_data_t *);
132d82c7103Splunky static void print_ctn_features(sdp_data_t *);
133384153c1Splunky
134384153c1Splunky static void print_rfcomm(sdp_data_t *);
135d82c7103Splunky static void print_att(sdp_data_t *);
136384153c1Splunky static void print_bnep(sdp_data_t *);
137384153c1Splunky static void print_avctp(sdp_data_t *);
138384153c1Splunky static void print_avdtp(sdp_data_t *);
139384153c1Splunky static void print_l2cap(sdp_data_t *);
140384153c1Splunky
141384153c1Splunky attr_t protocol_list[] = {
142384153c1Splunky { 0x0001, "SDP", NULL },
143384153c1Splunky { 0x0002, "UDP", NULL },
144384153c1Splunky { 0x0003, "RFCOMM", print_rfcomm },
145384153c1Splunky { 0x0004, "TCP", NULL },
146384153c1Splunky { 0x0005, "TCS_BIN", NULL },
147384153c1Splunky { 0x0006, "TCS_AT", NULL },
148d82c7103Splunky { 0x0007, "ATT", print_att },
149384153c1Splunky { 0x0008, "OBEX", NULL },
150384153c1Splunky { 0x0009, "IP", NULL },
151384153c1Splunky { 0x000a, "FTP", NULL },
152384153c1Splunky { 0x000c, "HTTP", NULL },
153384153c1Splunky { 0x000e, "WSP", NULL },
154384153c1Splunky { 0x000f, "BNEP", print_bnep },
155384153c1Splunky { 0x0010, "UPNP", NULL },
156384153c1Splunky { 0x0011, "HIDP", NULL },
157384153c1Splunky { 0x0012, "HARDCOPY_CONTROL_CHANNEL", NULL },
158384153c1Splunky { 0x0014, "HARDCOPY_DATA_CHANNEL", NULL },
159384153c1Splunky { 0x0016, "HARDCOPY_NOTIFICATION", NULL },
160384153c1Splunky { 0x0017, "AVCTP", print_avctp },
161384153c1Splunky { 0x0019, "AVDTP", print_avdtp },
162384153c1Splunky { 0x001b, "CMTP", NULL },
163384153c1Splunky { 0x001d, "UDI_C_PLANE", NULL },
164018ad52aSplunky { 0x001e, "MCAP_CONTROL_CHANNEL", NULL },
165018ad52aSplunky { 0x001f, "MCAP_DATA_CHANNEL", NULL },
166384153c1Splunky { 0x0100, "L2CAP", print_l2cap },
167384153c1Splunky };
168384153c1Splunky
169384153c1Splunky attr_t universal_attrs[] = {
170384153c1Splunky { 0x0000, "ServiceRecordHandle", print_uint32x },
171384153c1Splunky { 0x0001, "ServiceClassIDList", print_service_class_id_list },
172384153c1Splunky { 0x0002, "ServiceRecordState", print_uint32x },
173384153c1Splunky { 0x0003, "ServiceID", print_uuid },
174384153c1Splunky { 0x0004, "ProtocolDescriptorList", print_protocol_descriptor_list },
175384153c1Splunky { 0x0005, "BrowseGroupList", print_uuid_list },
176384153c1Splunky { 0x0006, "LanguageBaseAttributeIDList", print_language_base_attribute_id_list },
177384153c1Splunky { 0x0007, "ServiceInfoTimeToLive", print_uint32d },
178384153c1Splunky { 0x0008, "ServiceAvailability", print_service_availability },
179384153c1Splunky { 0x0009, "BluetoothProfileDescriptorList", print_bluetooth_profile_descriptor_list },
180384153c1Splunky { 0x000a, "DocumentationURL", print_url },
181384153c1Splunky { 0x000b, "ClientExecutableURL", print_url },
182384153c1Splunky { 0x000c, "IconURL", print_url },
183384153c1Splunky { 0x000d, "AdditionalProtocolDescriptorLists", print_additional_protocol_descriptor_lists },
184384153c1Splunky };
185384153c1Splunky
186384153c1Splunky attr_t language_attrs[] = { /* Language Attribute Offsets */
187384153c1Splunky { 0x0000, "ServiceName", print_language_string },
188384153c1Splunky { 0x0001, "ServiceDescription", print_language_string },
189384153c1Splunky { 0x0002, "ProviderName", print_language_string },
190384153c1Splunky };
191384153c1Splunky
192384153c1Splunky attr_t sds_attrs[] = { /* Service Discovery Server */
193384153c1Splunky { 0x0200, "VersionNumberList", print_sds_version_number_list },
194384153c1Splunky { 0x0201, "ServiceDatabaseState", print_uint32x },
195384153c1Splunky };
196384153c1Splunky
197384153c1Splunky attr_t bgd_attrs[] = { /* Browse Group Descriptor */
198384153c1Splunky { 0x0200, "GroupID", print_uuid },
199384153c1Splunky };
200384153c1Splunky
201384153c1Splunky attr_t ct_attrs[] = { /* Cordless Telephony */
202384153c1Splunky { 0x0301, "ExternalNetwork", print_ct_network },
203384153c1Splunky };
204384153c1Splunky
205384153c1Splunky attr_t asrc_attrs[] = { /* Audio Source */
206384153c1Splunky { 0x0311, "SupportedFeatures", print_asrc_features },
207384153c1Splunky };
208384153c1Splunky
209384153c1Splunky attr_t asink_attrs[] = { /* Audio Sink */
210384153c1Splunky { 0x0311, "SupportedFeatures", print_asink_features },
211384153c1Splunky };
212384153c1Splunky
213384153c1Splunky attr_t avrcp_attrs[] = { /* Audio Video Remote Control Profile */
214384153c1Splunky { 0x0311, "SupportedFeatures", print_avrcp_features },
215384153c1Splunky };
216384153c1Splunky
217384153c1Splunky attr_t lan_attrs[] = { /* LAN Access Using PPP */
218384153c1Splunky { 0x0200, "IPSubnet", print_string },
219384153c1Splunky };
220384153c1Splunky
221384153c1Splunky attr_t dun_attrs[] = { /* Dialup Networking */
222384153c1Splunky { 0x0305, "AudioFeedbackSupport", print_bool },
223384153c1Splunky };
224384153c1Splunky
225384153c1Splunky attr_t irmc_sync_attrs[] = { /* IrMC Sync */
226384153c1Splunky { 0x0301, "SupportedDataStoresList", print_supported_data_stores },
227384153c1Splunky };
228384153c1Splunky
229384153c1Splunky attr_t opush_attrs[] = { /* Object Push */
230d82c7103Splunky { 0x0200, "GeopL2capPSM", print_uint16x },
231384153c1Splunky { 0x0303, "SupportedFormatsList", print_supported_formats },
232384153c1Splunky };
233384153c1Splunky
234d82c7103Splunky attr_t ft_attrs[] = { /* File Transfer */
235d82c7103Splunky { 0x0200, "GeopL2capPSM", print_uint16x },
236d82c7103Splunky };
237d82c7103Splunky
238384153c1Splunky attr_t hset_attrs[] = { /* Headset */
239384153c1Splunky { 0x0302, "RemoteAudioVolumeControl", print_bool },
240384153c1Splunky };
241384153c1Splunky
242384153c1Splunky attr_t fax_attrs[] = { /* Fax */
243384153c1Splunky { 0x0302, "FAXClass1", print_bool },
244384153c1Splunky { 0x0303, "FAXClass2.0", print_bool },
245384153c1Splunky { 0x0304, "FAXClass2", print_bool },
246384153c1Splunky { 0x0305, "AudioFeedbackSupport", print_bool },
247384153c1Splunky };
248384153c1Splunky
249d82c7103Splunky attr_t wap_attrs[] = { /* WAP Bearer */
250d82c7103Splunky { 0x0306, "NetworkAddress", print_wap_addr },
251d82c7103Splunky { 0x0307, "WAPGateway", print_wap_gateway },
252d82c7103Splunky { 0x0308, "HomePageURL", print_url },
253d82c7103Splunky { 0x0309, "WAPStackType", print_wap_type },
254d82c7103Splunky };
255d82c7103Splunky
256384153c1Splunky attr_t panu_attrs[] = { /* Personal Area Networking User */
257d82c7103Splunky { 0x0200, "IpSubnet", print_string },
258384153c1Splunky { 0x030a, "SecurityDescription", print_security_description },
259384153c1Splunky };
260384153c1Splunky
261384153c1Splunky attr_t nap_attrs[] = { /* Network Access Point */
262d82c7103Splunky { 0x0200, "IpSubnet", print_string },
263384153c1Splunky { 0x030a, "SecurityDescription", print_security_description },
264384153c1Splunky { 0x030b, "NetAccessType", print_net_access_type },
265384153c1Splunky { 0x030c, "MaxNetAccessRate", print_uint32d },
266384153c1Splunky { 0x030d, "IPv4Subnet", print_string },
267384153c1Splunky { 0x030e, "IPv6Subnet", print_string },
268384153c1Splunky };
269384153c1Splunky
270384153c1Splunky attr_t gn_attrs[] = { /* Group Network */
271d82c7103Splunky { 0x0200, "IpSubnet", print_string },
272384153c1Splunky { 0x030a, "SecurityDescription", print_security_description },
273384153c1Splunky { 0x030d, "IPv4Subnet", print_string },
274384153c1Splunky { 0x030e, "IPv6Subnet", print_string },
275384153c1Splunky };
276384153c1Splunky
277c7407d62Splunky attr_t bp_attrs[] = { /* Basic Printing */
2789a6467a3Splunky { 0x0350, "DocumentFormatsSupported", print_string_list },
279c7407d62Splunky { 0x0352, "CharacterRepertoiresSupported", print_character_repertoires },
2809a6467a3Splunky { 0x0354, "XHTML-PrintImageFormatsSupported", print_string_list },
281c7407d62Splunky { 0x0356, "ColorSupported", print_bool },
282f88159b8Splunky { 0x0358, "1284ID", print_1284id },
283a54eea1cSplunky { 0x035a, "PrinterName", print_utf8_string },
284a54eea1cSplunky { 0x035c, "PrinterLocation", print_utf8_string },
285c7407d62Splunky { 0x035e, "DuplexSupported", print_bool },
2869a6467a3Splunky { 0x0360, "MediaTypesSupported", print_string_list },
287c7407d62Splunky { 0x0362, "MaxMediaWidth", print_uint16d },
288c7407d62Splunky { 0x0364, "MaxMediaLength", print_uint16d },
289c7407d62Splunky { 0x0366, "EnhancedLayoutSupport", print_bool },
2909a6467a3Splunky { 0x0368, "RUIFormatsSupported", print_string_list },
291c7407d62Splunky { 0x0370, "ReferencePrintingRUISupported", print_bool },
292c7407d62Splunky { 0x0372, "DirectPrintingRUISupported", print_bool },
293c7407d62Splunky { 0x0374, "ReferencePrintingTopURL", print_url },
294c7407d62Splunky { 0x0376, "DirectPrintingTopURL", print_url },
295a54eea1cSplunky { 0x037a, "DeviceName", print_utf8_string },
296c7407d62Splunky };
297c7407d62Splunky
29812d25979Splunky attr_t bi_attrs[] = { /* Basic Imaging */
299d82c7103Splunky { 0x0200, "GeopL2capPSM", print_uint16x },
30012d25979Splunky { 0x0310, "SupportedCapabilities", print_bip_capabilities },
30112d25979Splunky { 0x0311, "SupportedFeatures", print_bip_features },
30212d25979Splunky { 0x0312, "SupportedFunctions", print_bip_functions },
30312d25979Splunky { 0x0313, "TotalImagingDataCapacity", print_bip_capacity },
30412d25979Splunky };
30512d25979Splunky
306384153c1Splunky attr_t hf_attrs[] = { /* Handsfree */
307384153c1Splunky { 0x0311, "SupportedFeatures", print_hf_features },
308384153c1Splunky };
309384153c1Splunky
310384153c1Splunky attr_t hfag_attrs[] = { /* Handsfree Audio Gateway */
311384153c1Splunky { 0x0301, "Network", print_hfag_network },
312384153c1Splunky { 0x0311, "SupportedFeatures", print_hfag_features },
313384153c1Splunky };
314384153c1Splunky
315c7407d62Splunky attr_t rui_attrs[] = { /* Reflected User Interface */
3169a6467a3Splunky { 0x0368, "RUIFormatsSupported", print_string_list },
317c7407d62Splunky { 0x0378, "PrinterAdminRUITopURL", print_url },
318c7407d62Splunky };
319c7407d62Splunky
320384153c1Splunky attr_t hid_attrs[] = { /* Human Interface Device */
321384153c1Splunky { 0x0200, "HIDDeviceReleaseNumber", print_hid_version },
322384153c1Splunky { 0x0201, "HIDParserVersion", print_hid_version },
323384153c1Splunky { 0x0202, "HIDDeviceSubClass", print_hid_device_subclass },
324384153c1Splunky { 0x0203, "HIDCountryCode", print_uint8x },
325384153c1Splunky { 0x0204, "HIDVirtualCable", print_bool },
326384153c1Splunky { 0x0205, "HIDReconnectInitiate", print_bool },
327384153c1Splunky { 0x0206, "HIDDescriptorList", print_hid_descriptor_list },
328e8fd30ebSplunky { 0x0207, "HIDLANGIDBaseList", print_hid_langid_base_list },
329384153c1Splunky { 0x0208, "HIDSDPDisable", print_bool },
330384153c1Splunky { 0x0209, "HIDBatteryPower", print_bool },
331384153c1Splunky { 0x020a, "HIDRemoteWake", print_bool },
332384153c1Splunky { 0x020b, "HIDProfileVersion", print_profile_version },
333384153c1Splunky { 0x020c, "HIDSupervisionTimeout", print_uint16d },
334384153c1Splunky { 0x020d, "HIDNormallyConnectable", print_bool },
335384153c1Splunky { 0x020e, "HIDBootDevice", print_bool },
336d82c7103Splunky { 0x020f, "HIDHostMaxLatency", print_uint16d },
337d82c7103Splunky { 0x0210, "HIDHostMinTimeout", print_uint16d },
338384153c1Splunky };
339384153c1Splunky
34010d720dbSplunky attr_t hcr_attrs[] = { /* Hardcopy Cable Replacement */
341f88159b8Splunky { 0x0300, "1284ID", print_1284id },
342a54eea1cSplunky { 0x0302, "DeviceName", print_utf8_string },
343a54eea1cSplunky { 0x0304, "FriendlyName", print_utf8_string },
344a54eea1cSplunky { 0x0306, "DeviceLocation", print_utf8_string },
34510d720dbSplunky };
34610d720dbSplunky
347d82c7103Splunky attr_t mps_attrs[] = { /* Multi-Profile Specification */
348d82c7103Splunky { 0x0200, "SingleDeviceSupportedScenarios", NULL },
349d82c7103Splunky { 0x0201, "MultiDeviceSupportedScenarios", NULL },
350d82c7103Splunky { 0x0202, "SupportedProfileAndProtocolDependencies", print_uint16x },
351d82c7103Splunky };
352d82c7103Splunky
353d82c7103Splunky attr_t cas_attrs[] = { /* Calendar, Tasks & Notes Access */
354d82c7103Splunky { 0x0315, "InstanceID", print_uint8d },
355d82c7103Splunky { 0x0317, "SupportedFeatures", print_ctn_features },
356d82c7103Splunky };
357d82c7103Splunky
358d82c7103Splunky attr_t cns_attrs[] = { /* Calendar, Tasks & Notes Notification */
359d82c7103Splunky { 0x0317, "SupportedFeatures", print_ctn_features },
360d82c7103Splunky };
361d82c7103Splunky
362447afe8dSplunky attr_t pnp_attrs[] = { /* Device ID */
363447afe8dSplunky { 0x0200, "SpecificationID", print_profile_version },
364447afe8dSplunky { 0x0201, "VendorID", print_uint16x },
365447afe8dSplunky { 0x0202, "ProductID", print_uint16x },
366447afe8dSplunky { 0x0203, "Version", print_hid_version },
367447afe8dSplunky { 0x0204, "PrimaryRecord", print_bool },
368447afe8dSplunky { 0x0205, "VendorIDSource", print_pnp_source },
369447afe8dSplunky };
370447afe8dSplunky
371018ad52aSplunky attr_t mas_attrs[] = { /* Message Access Server */
372d82c7103Splunky { 0x0200, "GeopL2capPSM", print_uint16x },
373018ad52aSplunky { 0x0315, "InstanceID", print_uint8d },
374018ad52aSplunky { 0x0316, "SupportedMessageTypes", print_mas_types },
375d82c7103Splunky { 0x0317, "SupportedFeatures", print_map_features },
376d82c7103Splunky };
377d82c7103Splunky
378d82c7103Splunky attr_t mns_attrs[] = { /* Message Notification Server */
379d82c7103Splunky { 0x0200, "GeopL2capPSM", print_uint16x },
380d82c7103Splunky { 0x0317, "SupportedFeatures", print_map_features },
381d82c7103Splunky };
382d82c7103Splunky
383d82c7103Splunky attr_t gnss_attrs[] = { /* Global Navigation Satellite System Server */
384d82c7103Splunky { 0x0200, "SupportedFeatures", print_uint16x },
385018ad52aSplunky };
386018ad52aSplunky
38746834460Splunky attr_t pse_attrs[] = { /* Phonebook Access Server */
388d82c7103Splunky { 0x0200, "GeopL2capPSM", print_uint16x },
389d82c7103Splunky { 0x0314, "SupportedRepositories", print_pse_repositories },
390d82c7103Splunky { 0x0317, "SupportedFeatures", print_pse_features },
391d82c7103Splunky };
392d82c7103Splunky
393d82c7103Splunky attr_t hdp_attrs[] = { /* Health Device Profile */
394d82c7103Splunky { 0x0200, "SupportedFeaturesList", print_hdp_features },
395d82c7103Splunky { 0x0301, "DataExchangeSpecification", print_hdp_specification },
396d82c7103Splunky { 0x0302, "MCAPSupportedProcedures", print_mcap_procedures },
39746834460Splunky };
39846834460Splunky
399384153c1Splunky #define A(a) a, __arraycount(a)
400384153c1Splunky service_t service_list[] = {
401384153c1Splunky { 0x1000, "Service Discovery Server", A(sds_attrs) },
402384153c1Splunky { 0x1001, "Browse Group Descriptor", A(bgd_attrs) },
403384153c1Splunky { 0x1002, "Public Browse Root", NULL, 0 },
404384153c1Splunky { 0x1101, "Serial Port", NULL, 0 },
405384153c1Splunky { 0x1102, "LAN Access Using PPP", A(lan_attrs) },
406384153c1Splunky { 0x1103, "Dialup Networking", A(dun_attrs) },
407384153c1Splunky { 0x1104, "IrMC Sync", A(irmc_sync_attrs) },
408384153c1Splunky { 0x1105, "Object Push", A(opush_attrs) },
409d82c7103Splunky { 0x1106, "File Transfer", A(ft_attrs) },
410384153c1Splunky { 0x1107, "IrMC Sync Command", NULL, 0 },
411384153c1Splunky { 0x1108, "Headset", A(hset_attrs) },
412384153c1Splunky { 0x1109, "Cordless Telephony", A(ct_attrs) },
413384153c1Splunky { 0x110a, "Audio Source", A(asrc_attrs) },
414384153c1Splunky { 0x110b, "Audio Sink", A(asink_attrs) },
415384153c1Splunky { 0x110c, "A/V Remote Control Target", A(avrcp_attrs) },
416384153c1Splunky { 0x110d, "Advanced Audio Distribution", NULL, 0 },
417384153c1Splunky { 0x110e, "A/V Remote Control", A(avrcp_attrs) },
418384153c1Splunky { 0x110f, "Video Conferencing", NULL, 0 },
419384153c1Splunky { 0x1110, "Intercom", NULL, 0 },
420384153c1Splunky { 0x1111, "Fax", A(fax_attrs) },
421384153c1Splunky { 0x1112, "Headset Audio Gateway", NULL, 0 },
422d82c7103Splunky { 0x1113, "WAP", A(wap_attrs) },
423384153c1Splunky { 0x1114, "WAP Client", NULL, 0 },
424384153c1Splunky { 0x1115, "Personal Area Networking User", A(panu_attrs) },
425384153c1Splunky { 0x1116, "Network Access Point", A(nap_attrs) },
426384153c1Splunky { 0x1117, "Group Network", A(gn_attrs) },
427b0e371d8Splunky { 0x1118, "Direct Printing", A(bp_attrs) },
428c7407d62Splunky { 0x1119, "Reference Printing", A(bp_attrs) },
429384153c1Splunky { 0x111a, "Imaging", NULL, 0 },
43012d25979Splunky { 0x111b, "Imaging Responder", A(bi_attrs) },
43112d25979Splunky { 0x111c, "Imaging Automatic Archive", A(bi_attrs) },
43212d25979Splunky { 0x111d, "Imaging Referenced Objects", A(bi_attrs) },
433384153c1Splunky { 0x111e, "Handsfree", A(hf_attrs) },
434384153c1Splunky { 0x111f, "Handsfree Audio Gateway", A(hfag_attrs) },
435384153c1Splunky { 0x1120, "Direct Printing Reference Objects", NULL, 0 },
436c7407d62Splunky { 0x1121, "Reflected User Interface", A(rui_attrs) },
437384153c1Splunky { 0x1122, "Basic Printing", NULL, 0 },
438b0e371d8Splunky { 0x1123, "Printing Status", A(bp_attrs) },
439384153c1Splunky { 0x1124, "Human Interface Device", A(hid_attrs) },
440384153c1Splunky { 0x1125, "Hardcopy Cable Replacement", NULL, 0 },
44110d720dbSplunky { 0x1126, "Hardcopy Cable Replacement Print", A(hcr_attrs) },
44210d720dbSplunky { 0x1127, "Hardcopy Cable Replacement Scan", A(hcr_attrs) },
443384153c1Splunky { 0x1128, "Common ISDN Access", NULL, 0 },
444384153c1Splunky { 0x1129, "Video Conferencing GW", NULL, 0 },
445384153c1Splunky { 0x112a, "UDI MT", NULL, 0 },
446384153c1Splunky { 0x112b, "UDI TA", NULL, 0 },
447384153c1Splunky { 0x112c, "Audio/Video", NULL, 0 },
448384153c1Splunky { 0x112d, "SIM Access", NULL, 0 },
44946834460Splunky { 0x112e, "Phonebook Access Client", NULL, 0 },
45046834460Splunky { 0x112f, "Phonebook Access Server", A(pse_attrs) },
451018ad52aSplunky { 0x1130, "Phonebook Access", NULL, 0 },
452018ad52aSplunky { 0x1131, "Headset HS", NULL, 0 },
453018ad52aSplunky { 0x1132, "Message Access Server", A(mas_attrs) },
454d82c7103Splunky { 0x1133, "Message Notification Server", A(mns_attrs) },
455018ad52aSplunky { 0x1134, "Message Access Profile", NULL, 0 },
456d82c7103Splunky { 0x1135, "Global Navigation Satellite System Profile", NULL, 0 },
457d82c7103Splunky { 0x1136, "Global Navigation Satellite System Server", A(gnss_attrs) },
458d82c7103Splunky { 0x1137, "3D Display", NULL, 0 },
459d82c7103Splunky { 0x1138, "3D Glasses", NULL, 0 },
460d82c7103Splunky { 0x1139, "3D Synchronization", NULL, 0 },
461d82c7103Splunky { 0x113a, "Multi-Profile Specification Profile",NULL, 0 },
462d82c7103Splunky { 0x113b, "Multi-Profile Specification Server", A(mps_attrs) },
463d82c7103Splunky { 0x113c, "Calendar, Tasks & Notes Access", A(cas_attrs) },
464d82c7103Splunky { 0x113d, "Calendar, Tasks & Notes Notification",A(cns_attrs) },
465d82c7103Splunky { 0x113e, "Calendar, Tasks & Notes Profile", NULL, 0 },
466447afe8dSplunky { 0x1200, "PNP Information", A(pnp_attrs) },
467384153c1Splunky { 0x1201, "Generic Networking", NULL, 0 },
468384153c1Splunky { 0x1202, "Generic File Transfer", NULL, 0 },
469384153c1Splunky { 0x1203, "Generic Audio", NULL, 0 },
470384153c1Splunky { 0x1204, "Generic Telephony", NULL, 0 },
471384153c1Splunky { 0x1205, "UPNP", NULL, 0 },
472384153c1Splunky { 0x1206, "UPNP IP", NULL, 0 },
473384153c1Splunky { 0x1300, "UPNP IP PAN", NULL, 0 },
474384153c1Splunky { 0x1301, "UPNP IP LAP", NULL, 0 },
475384153c1Splunky { 0x1302, "UPNP IP L2CAP", NULL, 0 },
476018ad52aSplunky { 0x1303, "Video Source", NULL, 0 },
477018ad52aSplunky { 0x1304, "Video Sink", NULL, 0 },
478018ad52aSplunky { 0x1305, "Video Distribution", NULL, 0 },
479018ad52aSplunky { 0x1400, "HDP", NULL, 0 },
480d82c7103Splunky { 0x1401, "HDP Source", A(hdp_attrs) },
481d82c7103Splunky { 0x1402, "HDP Sink", A(hdp_attrs) },
482d82c7103Splunky { 0x1800, "Generic Access Profile", NULL, 0 },
483d82c7103Splunky { 0x1801, "Generic Attribute Server", NULL, 0 },
484384153c1Splunky };
485384153c1Splunky #undef A
486384153c1Splunky
487384153c1Splunky /* extracted Service Class ID List */
488384153c1Splunky #define MAX_SERVICES 16
489384153c1Splunky static size_t nservices;
490384153c1Splunky static uint16_t service_class[MAX_SERVICES];
491384153c1Splunky
492384153c1Splunky /* extracted Language Base Attribute ID List */
493384153c1Splunky #define MAX_LANGUAGES 16
494384153c1Splunky static int nlanguages;
495384153c1Splunky static language_t language[MAX_LANGUAGES];
496384153c1Splunky static int current;
497384153c1Splunky
498384153c1Splunky static bool
sdp_get_uint8(sdp_data_t * d,uint8_t * vp)499384153c1Splunky sdp_get_uint8(sdp_data_t *d, uint8_t *vp)
500384153c1Splunky {
501384153c1Splunky uintmax_t v;
502384153c1Splunky
503384153c1Splunky if (sdp_data_type(d) != SDP_DATA_UINT8
504384153c1Splunky || !sdp_get_uint(d, &v))
505384153c1Splunky return false;
506384153c1Splunky
507384153c1Splunky *vp = (uint8_t)v;
508384153c1Splunky return true;
509384153c1Splunky }
510384153c1Splunky
511384153c1Splunky static bool
sdp_get_uint16(sdp_data_t * d,uint16_t * vp)512384153c1Splunky sdp_get_uint16(sdp_data_t *d, uint16_t *vp)
513384153c1Splunky {
514384153c1Splunky uintmax_t v;
515384153c1Splunky
516384153c1Splunky if (sdp_data_type(d) != SDP_DATA_UINT16
517384153c1Splunky || !sdp_get_uint(d, &v))
518384153c1Splunky return false;
519384153c1Splunky
520384153c1Splunky *vp = (uint16_t)v;
521384153c1Splunky return true;
522384153c1Splunky }
523384153c1Splunky
524384153c1Splunky static bool
sdp_get_uint32(sdp_data_t * d,uint32_t * vp)525384153c1Splunky sdp_get_uint32(sdp_data_t *d, uint32_t *vp)
526384153c1Splunky {
527384153c1Splunky uintmax_t v;
528384153c1Splunky
529384153c1Splunky if (sdp_data_type(d) != SDP_DATA_UINT32
530384153c1Splunky || !sdp_get_uint(d, &v))
531384153c1Splunky return false;
532384153c1Splunky
533384153c1Splunky *vp = (uint32_t)v;
534384153c1Splunky return true;
535384153c1Splunky }
536384153c1Splunky
53712d25979Splunky static bool
sdp_get_uint64(sdp_data_t * d,uint64_t * vp)53812d25979Splunky sdp_get_uint64(sdp_data_t *d, uint64_t *vp)
53912d25979Splunky {
54012d25979Splunky uintmax_t v;
54112d25979Splunky
54212d25979Splunky if (sdp_data_type(d) != SDP_DATA_UINT64
54312d25979Splunky || !sdp_get_uint(d, &v))
54412d25979Splunky return false;
54512d25979Splunky
54612d25979Splunky *vp = (uint64_t)v;
54712d25979Splunky return true;
54812d25979Splunky }
54912d25979Splunky
550384153c1Splunky void
print_record(sdp_data_t * rec)551384153c1Splunky print_record(sdp_data_t *rec)
552384153c1Splunky {
553384153c1Splunky sdp_data_t value;
554384153c1Splunky uint16_t id;
555384153c1Splunky
556384153c1Splunky nservices = 0;
557384153c1Splunky nlanguages = 0;
558384153c1Splunky current = -1;
559384153c1Splunky
560384153c1Splunky while (sdp_get_attr(rec, &id, &value)) {
561384153c1Splunky if (Xflag) {
562384153c1Splunky printf("AttributeID 0x%04x:\n", id);
5632424b4a6Splunky print_hexdump(" ", value.next,
5642424b4a6Splunky (size_t)(value.end - value.next));
565384153c1Splunky } else if (Rflag) {
566384153c1Splunky printf("AttributeID 0x%04x:\n", id);
567384153c1Splunky sdp_data_print(&value, 4);
568384153c1Splunky } else if (print_universal_attribute(id, &value)
569384153c1Splunky || print_language_attribute(id, &value)
570384153c1Splunky || print_service_attribute(id, &value)) {
571384153c1Splunky if (value.next != value.end)
572384153c1Splunky printf(" [additional data ignored]\n");
573384153c1Splunky } else {
574384153c1Splunky printf("AttributeID 0x%04x:\n", id);
575384153c1Splunky sdp_data_print(&value, 4);
576384153c1Splunky }
577384153c1Splunky }
578384153c1Splunky }
579384153c1Splunky
580384153c1Splunky static const char *
string_uuid(uuid_t * uuid)581384153c1Splunky string_uuid(uuid_t *uuid)
582384153c1Splunky {
583384153c1Splunky static char buf[64];
584384153c1Splunky const char *desc;
585384153c1Splunky uuid_t u;
586384153c1Splunky size_t i;
587384153c1Splunky
588384153c1Splunky u = *uuid;
589384153c1Splunky u.time_low = 0;
590384153c1Splunky if (!uuid_equal(&u, &BLUETOOTH_BASE_UUID, NULL)) {
591384153c1Splunky snprintf(buf, sizeof(buf),
592384153c1Splunky "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
593384153c1Splunky uuid->time_low, uuid->time_mid, uuid->time_hi_and_version,
594384153c1Splunky uuid->clock_seq_hi_and_reserved, uuid->clock_seq_low,
595384153c1Splunky uuid->node[0], uuid->node[1], uuid->node[2],
596384153c1Splunky uuid->node[3], uuid->node[4], uuid->node[5]);
597384153c1Splunky
598384153c1Splunky return buf;
599384153c1Splunky }
600384153c1Splunky
601384153c1Splunky desc = NULL;
602384153c1Splunky for (i = 0; i < __arraycount(service_list); i++) {
603384153c1Splunky if (uuid->time_low == service_list[i].class) {
604384153c1Splunky desc = service_list[i].desc;
605384153c1Splunky break;
606384153c1Splunky }
607384153c1Splunky }
608384153c1Splunky
609384153c1Splunky for (i = 0; i < __arraycount(protocol_list); i++) {
610384153c1Splunky if (uuid->time_low == protocol_list[i].id) {
611384153c1Splunky desc = protocol_list[i].desc;
612384153c1Splunky break;
613384153c1Splunky }
614384153c1Splunky }
615384153c1Splunky
616384153c1Splunky if (!Nflag && desc) {
617384153c1Splunky snprintf(buf, sizeof(buf), "%s", desc);
618384153c1Splunky return buf;
619384153c1Splunky }
620384153c1Splunky
621384153c1Splunky snprintf(buf, sizeof(buf), "%s%s(0x%*.*x)",
622384153c1Splunky (desc == NULL ? "" : desc),
623384153c1Splunky (desc == NULL ? "" : " "),
624384153c1Splunky (uuid->time_low > UINT16_MAX ? 8 : 4),
625384153c1Splunky (uuid->time_low > UINT16_MAX ? 8 : 4),
626384153c1Splunky uuid->time_low);
627384153c1Splunky
628384153c1Splunky return buf;
629384153c1Splunky }
630384153c1Splunky
631384153c1Splunky static const char *
string_vis(const char * src,size_t len)6321803dc4bSplunky string_vis(const char *src, size_t len)
633384153c1Splunky {
634384153c1Splunky static char buf[50];
635384153c1Splunky char *dst = buf;
6361803dc4bSplunky int style;
637384153c1Splunky
638cc676302Splunky buf[0] = '\0';
6391803dc4bSplunky style = VIS_CSTYLE | VIS_NL;
640384153c1Splunky while (len > 0 && (dst + 5) < (buf + sizeof(buf))) {
641384153c1Splunky dst = vis(dst, src[0], style, (len > 1 ? src[1] : 0));
642384153c1Splunky src++;
643384153c1Splunky len--;
644384153c1Splunky }
645384153c1Splunky
646384153c1Splunky return buf;
647384153c1Splunky }
648384153c1Splunky
649384153c1Splunky static void
print_hexdump(const char * title,const uint8_t * data,size_t len)650384153c1Splunky print_hexdump(const char *title, const uint8_t *data, size_t len)
651384153c1Splunky {
652384153c1Splunky int n, i;
653384153c1Splunky
654384153c1Splunky i = 0;
655384153c1Splunky n = printf("%s", title);
656384153c1Splunky
657384153c1Splunky while (len-- > 0) {
658384153c1Splunky if (++i > 8) {
659384153c1Splunky printf("\n%*s", n, "");
660384153c1Splunky i = 1;
661384153c1Splunky }
662384153c1Splunky
663384153c1Splunky printf(" 0x%02x", *data++);
664384153c1Splunky }
665384153c1Splunky
666384153c1Splunky printf("\n");
667384153c1Splunky }
668384153c1Splunky
669384153c1Splunky static bool
print_attribute(uint16_t id,sdp_data_t * value,attr_t * attr,size_t count)6702424b4a6Splunky print_attribute(uint16_t id, sdp_data_t *value, attr_t *attr, size_t count)
671384153c1Splunky {
6722424b4a6Splunky size_t i;
673384153c1Splunky
674384153c1Splunky for (i = 0; i < count; i++) {
675384153c1Splunky if (id == attr[i].id) {
676384153c1Splunky printf("%s", attr[i].desc);
677384153c1Splunky
678384153c1Splunky if (Nflag) {
679384153c1Splunky printf(" (");
680384153c1Splunky
681384153c1Splunky if (current != -1)
682384153c1Splunky printf("0x%04x + ", language[current].base);
683384153c1Splunky
684384153c1Splunky printf("0x%04x)", id);
685384153c1Splunky }
686384153c1Splunky
687384153c1Splunky printf(": ");
688384153c1Splunky
689384153c1Splunky if (attr[i].print == NULL) {
690384153c1Splunky printf("\n");
691384153c1Splunky sdp_data_print(value, 4);
692384153c1Splunky value->next = value->end;
693384153c1Splunky } else {
694384153c1Splunky (attr[i].print)(value);
695384153c1Splunky }
696384153c1Splunky
697384153c1Splunky return true;
698384153c1Splunky }
699384153c1Splunky }
700384153c1Splunky
701384153c1Splunky return false;
702384153c1Splunky }
703384153c1Splunky
704384153c1Splunky static bool
print_universal_attribute(uint16_t id,sdp_data_t * value)705384153c1Splunky print_universal_attribute(uint16_t id, sdp_data_t *value)
706384153c1Splunky {
707384153c1Splunky
708384153c1Splunky return print_attribute(id, value,
709384153c1Splunky universal_attrs, __arraycount(universal_attrs));
710384153c1Splunky }
711384153c1Splunky
712384153c1Splunky static bool
print_language_attribute(uint16_t id,sdp_data_t * value)713384153c1Splunky print_language_attribute(uint16_t id, sdp_data_t *value)
714384153c1Splunky {
715384153c1Splunky bool done = false;
716384153c1Splunky
717384153c1Splunky for (current = 0; current < nlanguages && !done; current++)
718384153c1Splunky done = print_attribute(id - language[current].base, value,
719384153c1Splunky language_attrs, __arraycount(language_attrs));
720384153c1Splunky
721384153c1Splunky current = -1;
722384153c1Splunky return done;
723384153c1Splunky }
724384153c1Splunky
725384153c1Splunky static bool
print_service_attribute(uint16_t id,sdp_data_t * value)726384153c1Splunky print_service_attribute(uint16_t id, sdp_data_t *value)
727384153c1Splunky {
728384153c1Splunky size_t i, j;
729384153c1Splunky
730384153c1Splunky for (i = 0; i < nservices; i++) {
731384153c1Splunky for (j = 0; j < __arraycount(service_list); j++) {
73245c72a01Splunky if (service_class[i] == service_list[j].class
73345c72a01Splunky && print_attribute(id, value,
73445c72a01Splunky service_list[j].attrs, service_list[j].nattr))
73545c72a01Splunky return true;
736384153c1Splunky }
737384153c1Splunky }
738384153c1Splunky
739384153c1Splunky return false;
740384153c1Splunky }
741384153c1Splunky
742384153c1Splunky static void
print_bool(sdp_data_t * data)743384153c1Splunky print_bool(sdp_data_t *data)
744384153c1Splunky {
745384153c1Splunky bool v;
746384153c1Splunky
747384153c1Splunky if (!sdp_get_bool(data, &v))
748384153c1Splunky return;
749384153c1Splunky
750384153c1Splunky printf("%s\n", (v ? "true" : "false"));
751384153c1Splunky }
752384153c1Splunky
753384153c1Splunky static void
print_uint8d(sdp_data_t * data)754018ad52aSplunky print_uint8d(sdp_data_t *data)
755018ad52aSplunky {
756018ad52aSplunky uint8_t v;
757018ad52aSplunky
758018ad52aSplunky if (!sdp_get_uint8(data, &v))
759018ad52aSplunky return;
760018ad52aSplunky
761018ad52aSplunky printf("%d\n", v);
762018ad52aSplunky }
763018ad52aSplunky
764018ad52aSplunky static void
print_uint8x(sdp_data_t * data)765384153c1Splunky print_uint8x(sdp_data_t *data)
766384153c1Splunky {
767384153c1Splunky uint8_t v;
768384153c1Splunky
769384153c1Splunky if (!sdp_get_uint8(data, &v))
770384153c1Splunky return;
771384153c1Splunky
772384153c1Splunky printf("0x%02x\n", v);
773384153c1Splunky }
774384153c1Splunky
775384153c1Splunky static void
print_uint16d(sdp_data_t * data)776384153c1Splunky print_uint16d(sdp_data_t *data)
777384153c1Splunky {
778384153c1Splunky uint16_t v;
779384153c1Splunky
780384153c1Splunky if (!sdp_get_uint16(data, &v))
781384153c1Splunky return;
782384153c1Splunky
783384153c1Splunky printf("%d\n", v);
784384153c1Splunky }
785384153c1Splunky
786384153c1Splunky static void
print_uint16x(sdp_data_t * data)787447afe8dSplunky print_uint16x(sdp_data_t *data)
788447afe8dSplunky {
789447afe8dSplunky uint16_t v;
790447afe8dSplunky
791447afe8dSplunky if (!sdp_get_uint16(data, &v))
792447afe8dSplunky return;
793447afe8dSplunky
794447afe8dSplunky printf("0x%04x\n", v);
795447afe8dSplunky }
796447afe8dSplunky
797447afe8dSplunky static void
print_uint32x(sdp_data_t * data)798384153c1Splunky print_uint32x(sdp_data_t *data)
799384153c1Splunky {
800384153c1Splunky uint32_t v;
801384153c1Splunky
802384153c1Splunky if (!sdp_get_uint32(data, &v))
803384153c1Splunky return;
804384153c1Splunky
805384153c1Splunky printf("0x%08x\n", v);
806384153c1Splunky }
807384153c1Splunky
808384153c1Splunky static void
print_uint32d(sdp_data_t * data)809384153c1Splunky print_uint32d(sdp_data_t *data)
810384153c1Splunky {
811384153c1Splunky uint32_t v;
812384153c1Splunky
813384153c1Splunky if (!sdp_get_uint32(data, &v))
814384153c1Splunky return;
815384153c1Splunky
816384153c1Splunky printf("%d\n", v);
817384153c1Splunky }
818384153c1Splunky
819384153c1Splunky static void
print_uuid(sdp_data_t * data)820384153c1Splunky print_uuid(sdp_data_t *data)
821384153c1Splunky {
822384153c1Splunky uuid_t uuid;
823384153c1Splunky
824384153c1Splunky if (!sdp_get_uuid(data, &uuid))
825384153c1Splunky return;
826384153c1Splunky
827384153c1Splunky printf("%s\n", string_uuid(&uuid));
828384153c1Splunky }
829384153c1Splunky
830384153c1Splunky static void
print_uuid_list(sdp_data_t * data)831384153c1Splunky print_uuid_list(sdp_data_t *data)
832384153c1Splunky {
833384153c1Splunky sdp_data_t seq;
834384153c1Splunky uuid_t uuid;
835384153c1Splunky
836384153c1Splunky if (!sdp_get_seq(data, &seq))
837384153c1Splunky return;
838384153c1Splunky
839384153c1Splunky printf("\n");
840384153c1Splunky while (sdp_get_uuid(&seq, &uuid))
841384153c1Splunky printf(" %s\n", string_uuid(&uuid));
842384153c1Splunky
843384153c1Splunky if (seq.next != seq.end)
844384153c1Splunky printf(" [additional data]\n");
845384153c1Splunky }
846384153c1Splunky
847384153c1Splunky static void
print_string(sdp_data_t * data)848384153c1Splunky print_string(sdp_data_t *data)
849384153c1Splunky {
850384153c1Splunky char *str;
851384153c1Splunky size_t len;
852384153c1Splunky
853384153c1Splunky if (!sdp_get_str(data, &str, &len))
854384153c1Splunky return;
855384153c1Splunky
8561803dc4bSplunky printf("\"%s\"\n", string_vis(str, len));
857384153c1Splunky }
858384153c1Splunky
859384153c1Splunky static void
print_string_list(sdp_data_t * data)8609a6467a3Splunky print_string_list(sdp_data_t *data)
8619a6467a3Splunky {
8629a6467a3Splunky char *str, *ep;
8639a6467a3Splunky size_t len, l;
8649a6467a3Splunky
8659a6467a3Splunky if (!sdp_get_str(data, &str, &len))
8669a6467a3Splunky return;
8679a6467a3Splunky
8689a6467a3Splunky printf("\n");
8699a6467a3Splunky while (len > 0) {
8709a6467a3Splunky ep = memchr(str, (int)',', len);
8719a6467a3Splunky if (ep == NULL) {
8729a6467a3Splunky l = len;
8739a6467a3Splunky len = 0;
8749a6467a3Splunky } else {
8759a6467a3Splunky l = (size_t)(ep - str);
8769a6467a3Splunky len -= l + 1;
8779a6467a3Splunky ep++;
8789a6467a3Splunky }
8791803dc4bSplunky printf(" %s\n", string_vis(str, l));
8809a6467a3Splunky str = ep;
8819a6467a3Splunky }
8829a6467a3Splunky }
8839a6467a3Splunky
8849a6467a3Splunky static void
print_url(sdp_data_t * data)885384153c1Splunky print_url(sdp_data_t *data)
886384153c1Splunky {
887384153c1Splunky char *url;
888384153c1Splunky size_t len;
889384153c1Splunky
890384153c1Splunky if (!sdp_get_url(data, &url, &len))
891384153c1Splunky return;
892384153c1Splunky
8931803dc4bSplunky printf("\"%s\"\n", string_vis(url, len));
894384153c1Splunky }
895384153c1Splunky
896384153c1Splunky static void
print_profile_version(sdp_data_t * data)897384153c1Splunky print_profile_version(sdp_data_t *data)
898384153c1Splunky {
899384153c1Splunky uint16_t v;
900384153c1Splunky
901384153c1Splunky if (!sdp_get_uint16(data, &v))
902384153c1Splunky return;
903384153c1Splunky
904384153c1Splunky printf("v%d.%d\n", (v >> 8), (v & 0xff));
905384153c1Splunky }
906384153c1Splunky
907a54eea1cSplunky static void
print_codeset_string(const char * src,size_t srclen,const char * codeset)908a54eea1cSplunky print_codeset_string(const char *src, size_t srclen, const char *codeset)
909a54eea1cSplunky {
910a54eea1cSplunky char buf[50], *dst;
911a54eea1cSplunky iconv_t ih;
9126e28978dSchristos size_t dstlen;
913a54eea1cSplunky
914a54eea1cSplunky dst = buf;
915a54eea1cSplunky dstlen = sizeof(buf);
916a54eea1cSplunky
917a54eea1cSplunky ih = iconv_open(nl_langinfo(CODESET), codeset);
918a54eea1cSplunky if (ih == (iconv_t)-1) {
919a54eea1cSplunky printf("Can't convert %s string\n", codeset);
920a54eea1cSplunky return;
921a54eea1cSplunky }
922a54eea1cSplunky
92377a1ad5fSkamil (void)iconv(ih, __UNCONST(&src), &srclen, &dst, &dstlen);
924a54eea1cSplunky
925a54eea1cSplunky iconv_close(ih);
926a54eea1cSplunky
927a54eea1cSplunky printf("\"%.*s%s\n", (int)(sizeof(buf) - dstlen), buf,
928a54eea1cSplunky (srclen > 0 ? " ..." : "\""));
929a54eea1cSplunky }
930a54eea1cSplunky
931384153c1Splunky /*
932384153c1Splunky * This should only be called through print_language_attribute() which
933384153c1Splunky * sets codeset of the string to be printed.
934384153c1Splunky */
935384153c1Splunky static void
print_language_string(sdp_data_t * data)936384153c1Splunky print_language_string(sdp_data_t *data)
937384153c1Splunky {
938a54eea1cSplunky char *str;
939a54eea1cSplunky size_t len;
940384153c1Splunky
941a54eea1cSplunky if (!sdp_get_str(data, &str, &len))
942384153c1Splunky return;
943384153c1Splunky
944a54eea1cSplunky print_codeset_string(str, len, language[current].codeset);
945384153c1Splunky }
946384153c1Splunky
947384153c1Splunky
948a54eea1cSplunky static void
print_utf8_string(sdp_data_t * data)949a54eea1cSplunky print_utf8_string(sdp_data_t *data)
950a54eea1cSplunky {
951a54eea1cSplunky char *str;
952a54eea1cSplunky size_t len;
953384153c1Splunky
954a54eea1cSplunky if (!sdp_get_str(data, &str, &len))
955a54eea1cSplunky return;
956384153c1Splunky
957a54eea1cSplunky print_codeset_string(str, len, "UTF-8");
958384153c1Splunky }
959384153c1Splunky
960384153c1Splunky static void
print_service_class_id_list(sdp_data_t * data)961384153c1Splunky print_service_class_id_list(sdp_data_t *data)
962384153c1Splunky {
963384153c1Splunky sdp_data_t seq;
964384153c1Splunky uuid_t uuid;
965384153c1Splunky
966384153c1Splunky if (!sdp_get_seq(data, &seq))
967384153c1Splunky return;
968384153c1Splunky
969384153c1Splunky printf("\n");
970384153c1Splunky while (sdp_get_uuid(&seq, &uuid)) {
971384153c1Splunky printf(" %s\n", string_uuid(&uuid));
972384153c1Splunky
973384153c1Splunky if (nservices < MAX_SERVICES) {
974384153c1Splunky service_class[nservices] = uuid.time_low;
975384153c1Splunky uuid.time_low = 0;
976384153c1Splunky if (uuid_equal(&uuid, &BLUETOOTH_BASE_UUID, NULL))
977384153c1Splunky nservices++;
978384153c1Splunky }
979384153c1Splunky }
980384153c1Splunky
981384153c1Splunky if (seq.next != seq.end)
982384153c1Splunky printf(" [additional data]\n");
983384153c1Splunky }
984384153c1Splunky
985384153c1Splunky static void
print_protocol_descriptor(sdp_data_t * data)986384153c1Splunky print_protocol_descriptor(sdp_data_t *data)
987384153c1Splunky {
988384153c1Splunky uuid_t u0, uuid;
989384153c1Splunky size_t i;
990384153c1Splunky
991384153c1Splunky if (!sdp_get_uuid(data, &uuid))
992384153c1Splunky return;
993384153c1Splunky
994384153c1Splunky u0 = uuid;
995384153c1Splunky u0.time_low = 0;
996384153c1Splunky if (uuid_equal(&u0, &BLUETOOTH_BASE_UUID, NULL)) {
997384153c1Splunky for (i = 0; i < __arraycount(protocol_list); i++) {
998384153c1Splunky if (uuid.time_low == protocol_list[i].id) {
999384153c1Splunky printf(" %s", protocol_list[i].desc);
1000384153c1Splunky
1001384153c1Splunky if (Nflag)
1002384153c1Splunky printf(" (0x%04x)", protocol_list[i].id);
1003384153c1Splunky
1004384153c1Splunky if (protocol_list[i].print)
1005384153c1Splunky (protocol_list[i].print)(data);
1006384153c1Splunky
1007384153c1Splunky if (data->next != data->end)
1008d82c7103Splunky printf(" [additional data]");
1009384153c1Splunky
1010384153c1Splunky printf("\n");
1011384153c1Splunky return;
1012384153c1Splunky }
1013384153c1Splunky }
1014384153c1Splunky }
1015384153c1Splunky
1016384153c1Splunky printf(" %s\n", string_uuid(&uuid));
1017384153c1Splunky sdp_data_print(data, 4);
1018384153c1Splunky data->next = data->end;
1019384153c1Splunky }
1020384153c1Splunky
1021384153c1Splunky static void
print_protocol_descriptor_list(sdp_data_t * data)1022384153c1Splunky print_protocol_descriptor_list(sdp_data_t *data)
1023384153c1Splunky {
1024384153c1Splunky sdp_data_t seq, proto;
1025384153c1Splunky
1026384153c1Splunky printf("\n");
1027384153c1Splunky sdp_get_alt(data, data); /* strip [optional] alt header */
1028384153c1Splunky
1029d82c7103Splunky while (sdp_get_seq(data, &seq)) {
1030384153c1Splunky while (sdp_get_seq(&seq, &proto))
1031384153c1Splunky print_protocol_descriptor(&proto);
1032d82c7103Splunky
1033d82c7103Splunky if (seq.next != seq.end)
1034d82c7103Splunky printf(" [additional protocol data]\n");
1035d82c7103Splunky }
1036d82c7103Splunky
1037d82c7103Splunky if (data->next != data->end)
1038d82c7103Splunky printf(" [additional data]\n");
1039384153c1Splunky }
1040384153c1Splunky
1041384153c1Splunky static void
print_language_base_attribute_id_list(sdp_data_t * data)1042384153c1Splunky print_language_base_attribute_id_list(sdp_data_t *data)
1043384153c1Splunky {
1044384153c1Splunky sdp_data_t list;
1045384153c1Splunky uint16_t v;
1046384153c1Splunky const char *codeset;
1047384153c1Splunky char lang[2];
1048384153c1Splunky
1049384153c1Splunky if (!sdp_get_seq(data, &list))
1050384153c1Splunky return;
1051384153c1Splunky
1052384153c1Splunky printf("\n");
1053384153c1Splunky while (list.next < list.end) {
1054384153c1Splunky /*
1055384153c1Splunky * ISO-639-1 natural language values are published at
1056384153c1Splunky * http://www.loc.gov/standards/iso639-2/php/code-list.php
1057384153c1Splunky */
1058384153c1Splunky if (!sdp_get_uint16(&list, &v))
1059384153c1Splunky break;
1060384153c1Splunky
1061384153c1Splunky be16enc(lang, v);
1062*9f6b0b0bSrillig if (!islower((unsigned char)lang[0]) ||
1063*9f6b0b0bSrillig !islower((unsigned char)lang[1]))
1064384153c1Splunky break;
1065384153c1Splunky
1066384153c1Splunky /*
1067384153c1Splunky * MIBenum values are published at
1068384153c1Splunky * http://www.iana.org/assignments/character-sets
1069384153c1Splunky */
1070384153c1Splunky if (!sdp_get_uint16(&list, &v))
1071384153c1Splunky break;
1072384153c1Splunky
1073384153c1Splunky switch(v) {
1074384153c1Splunky case 3: codeset = "US-ASCII"; break;
1075384153c1Splunky case 4: codeset = "ISO-8859-1"; break;
1076384153c1Splunky case 5: codeset = "ISO-8859-2"; break;
1077384153c1Splunky case 106: codeset = "UTF-8"; break;
1078384153c1Splunky case 1013: codeset = "UTF-16BE"; break;
1079384153c1Splunky case 1014: codeset = "UTF-16LE"; break;
1080384153c1Splunky default: codeset = "Unknown"; break;
1081384153c1Splunky }
1082384153c1Splunky
1083384153c1Splunky if (!sdp_get_uint16(&list, &v))
1084384153c1Splunky break;
1085384153c1Splunky
1086384153c1Splunky printf(" %.2s.%s base 0x%04x\n", lang, codeset, v);
1087384153c1Splunky
1088384153c1Splunky if (nlanguages < MAX_LANGUAGES) {
1089384153c1Splunky language[nlanguages].base = v;
1090384153c1Splunky language[nlanguages].codeset = codeset;
1091384153c1Splunky nlanguages++;
1092384153c1Splunky }
1093384153c1Splunky }
1094384153c1Splunky
1095384153c1Splunky if (list.next != list.end)
1096384153c1Splunky printf(" [additional data]\n");
1097384153c1Splunky }
1098384153c1Splunky
1099384153c1Splunky static void
print_service_availability(sdp_data_t * data)1100384153c1Splunky print_service_availability(sdp_data_t *data)
1101384153c1Splunky {
1102384153c1Splunky uint8_t v;
1103384153c1Splunky
1104384153c1Splunky if (!sdp_get_uint8(data, &v))
1105384153c1Splunky return;
1106384153c1Splunky
1107384153c1Splunky printf("%d/%d\n", v, UINT8_MAX);
1108384153c1Splunky }
1109384153c1Splunky
1110384153c1Splunky static void
print_bluetooth_profile_descriptor_list(sdp_data_t * data)1111384153c1Splunky print_bluetooth_profile_descriptor_list(sdp_data_t *data)
1112384153c1Splunky {
1113384153c1Splunky sdp_data_t seq, profile;
1114384153c1Splunky uuid_t uuid;
1115384153c1Splunky uint16_t v;
1116384153c1Splunky
1117384153c1Splunky if (!sdp_get_seq(data, &seq))
1118384153c1Splunky return;
1119384153c1Splunky
1120384153c1Splunky printf("\n");
1121384153c1Splunky while (seq.next < seq.end) {
1122384153c1Splunky if (!sdp_get_seq(&seq, &profile)
1123384153c1Splunky || !sdp_get_uuid(&profile, &uuid)
1124384153c1Splunky || !sdp_get_uint16(&profile, &v))
1125384153c1Splunky break;
1126384153c1Splunky
1127384153c1Splunky printf(" %s, v%d.%d", string_uuid(&uuid),
1128384153c1Splunky (v >> 8), (v & 0xff));
1129384153c1Splunky
1130384153c1Splunky if (profile.next != profile.end)
1131384153c1Splunky printf(" [additional profile data]");
1132384153c1Splunky
1133384153c1Splunky printf("\n");
1134384153c1Splunky }
1135384153c1Splunky
1136384153c1Splunky if (seq.next != seq.end)
1137384153c1Splunky printf(" [additional data]\n");
1138384153c1Splunky }
1139384153c1Splunky
1140384153c1Splunky static void
print_additional_protocol_descriptor_lists(sdp_data_t * data)1141384153c1Splunky print_additional_protocol_descriptor_lists(sdp_data_t *data)
1142384153c1Splunky {
1143384153c1Splunky sdp_data_t seq, stack, proto;
1144384153c1Splunky
1145384153c1Splunky printf("\n");
1146384153c1Splunky sdp_get_seq(data, &seq);
1147384153c1Splunky
1148384153c1Splunky while (sdp_get_seq(&seq, &stack))
1149384153c1Splunky while (sdp_get_seq(&stack, &proto))
1150384153c1Splunky print_protocol_descriptor(&proto);
1151384153c1Splunky
1152384153c1Splunky if (seq.next != seq.end)
1153384153c1Splunky printf(" [additional data]\n");
1154384153c1Splunky }
1155384153c1Splunky
1156384153c1Splunky static void
print_sds_version_number_list(sdp_data_t * data)1157384153c1Splunky print_sds_version_number_list(sdp_data_t *data)
1158384153c1Splunky {
1159384153c1Splunky sdp_data_t list;
1160384153c1Splunky const char *sep;
1161384153c1Splunky uint16_t v;
1162384153c1Splunky
1163384153c1Splunky if (!sdp_get_seq(data, &list))
1164384153c1Splunky return;
1165384153c1Splunky
1166384153c1Splunky sep = "";
1167384153c1Splunky while (sdp_get_uint16(&list, &v)) {
1168384153c1Splunky printf("%sv%d.%d", sep, (v >> 8), (v & 0xff));
1169384153c1Splunky sep = ", ";
1170384153c1Splunky }
1171384153c1Splunky
1172384153c1Splunky if (list.next != list.end)
1173384153c1Splunky printf(" [additional data]");
1174384153c1Splunky
1175384153c1Splunky printf("\n");
1176384153c1Splunky }
1177384153c1Splunky
1178384153c1Splunky static void
print_ct_network(sdp_data_t * data)1179384153c1Splunky print_ct_network(sdp_data_t *data)
1180384153c1Splunky {
1181384153c1Splunky uint8_t v;
1182384153c1Splunky
1183384153c1Splunky if (!sdp_get_uint8(data, &v))
1184384153c1Splunky return;
1185384153c1Splunky
1186384153c1Splunky switch (v) {
1187384153c1Splunky case 0x01: printf("PSTN"); break;
1188384153c1Splunky case 0x02: printf("ISDN"); break;
1189384153c1Splunky case 0x03: printf("GSM"); break;
1190384153c1Splunky case 0x04: printf("CDMA"); break;
1191384153c1Splunky case 0x05: printf("Analogue Cellular"); break;
1192384153c1Splunky case 0x06: printf("Packet Switched"); break;
1193384153c1Splunky case 0x07: printf("Other"); break;
1194384153c1Splunky default: printf("0x%02x", v); break;
1195384153c1Splunky }
1196384153c1Splunky
1197384153c1Splunky printf("\n");
1198384153c1Splunky }
1199384153c1Splunky
1200384153c1Splunky static void
print_asrc_features(sdp_data_t * data)1201384153c1Splunky print_asrc_features(sdp_data_t *data)
1202384153c1Splunky {
1203384153c1Splunky uint16_t v;
1204384153c1Splunky
1205384153c1Splunky if (!sdp_get_uint16(data, &v))
1206384153c1Splunky return;
1207384153c1Splunky
1208384153c1Splunky if (Nflag)
1209384153c1Splunky printf("(0x%04x)", v);
1210384153c1Splunky
1211384153c1Splunky printf("\n");
1212384153c1Splunky if (v & (1<<0)) printf(" Player\n");
1213384153c1Splunky if (v & (1<<1)) printf(" Microphone\n");
1214384153c1Splunky if (v & (1<<2)) printf(" Tuner\n");
1215384153c1Splunky if (v & (1<<3)) printf(" Mixer\n");
1216384153c1Splunky }
1217384153c1Splunky
1218384153c1Splunky static void
print_asink_features(sdp_data_t * data)1219384153c1Splunky print_asink_features(sdp_data_t *data)
1220384153c1Splunky {
1221384153c1Splunky uint16_t v;
1222384153c1Splunky
1223384153c1Splunky if (!sdp_get_uint16(data, &v))
1224384153c1Splunky return;
1225384153c1Splunky
1226384153c1Splunky if (Nflag)
1227384153c1Splunky printf("(0x%04x)", v);
1228384153c1Splunky
1229384153c1Splunky printf("\n");
1230384153c1Splunky if (v & (1<<0)) printf(" Headphone\n");
1231384153c1Splunky if (v & (1<<1)) printf(" Speaker\n");
1232384153c1Splunky if (v & (1<<2)) printf(" Recorder\n");
1233384153c1Splunky if (v & (1<<3)) printf(" Amplifier\n");
1234384153c1Splunky }
1235384153c1Splunky
1236384153c1Splunky static void
print_avrcp_features(sdp_data_t * data)1237384153c1Splunky print_avrcp_features(sdp_data_t *data)
1238384153c1Splunky {
1239384153c1Splunky uint16_t v;
1240384153c1Splunky
1241384153c1Splunky if (!sdp_get_uint16(data, &v))
1242384153c1Splunky return;
1243384153c1Splunky
1244384153c1Splunky if (Nflag)
1245384153c1Splunky printf("(0x%04x)", v);
1246384153c1Splunky
1247384153c1Splunky printf("\n");
1248384153c1Splunky if (v & (1<<0)) printf(" Category 1\n");
1249384153c1Splunky if (v & (1<<1)) printf(" Category 2\n");
1250384153c1Splunky if (v & (1<<2)) printf(" Category 3\n");
1251384153c1Splunky if (v & (1<<3)) printf(" Category 4\n");
1252384153c1Splunky }
1253384153c1Splunky
1254384153c1Splunky static void
print_supported_data_stores(sdp_data_t * data)1255384153c1Splunky print_supported_data_stores(sdp_data_t *data)
1256384153c1Splunky {
1257384153c1Splunky sdp_data_t list;
1258384153c1Splunky const char *sep;
1259384153c1Splunky uint8_t v;
1260384153c1Splunky
1261384153c1Splunky if (!sdp_get_seq(data, &list))
1262384153c1Splunky return;
1263384153c1Splunky
1264384153c1Splunky sep = "\n ";
1265384153c1Splunky while (sdp_get_uint8(&list, &v)) {
12669f52716dSjoerg printf("%s", sep);
1267384153c1Splunky sep = ", ";
1268384153c1Splunky
1269384153c1Splunky switch(v) {
1270384153c1Splunky case 0x01: printf("Phonebook"); break;
1271384153c1Splunky case 0x03: printf("Calendar"); break;
1272384153c1Splunky case 0x05: printf("Notes"); break;
1273384153c1Splunky case 0x06: printf("Messages"); break;
1274384153c1Splunky default: printf("0x%02x", v); break;
1275384153c1Splunky }
1276384153c1Splunky }
1277384153c1Splunky
1278384153c1Splunky if (list.next != list.end)
1279384153c1Splunky printf(" [additional data]");
1280384153c1Splunky
1281384153c1Splunky printf("\n");
1282384153c1Splunky }
1283384153c1Splunky
1284384153c1Splunky static void
print_supported_formats(sdp_data_t * data)1285384153c1Splunky print_supported_formats(sdp_data_t *data)
1286384153c1Splunky {
1287384153c1Splunky sdp_data_t list;
1288384153c1Splunky const char *sep;
1289384153c1Splunky uint8_t v;
1290384153c1Splunky
1291384153c1Splunky if (!sdp_get_seq(data, &list))
1292384153c1Splunky return;
1293384153c1Splunky
1294384153c1Splunky sep = "\n ";
1295384153c1Splunky while (sdp_get_uint8(&list, &v)) {
12969f52716dSjoerg printf("%s", sep);
1297384153c1Splunky sep = ", ";
1298384153c1Splunky
1299384153c1Splunky switch(v) {
1300384153c1Splunky case 0x01: printf("vCard 2.1"); break;
1301384153c1Splunky case 0x02: printf("vCard 3.0"); break;
1302384153c1Splunky case 0x03: printf("vCal 1.0"); break;
1303384153c1Splunky case 0x04: printf("iCal 2.0"); break;
1304384153c1Splunky case 0x05: printf("vNote"); break;
1305384153c1Splunky case 0x06: printf("vMessage"); break;
1306384153c1Splunky case 0xff: printf("Any"); break;
1307384153c1Splunky default: printf("0x%02x", v); break;
1308384153c1Splunky }
1309384153c1Splunky }
1310384153c1Splunky
1311384153c1Splunky if (list.next != list.end)
1312384153c1Splunky printf(" [additional data]");
1313384153c1Splunky
1314384153c1Splunky printf("\n");
1315384153c1Splunky }
1316384153c1Splunky
1317384153c1Splunky static void
print_wap_addr(sdp_data_t * data)1318d82c7103Splunky print_wap_addr(sdp_data_t *data)
1319d82c7103Splunky {
1320d82c7103Splunky uint32_t v;
1321d82c7103Splunky
1322d82c7103Splunky if (!sdp_get_uint32(data, &v))
1323d82c7103Splunky return;
1324d82c7103Splunky
1325d82c7103Splunky printf("%d.%d.%d.%d\n",
1326d82c7103Splunky ((v & 0xff000000) >> 24), ((v & 0x00ff0000) >> 16),
1327d82c7103Splunky ((v & 0x0000ff00) >> 8), (v & 0x000000ff));
1328d82c7103Splunky }
1329d82c7103Splunky
1330d82c7103Splunky static void
print_wap_gateway(sdp_data_t * data)1331d82c7103Splunky print_wap_gateway(sdp_data_t *data)
1332d82c7103Splunky {
1333d82c7103Splunky uint8_t v;
1334d82c7103Splunky
1335d82c7103Splunky if (!sdp_get_uint8(data, &v))
1336d82c7103Splunky return;
1337d82c7103Splunky
1338d82c7103Splunky switch(v) {
1339d82c7103Splunky case 0x01: printf("Origin Server\n"); break;
1340d82c7103Splunky case 0x02: printf("Proxy\n"); break;
1341d82c7103Splunky default: printf("0x%02x\n", v); break;
1342d82c7103Splunky }
1343d82c7103Splunky }
1344d82c7103Splunky
1345d82c7103Splunky static void
print_wap_type(sdp_data_t * data)1346d82c7103Splunky print_wap_type(sdp_data_t *data)
1347d82c7103Splunky {
1348d82c7103Splunky uint8_t v;
1349d82c7103Splunky
1350d82c7103Splunky if (!sdp_get_uint8(data, &v))
1351d82c7103Splunky return;
1352d82c7103Splunky
1353d82c7103Splunky switch(v) {
1354d82c7103Splunky case 0x01: printf("Connectionless\n"); break;
1355d82c7103Splunky case 0x02: printf("Connection Oriented\n");break;
1356d82c7103Splunky case 0x03: printf("Both\n"); break;
1357d82c7103Splunky default: printf("0x%02x\n", v); break;
1358d82c7103Splunky }
1359d82c7103Splunky }
1360d82c7103Splunky
1361d82c7103Splunky static void
print_hid_version(sdp_data_t * data)1362384153c1Splunky print_hid_version(sdp_data_t *data)
1363384153c1Splunky {
1364384153c1Splunky uint16_t v;
1365384153c1Splunky
1366384153c1Splunky if (!sdp_get_uint16(data, &v))
1367384153c1Splunky return;
1368384153c1Splunky
1369384153c1Splunky printf("v%d.%d.%d\n",
1370384153c1Splunky ((v & 0xff00) >> 8), ((v & 0x00f0) >> 4), (v & 0x000f));
1371384153c1Splunky }
1372384153c1Splunky
1373384153c1Splunky static void
print_hid_device_subclass(sdp_data_t * data)1374384153c1Splunky print_hid_device_subclass(sdp_data_t *data)
1375384153c1Splunky {
1376384153c1Splunky uint8_t v;
1377384153c1Splunky
1378384153c1Splunky if (!sdp_get_uint8(data, &v))
1379384153c1Splunky return;
1380384153c1Splunky
1381384153c1Splunky switch ((v & 0x3c) >> 2) {
1382384153c1Splunky case 1: printf("Joystick"); break;
1383384153c1Splunky case 2: printf("Gamepad"); break;
1384384153c1Splunky case 3: printf("Remote Control"); break;
1385384153c1Splunky case 4: printf("Sensing Device"); break;
1386384153c1Splunky case 5: printf("Digitiser Tablet"); break;
1387384153c1Splunky case 6: printf("Card Reader"); break;
1388384153c1Splunky default: printf("Peripheral"); break;
1389384153c1Splunky }
1390384153c1Splunky
1391384153c1Splunky if (v & 0x40) printf(" <Keyboard>");
1392384153c1Splunky if (v & 0x80) printf(" <Mouse>");
1393384153c1Splunky
1394384153c1Splunky printf("\n");
1395384153c1Splunky }
1396384153c1Splunky
1397384153c1Splunky static void
print_hid_descriptor_list(sdp_data_t * data)1398384153c1Splunky print_hid_descriptor_list(sdp_data_t *data)
1399384153c1Splunky {
1400384153c1Splunky sdp_data_t list, seq;
1401384153c1Splunky uint8_t type;
1402384153c1Splunky const char *name;
1403384153c1Splunky char *str;
1404384153c1Splunky size_t len;
1405384153c1Splunky
1406384153c1Splunky if (!sdp_get_seq(data, &list))
1407384153c1Splunky return;
1408384153c1Splunky
1409384153c1Splunky printf("\n");
1410384153c1Splunky while (list.next < list.end) {
1411384153c1Splunky if (!sdp_get_seq(&list, &seq)
1412384153c1Splunky || !sdp_get_uint8(&seq, &type)
1413384153c1Splunky || !sdp_get_str(&seq, &str, &len))
1414384153c1Splunky return;
1415384153c1Splunky
1416384153c1Splunky switch (type) {
1417384153c1Splunky case 0x22: name = "Report"; break;
1418384153c1Splunky case 0x23: name = "Physical Descriptor"; break;
1419384153c1Splunky default: name = ""; break;
1420384153c1Splunky }
1421384153c1Splunky
1422384153c1Splunky printf(" Type 0x%02x: %s\n", type, name);
1423384153c1Splunky print_hexdump(" Data", (uint8_t *)str, len);
1424384153c1Splunky
1425384153c1Splunky if (seq.next != seq.end)
1426384153c1Splunky printf(" [additional data]\n");
1427384153c1Splunky }
1428384153c1Splunky }
1429384153c1Splunky
1430384153c1Splunky static void
print_hid_langid_base_list(sdp_data_t * data)1431e8fd30ebSplunky print_hid_langid_base_list(sdp_data_t *data)
1432e8fd30ebSplunky {
1433e8fd30ebSplunky sdp_data_t list, seq;
1434e8fd30ebSplunky uint16_t lang, base;
1435e8fd30ebSplunky
1436e8fd30ebSplunky if (!sdp_get_seq(data, &list))
1437e8fd30ebSplunky return;
1438e8fd30ebSplunky
1439e8fd30ebSplunky while (list.next < list.end) {
1440e8fd30ebSplunky if (!sdp_get_seq(&list, &seq)
1441e8fd30ebSplunky || !sdp_get_uint16(&seq, &lang)
1442e8fd30ebSplunky || !sdp_get_uint16(&seq, &base))
1443e8fd30ebSplunky return;
1444e8fd30ebSplunky
1445e8fd30ebSplunky printf("\n ");
1446e8fd30ebSplunky /*
1447e8fd30ebSplunky * The language is encoded according to the
1448e8fd30ebSplunky * "Universal Serial Bus Language Identifiers (LANGIDs)"
1449e8fd30ebSplunky * specification. It does not seem worth listing them all
1450e8fd30ebSplunky * here, but feel free to add if you notice any being used.
1451e8fd30ebSplunky */
1452e8fd30ebSplunky switch (lang) {
1453e8fd30ebSplunky case 0x0409: printf("English (US)"); break;
1454e8fd30ebSplunky case 0x0809: printf("English (UK)"); break;
1455e8fd30ebSplunky default: printf("0x%04x", lang); break;
1456e8fd30ebSplunky }
1457e8fd30ebSplunky
1458d82c7103Splunky printf(" base 0x%04x%s\n", base,
1459d82c7103Splunky (seq.next == seq.end ? "" : " [additional data]"));
1460e8fd30ebSplunky }
1461e8fd30ebSplunky }
1462e8fd30ebSplunky
1463e8fd30ebSplunky static void
print_security_description(sdp_data_t * data)1464384153c1Splunky print_security_description(sdp_data_t *data)
1465384153c1Splunky {
1466384153c1Splunky uint16_t v;
1467384153c1Splunky
1468384153c1Splunky if (!sdp_get_uint16(data, &v))
1469384153c1Splunky return;
1470384153c1Splunky
1471384153c1Splunky switch (v) {
1472384153c1Splunky case 0x0000: printf("None"); break;
1473384153c1Splunky case 0x0001: printf("Service-level Security"); break;
1474384153c1Splunky case 0x0002: printf("802.1x Security"); break;
1475384153c1Splunky default: printf("0x%04x", v); break;
1476384153c1Splunky }
1477384153c1Splunky
1478384153c1Splunky printf("\n");
1479384153c1Splunky }
1480384153c1Splunky
1481384153c1Splunky static void
print_hf_features(sdp_data_t * data)1482384153c1Splunky print_hf_features(sdp_data_t *data)
1483384153c1Splunky {
1484384153c1Splunky uint16_t v;
1485384153c1Splunky
1486384153c1Splunky if (!sdp_get_uint16(data, &v))
1487384153c1Splunky return;
1488384153c1Splunky
1489384153c1Splunky if (Nflag)
1490384153c1Splunky printf("(0x%04x)", v);
1491384153c1Splunky
1492384153c1Splunky printf("\n");
1493384153c1Splunky if (v & (1<<0)) printf(" Echo Cancellation/Noise Reduction\n");
1494384153c1Splunky if (v & (1<<1)) printf(" Call Waiting\n");
1495384153c1Splunky if (v & (1<<2)) printf(" Caller Line Identification\n");
1496384153c1Splunky if (v & (1<<3)) printf(" Voice Recognition\n");
1497384153c1Splunky if (v & (1<<4)) printf(" Volume Control\n");
1498384153c1Splunky }
1499384153c1Splunky
1500384153c1Splunky static void
print_hfag_network(sdp_data_t * data)1501384153c1Splunky print_hfag_network(sdp_data_t *data)
1502384153c1Splunky {
1503384153c1Splunky uint8_t v;
1504384153c1Splunky
1505384153c1Splunky if (!sdp_get_uint8(data, &v))
1506384153c1Splunky return;
1507384153c1Splunky
1508384153c1Splunky switch (v) {
1509384153c1Splunky case 0x01: printf("Ability to reject a call"); break;
1510384153c1Splunky case 0x02: printf("No ability to reject a call"); break;
1511384153c1Splunky default: printf("0x%02x", v); break;
1512384153c1Splunky }
1513384153c1Splunky
1514384153c1Splunky printf("\n");
1515384153c1Splunky }
1516384153c1Splunky
1517384153c1Splunky static void
print_hfag_features(sdp_data_t * data)1518384153c1Splunky print_hfag_features(sdp_data_t *data)
1519384153c1Splunky {
1520384153c1Splunky uint16_t v;
1521384153c1Splunky
1522384153c1Splunky if (!sdp_get_uint16(data, &v))
1523384153c1Splunky return;
1524384153c1Splunky
1525384153c1Splunky if (Nflag)
1526384153c1Splunky printf("(0x%04x)", v);
1527384153c1Splunky
1528384153c1Splunky printf("\n");
1529384153c1Splunky if (v & (1<<0)) printf(" 3 Way Calling\n");
1530384153c1Splunky if (v & (1<<1)) printf(" Echo Cancellation/Noise Reduction\n");
1531384153c1Splunky if (v & (1<<2)) printf(" Voice Recognition\n");
1532384153c1Splunky if (v & (1<<3)) printf(" In-band Ring Tone\n");
1533384153c1Splunky if (v & (1<<4)) printf(" Voice Tags\n");
1534384153c1Splunky }
1535384153c1Splunky
1536384153c1Splunky static void
print_net_access_type(sdp_data_t * data)1537384153c1Splunky print_net_access_type(sdp_data_t *data)
1538384153c1Splunky {
1539384153c1Splunky uint16_t v;
1540384153c1Splunky
1541384153c1Splunky if (!sdp_get_uint16(data, &v))
1542384153c1Splunky return;
1543384153c1Splunky
1544384153c1Splunky switch(v) {
1545384153c1Splunky case 0x0000: printf("PSTN"); break;
1546384153c1Splunky case 0x0001: printf("ISDN"); break;
1547384153c1Splunky case 0x0002: printf("DSL"); break;
1548384153c1Splunky case 0x0003: printf("Cable Modem"); break;
1549384153c1Splunky case 0x0004: printf("10Mb Ethernet"); break;
1550384153c1Splunky case 0x0005: printf("100Mb Ethernet"); break;
1551384153c1Splunky case 0x0006: printf("4Mb Token Ring"); break;
1552384153c1Splunky case 0x0007: printf("16Mb Token Ring"); break;
1553384153c1Splunky case 0x0008: printf("100Mb Token Ring"); break;
1554384153c1Splunky case 0x0009: printf("FDDI"); break;
1555384153c1Splunky case 0x000a: printf("GSM"); break;
1556384153c1Splunky case 0x000b: printf("CDMA"); break;
1557384153c1Splunky case 0x000c: printf("GPRS"); break;
1558384153c1Splunky case 0x000d: printf("3G Cellular"); break;
1559384153c1Splunky case 0xfffe: printf("other"); break;
1560384153c1Splunky default: printf("0x%04x", v); break;
1561384153c1Splunky }
1562384153c1Splunky
1563384153c1Splunky printf("\n");
1564384153c1Splunky }
1565384153c1Splunky
1566384153c1Splunky static void
print_pnp_source(sdp_data_t * data)1567447afe8dSplunky print_pnp_source(sdp_data_t *data)
1568447afe8dSplunky {
1569447afe8dSplunky uint16_t v;
1570447afe8dSplunky
1571447afe8dSplunky if (!sdp_get_uint16(data, &v))
1572447afe8dSplunky return;
1573447afe8dSplunky
1574447afe8dSplunky switch (v) {
1575447afe8dSplunky case 0x0001: printf("Bluetooth SIG"); break;
1576447afe8dSplunky case 0x0002: printf("USB Implementers Forum"); break;
1577447afe8dSplunky default: printf("0x%04x", v); break;
1578447afe8dSplunky }
1579447afe8dSplunky
1580447afe8dSplunky printf("\n");
1581447afe8dSplunky }
1582447afe8dSplunky
1583447afe8dSplunky static void
print_mas_types(sdp_data_t * data)1584018ad52aSplunky print_mas_types(sdp_data_t *data)
1585018ad52aSplunky {
1586018ad52aSplunky uint8_t v;
1587018ad52aSplunky
1588018ad52aSplunky if (!sdp_get_uint8(data, &v))
1589018ad52aSplunky return;
1590018ad52aSplunky
1591018ad52aSplunky if (Nflag)
1592018ad52aSplunky printf("(0x%02x)", v);
1593018ad52aSplunky
1594018ad52aSplunky printf("\n");
1595018ad52aSplunky if (v & (1<<0)) printf(" EMAIL\n");
1596018ad52aSplunky if (v & (1<<1)) printf(" SMS_GSM\n");
1597018ad52aSplunky if (v & (1<<2)) printf(" SMS_CDMA\n");
1598018ad52aSplunky if (v & (1<<3)) printf(" MMS\n");
1599018ad52aSplunky }
1600018ad52aSplunky
1601018ad52aSplunky static void
print_map_features(sdp_data_t * data)1602d82c7103Splunky print_map_features(sdp_data_t *data)
1603d82c7103Splunky {
1604d82c7103Splunky uint32_t v;
1605d82c7103Splunky
1606d82c7103Splunky if (!sdp_get_uint32(data, &v))
1607d82c7103Splunky return;
1608d82c7103Splunky
1609d82c7103Splunky if (Nflag)
1610d82c7103Splunky printf("(0x%08x)", v);
1611d82c7103Splunky
1612d82c7103Splunky printf("\n");
1613d82c7103Splunky if (v & (1<<0)) printf(" Notification Registration\n");
1614d82c7103Splunky if (v & (1<<1)) printf(" Notification\n");
1615d82c7103Splunky if (v & (1<<2)) printf(" Browsing\n");
1616d82c7103Splunky if (v & (1<<3)) printf(" Uploading\n");
1617d82c7103Splunky if (v & (1<<4)) printf(" Delete\n");
1618d82c7103Splunky if (v & (1<<5)) printf(" Instance Information\n");
1619d82c7103Splunky if (v & (1<<6)) printf(" Extended Event Report 1.1\n");
1620d82c7103Splunky }
1621d82c7103Splunky
1622d82c7103Splunky static void
print_pse_repositories(sdp_data_t * data)1623d82c7103Splunky print_pse_repositories(sdp_data_t *data)
162446834460Splunky {
162546834460Splunky uint8_t v;
162646834460Splunky
162746834460Splunky if (!sdp_get_uint8(data, &v))
162846834460Splunky return;
162946834460Splunky
163046834460Splunky if (Nflag)
163146834460Splunky printf("(0x%02x)", v);
163246834460Splunky
163346834460Splunky printf("\n");
163446834460Splunky if (v & (1<<0)) printf(" Local Phonebook\n");
163546834460Splunky if (v & (1<<1)) printf(" SIM Card\n");
1636d82c7103Splunky if (v & (1<<2)) printf(" Speed Dial\n");
1637d82c7103Splunky if (v & (1<<3)) printf(" Favorites\n");
1638d82c7103Splunky }
1639d82c7103Splunky
1640d82c7103Splunky static void
print_pse_features(sdp_data_t * data)1641d82c7103Splunky print_pse_features(sdp_data_t *data)
1642d82c7103Splunky {
1643d82c7103Splunky uint32_t v;
1644d82c7103Splunky
1645d82c7103Splunky if (!sdp_get_uint32(data, &v))
1646d82c7103Splunky return;
1647d82c7103Splunky
1648d82c7103Splunky if (Nflag)
1649d82c7103Splunky printf("(0x%08x)", v);
1650d82c7103Splunky
1651d82c7103Splunky printf("\n");
1652d82c7103Splunky if (v & (1<<0)) printf(" Download\n");
1653d82c7103Splunky if (v & (1<<1)) printf(" Browsing\n");
1654d82c7103Splunky if (v & (1<<2)) printf(" Database Identifier\n");
1655d82c7103Splunky if (v & (1<<3)) printf(" Folder Version Counters\n");
1656d82c7103Splunky if (v & (1<<4)) printf(" vCard Selecting\n");
1657d82c7103Splunky if (v & (1<<5)) printf(" Enhanced Missed Calls\n");
1658d82c7103Splunky if (v & (1<<6)) printf(" X-BT-UCI vCard Property\n");
1659d82c7103Splunky if (v & (1<<7)) printf(" X-BT-UID vCard Property\n");
1660d82c7103Splunky if (v & (1<<8)) printf(" Contact Referencing\n");
1661d82c7103Splunky if (v & (1<<9)) printf(" Default Contact Image Format\n");
1662d82c7103Splunky }
1663d82c7103Splunky
1664d82c7103Splunky static void
print_hdp_features(sdp_data_t * data)1665d82c7103Splunky print_hdp_features(sdp_data_t *data)
1666d82c7103Splunky {
1667d82c7103Splunky sdp_data_t seq, feature;
1668d82c7103Splunky char *str;
1669d82c7103Splunky size_t len;
1670d82c7103Splunky uint16_t type;
1671d82c7103Splunky uint8_t id, role;
1672d82c7103Splunky
1673d82c7103Splunky if (!sdp_get_seq(data, &seq))
1674d82c7103Splunky return;
1675d82c7103Splunky
1676d82c7103Splunky printf("\n");
1677d82c7103Splunky while (sdp_get_seq(&seq, &feature)) {
1678d82c7103Splunky if (!sdp_get_uint8(&feature, &id)
1679d82c7103Splunky || !sdp_get_uint16(&feature, &type)
1680d82c7103Splunky || !sdp_get_uint8(&feature, &role))
1681d82c7103Splunky break;
1682d82c7103Splunky
1683d82c7103Splunky printf(" # %d: ", id);
1684d82c7103Splunky
1685d82c7103Splunky switch(type) {
1686d82c7103Splunky case 0x1004: printf("Pulse Oximeter"); break;
1687d82c7103Splunky case 0x1006: printf("Basic ECG"); break;
1688d82c7103Splunky case 0x1007: printf("Blood Pressure Monitor"); break;
1689d82c7103Splunky case 0x1008: printf("Body Thermometer"); break;
1690d82c7103Splunky case 0x100F: printf("Body Weight Scale"); break;
1691d82c7103Splunky case 0x1011: printf("Glucose Meter"); break;
1692d82c7103Splunky case 0x1012: printf("International Normalized Ratio Monitor"); break;
1693d82c7103Splunky case 0x1014: printf("Body Composition Analyzer"); break;
1694d82c7103Splunky case 0x1015: printf("Peak Flow Monitor"); break;
1695d82c7103Splunky case 0x1029: printf("Cardiovascular Fitness and Activity Monitor"); break;
1696d82c7103Splunky case 0x1068: printf("Step Counter"); break;
1697d82c7103Splunky case 0x102A: printf("Strength Fitness Equipment"); break;
1698d82c7103Splunky case 0x1047: printf("Independent Living Activity Hub"); break;
1699d82c7103Splunky case 0x1075: printf("Fall Sensor"); break;
1700d82c7103Splunky case 0x1076: printf("Personal Emergency Response Sensor"); break;
1701d82c7103Splunky case 0x1077: printf("Smoke Sensor"); break;
1702d82c7103Splunky case 0x1078: printf("Carbon Monoxide Sensor"); break;
1703d82c7103Splunky case 0x1079: printf("Water Sensor"); break;
1704d82c7103Splunky case 0x107A: printf("Gas Sensor"); break;
1705d82c7103Splunky case 0x107B: printf("Motion Sensor"); break;
1706d82c7103Splunky case 0x107C: printf("Property Exit Sensor"); break;
1707d82c7103Splunky case 0x107D: printf("Enuresis Sensor"); break;
1708d82c7103Splunky case 0x107E: printf("Contact Closure Sensor"); break;
1709d82c7103Splunky case 0x107F: printf("Usage Sensor"); break;
1710d82c7103Splunky case 0x1080: printf("Switch Sensor"); break;
1711d82c7103Splunky case 0x1081: printf("Medication Dosing Sensor"); break;
1712d82c7103Splunky case 0x1082: printf("Temperature Sensor"); break;
1713d82c7103Splunky case 0x1048: printf("Medication monitor"); break;
1714d82c7103Splunky default: printf("Type 0x%04x", type); break;
1715d82c7103Splunky }
1716d82c7103Splunky
1717d82c7103Splunky switch(role) {
1718d82c7103Splunky case 0x00: printf(" [Source]"); break;
1719d82c7103Splunky case 0x01: printf(" [Sink]"); break;
1720d82c7103Splunky default: printf(" [Role 0x%02x]", role); break;
1721d82c7103Splunky }
1722d82c7103Splunky
1723d82c7103Splunky printf("\n");
1724d82c7103Splunky
1725d82c7103Splunky if (sdp_get_str(&feature, &str, &len)) {
1726d82c7103Splunky int n;
1727d82c7103Splunky
1728d82c7103Splunky /* This optional human-readable description should
1729d82c7103Splunky * be in the primary language encoding, which ought
1730d82c7103Splunky * to have a base of 0x0100 or if there isn't one,
1731d82c7103Splunky * use the first encoding listed
1732d82c7103Splunky */
1733d82c7103Splunky for (n = 0; n < nlanguages; n++) {
1734d82c7103Splunky if (language[n].base == 0x0100)
1735d82c7103Splunky break;
1736d82c7103Splunky }
1737d82c7103Splunky
1738d82c7103Splunky printf(" # %d: ", id);
1739d82c7103Splunky if (n < nlanguages)
1740d82c7103Splunky print_codeset_string(str, len, language[n].codeset);
1741d82c7103Splunky else if (n > 0)
1742d82c7103Splunky print_codeset_string(str, len, language[0].codeset);
1743d82c7103Splunky else
1744d82c7103Splunky printf("%s", string_vis(str, len));
1745d82c7103Splunky
1746d82c7103Splunky printf("\n");
1747d82c7103Splunky }
1748d82c7103Splunky
1749d82c7103Splunky if (feature.next != feature.end)
1750d82c7103Splunky printf(" [additional data in feature]\n");
1751d82c7103Splunky }
1752d82c7103Splunky
1753d82c7103Splunky if (seq.next != seq.end)
1754d82c7103Splunky printf(" [additional data]\n");
1755d82c7103Splunky }
1756d82c7103Splunky
1757d82c7103Splunky static void
print_hdp_specification(sdp_data_t * data)1758d82c7103Splunky print_hdp_specification(sdp_data_t *data)
1759d82c7103Splunky {
1760d82c7103Splunky uint8_t v;
1761d82c7103Splunky
1762d82c7103Splunky if (!sdp_get_uint8(data, &v))
1763d82c7103Splunky return;
1764d82c7103Splunky
1765d82c7103Splunky switch(v) {
1766d82c7103Splunky case 0x01: printf("ISO/IEEE 11073-20601\n"); break;
1767d82c7103Splunky default: printf("0x%02x\n", v); break;
1768d82c7103Splunky }
1769d82c7103Splunky }
1770d82c7103Splunky
1771d82c7103Splunky static void
print_mcap_procedures(sdp_data_t * data)1772d82c7103Splunky print_mcap_procedures(sdp_data_t *data)
1773d82c7103Splunky {
1774d82c7103Splunky uint8_t v;
1775d82c7103Splunky
1776d82c7103Splunky if (!sdp_get_uint8(data, &v))
1777d82c7103Splunky return;
1778d82c7103Splunky
1779d82c7103Splunky if (Nflag)
1780d82c7103Splunky printf("(0x%02x)", v);
1781d82c7103Splunky
1782d82c7103Splunky printf("\n");
1783d82c7103Splunky if (v & (1<<1)) printf(" Reconnect Initiation\n");
1784d82c7103Splunky if (v & (1<<2)) printf(" Reconnect Acceptance\n");
1785d82c7103Splunky if (v & (1<<3)) printf(" Clock Synchronization Protocol\n");
1786d82c7103Splunky if (v & (1<<4)) printf(" Sync-Master Role\n");
178746834460Splunky }
178846834460Splunky
178946834460Splunky static void
print_character_repertoires(sdp_data_t * data)1790c7407d62Splunky print_character_repertoires(sdp_data_t *data)
1791c7407d62Splunky {
1792a8cbf485Splunky uintmax_t v;
1793c7407d62Splunky
1794c7407d62Splunky /*
1795a8cbf485Splunky * we have no uint128 type so use uintmax as only
1796a8cbf485Splunky * only 17-bits are currently defined, and if the
1797a8cbf485Splunky * value is out of bounds it will be printed anyway
1798c7407d62Splunky */
1799a8cbf485Splunky if (sdp_data_type(data) != SDP_DATA_UINT128
1800a8cbf485Splunky || !sdp_get_uint(data, &v))
1801c7407d62Splunky return;
1802c7407d62Splunky
1803c7407d62Splunky if (Nflag)
1804a8cbf485Splunky printf("(0x%016jx)", v);
1805c7407d62Splunky
1806c7407d62Splunky printf("\n");
1807a8cbf485Splunky if (v & (1<< 0)) printf(" ISO-8859-1\n");
1808a8cbf485Splunky if (v & (1<< 1)) printf(" ISO-8859-2\n");
1809a8cbf485Splunky if (v & (1<< 2)) printf(" ISO-8859-3\n");
1810a8cbf485Splunky if (v & (1<< 3)) printf(" ISO-8859-4\n");
1811a8cbf485Splunky if (v & (1<< 4)) printf(" ISO-8859-5\n");
1812a8cbf485Splunky if (v & (1<< 5)) printf(" ISO-8859-6\n");
1813a8cbf485Splunky if (v & (1<< 6)) printf(" ISO-8859-7\n");
1814a8cbf485Splunky if (v & (1<< 7)) printf(" ISO-8859-8\n");
1815a8cbf485Splunky if (v & (1<< 8)) printf(" ISO-8859-9\n");
1816a8cbf485Splunky if (v & (1<< 9)) printf(" ISO-8859-10\n");
1817a8cbf485Splunky if (v & (1<<10)) printf(" ISO-8859-13\n");
1818a8cbf485Splunky if (v & (1<<11)) printf(" ISO-8859-14\n");
1819a8cbf485Splunky if (v & (1<<12)) printf(" ISO-8859-15\n");
1820a8cbf485Splunky if (v & (1<<13)) printf(" GB18030\n");
1821a8cbf485Splunky if (v & (1<<14)) printf(" JIS X0208-1990, JIS X0201-1976\n");
1822a8cbf485Splunky if (v & (1<<15)) printf(" KSC 5601-1992\n");
1823a8cbf485Splunky if (v & (1<<16)) printf(" Big5\n");
1824a8cbf485Splunky if (v & (1<<17)) printf(" TIS-620\n");
1825c7407d62Splunky }
1826c7407d62Splunky
1827c7407d62Splunky static void
print_bip_capabilities(sdp_data_t * data)182812d25979Splunky print_bip_capabilities(sdp_data_t *data)
182912d25979Splunky {
183012d25979Splunky uint8_t v;
183112d25979Splunky
183212d25979Splunky if (!sdp_get_uint8(data, &v))
183312d25979Splunky return;
183412d25979Splunky
183512d25979Splunky if (Nflag)
183612d25979Splunky printf("(0x%02x)", v);
183712d25979Splunky
183812d25979Splunky printf("\n");
183912d25979Splunky if (v & (1<< 0)) printf(" Generic imaging\n");
184012d25979Splunky if (v & (1<< 1)) printf(" Capturing\n");
184112d25979Splunky if (v & (1<< 2)) printf(" Printing\n");
184212d25979Splunky if (v & (1<< 3)) printf(" Displaying\n");
184312d25979Splunky }
184412d25979Splunky
184512d25979Splunky static void
print_bip_features(sdp_data_t * data)184612d25979Splunky print_bip_features(sdp_data_t *data)
184712d25979Splunky {
184812d25979Splunky uint16_t v;
184912d25979Splunky
185012d25979Splunky if (!sdp_get_uint16(data, &v))
185112d25979Splunky return;
185212d25979Splunky
185312d25979Splunky if (Nflag)
185412d25979Splunky printf("(0x%04x)", v);
185512d25979Splunky
185612d25979Splunky printf("\n");
185712d25979Splunky if (v & (1<<0)) printf(" ImagePush\n");
185812d25979Splunky if (v & (1<<1)) printf(" ImagePush-Store\n");
185912d25979Splunky if (v & (1<<2)) printf(" ImagePush-Print\n");
186012d25979Splunky if (v & (1<<3)) printf(" ImagePush-Display\n");
186112d25979Splunky if (v & (1<<4)) printf(" ImagePull\n");
186212d25979Splunky if (v & (1<<5)) printf(" AdvancedImagePrinting\n");
186312d25979Splunky if (v & (1<<6)) printf(" AutomaticArchive\n");
186412d25979Splunky if (v & (1<<7)) printf(" RemoteCamera\n");
186512d25979Splunky if (v & (1<<8)) printf(" RemoteDisplay\n");
186612d25979Splunky }
186712d25979Splunky
186812d25979Splunky static void
print_bip_functions(sdp_data_t * data)186912d25979Splunky print_bip_functions(sdp_data_t *data)
187012d25979Splunky {
187112d25979Splunky uint32_t v;
187212d25979Splunky
187312d25979Splunky if (!sdp_get_uint32(data, &v))
187412d25979Splunky return;
187512d25979Splunky
187612d25979Splunky if (Nflag)
187712d25979Splunky printf("(0x%08x)", v);
187812d25979Splunky
187912d25979Splunky printf("\n");
188012d25979Splunky if (v & (1<< 0)) printf(" GetCapabilities\n");
188112d25979Splunky if (v & (1<< 1)) printf(" PutImage\n");
188212d25979Splunky if (v & (1<< 2)) printf(" PutLinkedAttachment\n");
188312d25979Splunky if (v & (1<< 3)) printf(" PutLinkedThumbnail\n");
188412d25979Splunky if (v & (1<< 4)) printf(" RemoteDisplay\n");
188512d25979Splunky if (v & (1<< 5)) printf(" GetImagesList\n");
188612d25979Splunky if (v & (1<< 6)) printf(" GetImageProperties\n");
188712d25979Splunky if (v & (1<< 7)) printf(" GetImage\n");
188812d25979Splunky if (v & (1<< 8)) printf(" GetLinkedThumbnail\n");
188912d25979Splunky if (v & (1<< 9)) printf(" GetLinkedAttachment\n");
189012d25979Splunky if (v & (1<<10)) printf(" DeleteImage\n");
189112d25979Splunky if (v & (1<<11)) printf(" StartPrint\n");
189212d25979Splunky if (v & (1<<12)) printf(" GetPartialImage\n");
189312d25979Splunky if (v & (1<<13)) printf(" StartArchive\n");
189412d25979Splunky if (v & (1<<14)) printf(" GetMonitoringImage\n");
189512d25979Splunky if (v & (1<<16)) printf(" GetStatus\n");
189612d25979Splunky }
189712d25979Splunky
189812d25979Splunky static void
print_bip_capacity(sdp_data_t * data)189912d25979Splunky print_bip_capacity(sdp_data_t *data)
190012d25979Splunky {
190112d25979Splunky char buf[9];
190212d25979Splunky uint64_t v;
190312d25979Splunky
190412d25979Splunky if (!sdp_get_uint64(data, &v))
190512d25979Splunky return;
190612d25979Splunky
190712d25979Splunky if (v > INT64_MAX) {
190812d25979Splunky printf("more than ");
190912d25979Splunky v = INT64_MAX;
191012d25979Splunky }
191112d25979Splunky
191212d25979Splunky (void)humanize_number(buf, sizeof(buf), (int64_t)v,
191312d25979Splunky "bytes", HN_AUTOSCALE, HN_NOSPACE);
191412d25979Splunky
191512d25979Splunky printf("%s\n", buf);
191612d25979Splunky }
191712d25979Splunky
191812d25979Splunky static void
print_1284id(sdp_data_t * data)1919f88159b8Splunky print_1284id(sdp_data_t *data)
1920f88159b8Splunky {
1921f88159b8Splunky char *str, *ep;
1922f88159b8Splunky size_t len, l;
1923f88159b8Splunky
1924f88159b8Splunky if (!sdp_get_str(data, &str, &len))
1925f88159b8Splunky return;
1926f88159b8Splunky
1927f88159b8Splunky if (len < 2 || len != be16dec(str)) {
1928f88159b8Splunky printf("[invalid IEEE 1284 Device ID]\n");
1929f88159b8Splunky return;
1930f88159b8Splunky }
1931f88159b8Splunky
1932f88159b8Splunky str += 2;
1933f88159b8Splunky len -= 2;
1934f88159b8Splunky
1935f88159b8Splunky printf("\n");
1936f88159b8Splunky while (len > 0) {
1937f88159b8Splunky ep = memchr(str, (int)';', len);
1938f88159b8Splunky if (ep == NULL) {
1939f88159b8Splunky printf("[invalid IEEE 1284 Device ID]\n");
1940f88159b8Splunky return;
1941f88159b8Splunky }
1942f88159b8Splunky
1943f88159b8Splunky l = (size_t)(ep - str + 1);
19441803dc4bSplunky printf(" %s\n", string_vis(str, l));
1945f88159b8Splunky str += l;
1946f88159b8Splunky len -= l;
1947f88159b8Splunky }
1948f88159b8Splunky }
1949f88159b8Splunky
1950f88159b8Splunky static void
print_ctn_features(sdp_data_t * data)1951d82c7103Splunky print_ctn_features(sdp_data_t *data)
1952d82c7103Splunky {
1953d82c7103Splunky uint32_t v;
1954d82c7103Splunky
1955d82c7103Splunky if (!sdp_get_uint32(data, &v))
1956d82c7103Splunky return;
1957d82c7103Splunky
1958d82c7103Splunky if (Nflag)
1959d82c7103Splunky printf("(0x%08x)", v);
1960d82c7103Splunky
1961d82c7103Splunky printf("\n");
1962d82c7103Splunky if (v & (1<<0)) printf(" Account Management\n");
1963d82c7103Splunky if (v & (1<<1)) printf(" Notification\n");
1964d82c7103Splunky if (v & (1<<2)) printf(" Browsing\n");
1965d82c7103Splunky if (v & (1<<3)) printf(" Downloading\n");
1966d82c7103Splunky if (v & (1<<4)) printf(" Uploading\n");
1967d82c7103Splunky if (v & (1<<5)) printf(" Delete\n");
1968d82c7103Splunky if (v & (1<<6)) printf(" Forward\n");
1969d82c7103Splunky }
1970d82c7103Splunky
1971d82c7103Splunky static void
print_rfcomm(sdp_data_t * data)1972384153c1Splunky print_rfcomm(sdp_data_t *data)
1973384153c1Splunky {
1974384153c1Splunky uint8_t v;
1975384153c1Splunky
1976384153c1Splunky if (sdp_get_uint8(data, &v))
1977384153c1Splunky printf(" (channel %d)", v);
1978384153c1Splunky }
1979384153c1Splunky
1980384153c1Splunky static void
print_att(sdp_data_t * data)1981d82c7103Splunky print_att(sdp_data_t *data)
1982d82c7103Splunky {
1983d82c7103Splunky uint16_t s, e;
1984d82c7103Splunky
1985d82c7103Splunky if (sdp_get_uint16(data, &s) && sdp_get_uint16(data, &e))
1986d82c7103Splunky printf(" (0x%04x .. 0x%04x)", s, e);
1987d82c7103Splunky }
1988d82c7103Splunky
1989d82c7103Splunky static void
print_bnep(sdp_data_t * data)1990384153c1Splunky print_bnep(sdp_data_t *data)
1991384153c1Splunky {
1992384153c1Splunky sdp_data_t seq;
1993384153c1Splunky uint16_t v;
1994384153c1Splunky const char *sep;
1995384153c1Splunky
1996384153c1Splunky if (!sdp_get_uint16(data, &v)
1997384153c1Splunky || !sdp_get_seq(data, &seq))
1998384153c1Splunky return;
1999384153c1Splunky
2000384153c1Splunky printf(" (v%d.%d", (v >> 8), (v & 0xff));
2001384153c1Splunky sep = "; ";
2002384153c1Splunky while (sdp_get_uint16(&seq, &v)) {
20039f52716dSjoerg printf("%s", sep);
2004384153c1Splunky sep = ", ";
2005384153c1Splunky
2006384153c1Splunky switch (v) {
2007384153c1Splunky case 0x0800: printf("IPv4"); break;
2008384153c1Splunky case 0x0806: printf("ARP"); break;
200960e7a7b1Splunky case 0x8100: printf("802.1Q"); break;
2010384153c1Splunky case 0x86dd: printf("IPv6"); break;
2011384153c1Splunky default: printf("0x%04x", v); break;
2012384153c1Splunky }
2013384153c1Splunky }
2014384153c1Splunky printf(")");
2015384153c1Splunky
2016384153c1Splunky if (seq.next != seq.end)
2017384153c1Splunky printf(" [additional data]");
2018384153c1Splunky }
2019384153c1Splunky
2020384153c1Splunky static void
print_avctp(sdp_data_t * data)2021384153c1Splunky print_avctp(sdp_data_t *data)
2022384153c1Splunky {
2023384153c1Splunky uint16_t v;
2024384153c1Splunky
2025384153c1Splunky if (sdp_get_uint16(data, &v))
2026384153c1Splunky printf(" (v%d.%d)", (v >> 8), (v & 0xff));
2027384153c1Splunky }
2028384153c1Splunky
2029384153c1Splunky static void
print_avdtp(sdp_data_t * data)2030384153c1Splunky print_avdtp(sdp_data_t *data)
2031384153c1Splunky {
2032384153c1Splunky uint16_t v;
2033384153c1Splunky
2034384153c1Splunky if (sdp_get_uint16(data, &v))
2035384153c1Splunky printf(" (v%d.%d)", (v >> 8), (v & 0xff));
2036384153c1Splunky }
2037384153c1Splunky
2038384153c1Splunky static void
print_l2cap(sdp_data_t * data)2039384153c1Splunky print_l2cap(sdp_data_t *data)
2040384153c1Splunky {
2041384153c1Splunky uint16_t v;
2042384153c1Splunky
2043384153c1Splunky if (sdp_get_uint16(data, &v))
2044384153c1Splunky printf(" (PSM 0x%04x)", v);
2045384153c1Splunky }
2046