11de7b4b8SPedro F. Giffuni /*- 20986ab12SMaksim Yevmenkin * search.c 30986ab12SMaksim Yevmenkin * 44d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 51de7b4b8SPedro F. Giffuni * 60986ab12SMaksim Yevmenkin * Copyright (c) 2001-2003 Maksim Yevmenkin <m_evmenkin@yahoo.com> 70986ab12SMaksim Yevmenkin * All rights reserved. 80986ab12SMaksim Yevmenkin * 90986ab12SMaksim Yevmenkin * Redistribution and use in source and binary forms, with or without 100986ab12SMaksim Yevmenkin * modification, are permitted provided that the following conditions 110986ab12SMaksim Yevmenkin * are met: 120986ab12SMaksim Yevmenkin * 1. Redistributions of source code must retain the above copyright 130986ab12SMaksim Yevmenkin * notice, this list of conditions and the following disclaimer. 140986ab12SMaksim Yevmenkin * 2. Redistributions in binary form must reproduce the above copyright 150986ab12SMaksim Yevmenkin * notice, this list of conditions and the following disclaimer in the 160986ab12SMaksim Yevmenkin * documentation and/or other materials provided with the distribution. 170986ab12SMaksim Yevmenkin * 180986ab12SMaksim Yevmenkin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 190986ab12SMaksim Yevmenkin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 200986ab12SMaksim Yevmenkin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 210986ab12SMaksim Yevmenkin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 220986ab12SMaksim Yevmenkin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 230986ab12SMaksim Yevmenkin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 240986ab12SMaksim Yevmenkin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 250986ab12SMaksim Yevmenkin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 260986ab12SMaksim Yevmenkin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 270986ab12SMaksim Yevmenkin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 280986ab12SMaksim Yevmenkin * SUCH DAMAGE. 290986ab12SMaksim Yevmenkin * 300986ab12SMaksim Yevmenkin * $Id: search.c,v 1.2 2003/09/08 17:35:15 max Exp $ 310986ab12SMaksim Yevmenkin */ 320986ab12SMaksim Yevmenkin 33*fdbf7cabSElyes Haouas #include <sys/param.h> 3443d33de9SMaksim Yevmenkin #include <netinet/in.h> 358d6f425dSTakanori Watanabe #define L2CAP_SOCKET_CHECKED 360986ab12SMaksim Yevmenkin #include <bluetooth.h> 370986ab12SMaksim Yevmenkin #include <ctype.h> 380986ab12SMaksim Yevmenkin #include <sdp.h> 390986ab12SMaksim Yevmenkin #include <stdio.h> 400986ab12SMaksim Yevmenkin #include <stdlib.h> 410986ab12SMaksim Yevmenkin #include "sdpcontrol.h" 420986ab12SMaksim Yevmenkin 430986ab12SMaksim Yevmenkin /* List of the attributes we are looking for */ 44a4b187faSMaksim Yevmenkin static uint32_t attrs[] = 450986ab12SMaksim Yevmenkin { 460986ab12SMaksim Yevmenkin SDP_ATTR_RANGE( SDP_ATTR_SERVICE_RECORD_HANDLE, 470986ab12SMaksim Yevmenkin SDP_ATTR_SERVICE_RECORD_HANDLE), 480986ab12SMaksim Yevmenkin SDP_ATTR_RANGE( SDP_ATTR_SERVICE_CLASS_ID_LIST, 490986ab12SMaksim Yevmenkin SDP_ATTR_SERVICE_CLASS_ID_LIST), 500986ab12SMaksim Yevmenkin SDP_ATTR_RANGE( SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST, 510986ab12SMaksim Yevmenkin SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST), 520986ab12SMaksim Yevmenkin SDP_ATTR_RANGE( SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST, 530986ab12SMaksim Yevmenkin SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST) 540986ab12SMaksim Yevmenkin }; 55*fdbf7cabSElyes Haouas #define attrs_len nitems(attrs) 560986ab12SMaksim Yevmenkin 570986ab12SMaksim Yevmenkin /* Buffer for the attributes */ 580986ab12SMaksim Yevmenkin #define NRECS 25 /* request this much records from the SDP server */ 590986ab12SMaksim Yevmenkin #define BSIZE 256 /* one attribute buffer size */ 60a4b187faSMaksim Yevmenkin static uint8_t buffer[NRECS * attrs_len][BSIZE]; 610986ab12SMaksim Yevmenkin 620986ab12SMaksim Yevmenkin /* SDP attributes */ 630986ab12SMaksim Yevmenkin static sdp_attr_t values[NRECS * attrs_len]; 64*fdbf7cabSElyes Haouas #define values_len nitems(values) 650986ab12SMaksim Yevmenkin 660986ab12SMaksim Yevmenkin /* 670986ab12SMaksim Yevmenkin * Print Service Class ID List 680986ab12SMaksim Yevmenkin * 690986ab12SMaksim Yevmenkin * The ServiceClassIDList attribute consists of a data element sequence in 700986ab12SMaksim Yevmenkin * which each data element is a UUID representing the service classes that 710986ab12SMaksim Yevmenkin * a given service record conforms to. The UUIDs are listed in order from 720986ab12SMaksim Yevmenkin * the most specific class to the most general class. The ServiceClassIDList 730986ab12SMaksim Yevmenkin * must contain at least one service class UUID. 740986ab12SMaksim Yevmenkin */ 750986ab12SMaksim Yevmenkin 760986ab12SMaksim Yevmenkin static void 77a4b187faSMaksim Yevmenkin print_service_class_id_list(uint8_t const *start, uint8_t const *end) 780986ab12SMaksim Yevmenkin { 79a4b187faSMaksim Yevmenkin uint32_t type, len, value; 800986ab12SMaksim Yevmenkin 810986ab12SMaksim Yevmenkin if (end - start < 2) { 820986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Service Class ID List. " \ 834ae439a3SMaksim Yevmenkin "Too short, len=%zd\n", end - start); 840986ab12SMaksim Yevmenkin return; 850986ab12SMaksim Yevmenkin } 860986ab12SMaksim Yevmenkin 870986ab12SMaksim Yevmenkin SDP_GET8(type, start); 880986ab12SMaksim Yevmenkin switch (type) { 890986ab12SMaksim Yevmenkin case SDP_DATA_SEQ8: 900986ab12SMaksim Yevmenkin SDP_GET8(len, start); 910986ab12SMaksim Yevmenkin break; 920986ab12SMaksim Yevmenkin 930986ab12SMaksim Yevmenkin case SDP_DATA_SEQ16: 940986ab12SMaksim Yevmenkin SDP_GET16(len, start); 950986ab12SMaksim Yevmenkin break; 960986ab12SMaksim Yevmenkin 970986ab12SMaksim Yevmenkin case SDP_DATA_SEQ32: 980986ab12SMaksim Yevmenkin SDP_GET32(len, start); 990986ab12SMaksim Yevmenkin break; 1000986ab12SMaksim Yevmenkin 1010986ab12SMaksim Yevmenkin default: 1020986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Service Class ID List. " \ 1030986ab12SMaksim Yevmenkin "Not a sequence, type=%#x\n", type); 1040986ab12SMaksim Yevmenkin return; 1050986ab12SMaksim Yevmenkin /* NOT REACHED */ 1060986ab12SMaksim Yevmenkin } 1070986ab12SMaksim Yevmenkin 108f32d9c4bSMaksim Yevmenkin if (len > (end - start)) { 109f32d9c4bSMaksim Yevmenkin fprintf(stderr, "Invalid Service Class ID List. " \ 110f32d9c4bSMaksim Yevmenkin "Too long len=%d\n", len); 111f32d9c4bSMaksim Yevmenkin return; 112f32d9c4bSMaksim Yevmenkin } 113f32d9c4bSMaksim Yevmenkin 1140986ab12SMaksim Yevmenkin while (start < end) { 1150986ab12SMaksim Yevmenkin SDP_GET8(type, start); 1160986ab12SMaksim Yevmenkin switch (type) { 1170986ab12SMaksim Yevmenkin case SDP_DATA_UUID16: 1180986ab12SMaksim Yevmenkin SDP_GET16(value, start); 1190986ab12SMaksim Yevmenkin fprintf(stdout, "\t%s (%#4.4x)\n", 1200986ab12SMaksim Yevmenkin sdp_uuid2desc(value), value); 1210986ab12SMaksim Yevmenkin break; 1220986ab12SMaksim Yevmenkin 1230986ab12SMaksim Yevmenkin case SDP_DATA_UUID32: 1240986ab12SMaksim Yevmenkin SDP_GET32(value, start); 1250986ab12SMaksim Yevmenkin fprintf(stdout, "\t%#8.8x\n", value); 1260986ab12SMaksim Yevmenkin break; 1270986ab12SMaksim Yevmenkin 1280986ab12SMaksim Yevmenkin case SDP_DATA_UUID128: { 1290986ab12SMaksim Yevmenkin int128_t uuid; 1300986ab12SMaksim Yevmenkin 13143d33de9SMaksim Yevmenkin SDP_GET_UUID128(&uuid, start); 1320986ab12SMaksim Yevmenkin fprintf(stdout, "\t%#8.8x-%4.4x-%4.4x-%4.4x-%4.4x%8.8x\n", 13343d33de9SMaksim Yevmenkin ntohl(*(uint32_t *)&uuid.b[0]), 13443d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&uuid.b[4]), 13543d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&uuid.b[6]), 13643d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&uuid.b[8]), 13743d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&uuid.b[10]), 13843d33de9SMaksim Yevmenkin ntohl(*(uint32_t *)&uuid.b[12])); 1390986ab12SMaksim Yevmenkin } break; 1400986ab12SMaksim Yevmenkin 1410986ab12SMaksim Yevmenkin default: 1420986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Service Class ID List. " \ 1430986ab12SMaksim Yevmenkin "Not a UUID, type=%#x\n", type); 1440986ab12SMaksim Yevmenkin return; 1450986ab12SMaksim Yevmenkin /* NOT REACHED */ 1460986ab12SMaksim Yevmenkin } 1470986ab12SMaksim Yevmenkin } 1480986ab12SMaksim Yevmenkin } /* print_service_class_id_list */ 1490986ab12SMaksim Yevmenkin 1500986ab12SMaksim Yevmenkin /* 1510986ab12SMaksim Yevmenkin * Print Protocol Descriptor List 1520986ab12SMaksim Yevmenkin * 1530986ab12SMaksim Yevmenkin * If the ProtocolDescriptorList describes a single stack, it takes the form 1540986ab12SMaksim Yevmenkin * of a data element sequence in which each element of the sequence is a 1550986ab12SMaksim Yevmenkin * protocol descriptor. Each protocol descriptor is, in turn, a data element 1560986ab12SMaksim Yevmenkin * sequence whose first element is a UUID identifying the protocol and whose 1570986ab12SMaksim Yevmenkin * successive elements are protocol-specific parameters. The protocol 1580986ab12SMaksim Yevmenkin * descriptors are listed in order from the lowest layer protocol to the 1590986ab12SMaksim Yevmenkin * highest layer protocol used to gain access to the service. If it is possible 1600986ab12SMaksim Yevmenkin * for more than one kind of protocol stack to be used to gain access to the 1610986ab12SMaksim Yevmenkin * service, the ProtocolDescriptorList takes the form of a data element 1620986ab12SMaksim Yevmenkin * alternative where each member is a data element sequence as described above. 1630986ab12SMaksim Yevmenkin */ 1640986ab12SMaksim Yevmenkin 1650986ab12SMaksim Yevmenkin static void 166a4b187faSMaksim Yevmenkin print_protocol_descriptor(uint8_t const *start, uint8_t const *end) 1670986ab12SMaksim Yevmenkin { 1680986ab12SMaksim Yevmenkin union { 1690986ab12SMaksim Yevmenkin uint8_t uint8; 1700986ab12SMaksim Yevmenkin uint16_t uint16; 1710986ab12SMaksim Yevmenkin uint32_t uint32; 1720986ab12SMaksim Yevmenkin uint64_t uint64; 1730986ab12SMaksim Yevmenkin int128_t int128; 1740986ab12SMaksim Yevmenkin } value; 175a4b187faSMaksim Yevmenkin uint32_t type, len, param; 1760986ab12SMaksim Yevmenkin 1770986ab12SMaksim Yevmenkin /* Get Protocol UUID */ 1780986ab12SMaksim Yevmenkin SDP_GET8(type, start); 1790986ab12SMaksim Yevmenkin switch (type) { 1800986ab12SMaksim Yevmenkin case SDP_DATA_UUID16: 1810986ab12SMaksim Yevmenkin SDP_GET16(value.uint16, start); 1820986ab12SMaksim Yevmenkin fprintf(stdout, "\t%s (%#4.4x)\n", sdp_uuid2desc(value.uint16), 1830986ab12SMaksim Yevmenkin value.uint16); 1840986ab12SMaksim Yevmenkin break; 1850986ab12SMaksim Yevmenkin 1860986ab12SMaksim Yevmenkin case SDP_DATA_UUID32: 1870986ab12SMaksim Yevmenkin SDP_GET32(value.uint32, start); 1880986ab12SMaksim Yevmenkin fprintf(stdout, "\t%#8.8x\n", value.uint32); 1890986ab12SMaksim Yevmenkin break; 1900986ab12SMaksim Yevmenkin 1910986ab12SMaksim Yevmenkin case SDP_DATA_UUID128: 19243d33de9SMaksim Yevmenkin SDP_GET_UUID128(&value.int128, start); 1930986ab12SMaksim Yevmenkin fprintf(stdout, "\t%#8.8x-%4.4x-%4.4x-%4.4x-%4.4x%8.8x\n", 19443d33de9SMaksim Yevmenkin ntohl(*(uint32_t *)&value.int128.b[0]), 19543d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&value.int128.b[4]), 19643d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&value.int128.b[6]), 19743d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&value.int128.b[8]), 19843d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&value.int128.b[10]), 19943d33de9SMaksim Yevmenkin ntohl(*(uint32_t *)&value.int128.b[12])); 2000986ab12SMaksim Yevmenkin break; 2010986ab12SMaksim Yevmenkin 2020986ab12SMaksim Yevmenkin default: 2030986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Protocol Descriptor. " \ 2040986ab12SMaksim Yevmenkin "Not a UUID, type=%#x\n", type); 2050986ab12SMaksim Yevmenkin return; 2060986ab12SMaksim Yevmenkin /* NOT REACHED */ 2070986ab12SMaksim Yevmenkin } 2080986ab12SMaksim Yevmenkin 2090986ab12SMaksim Yevmenkin /* Protocol specific parameters */ 2100986ab12SMaksim Yevmenkin for (param = 1; start < end; param ++) { 2110986ab12SMaksim Yevmenkin fprintf(stdout, "\t\tProtocol specific parameter #%d: ", param); 2120986ab12SMaksim Yevmenkin 2130986ab12SMaksim Yevmenkin SDP_GET8(type, start); 2140986ab12SMaksim Yevmenkin switch (type) { 2150986ab12SMaksim Yevmenkin case SDP_DATA_NIL: 2160986ab12SMaksim Yevmenkin fprintf(stdout, "nil\n"); 2170986ab12SMaksim Yevmenkin break; 2180986ab12SMaksim Yevmenkin 2190986ab12SMaksim Yevmenkin case SDP_DATA_UINT8: 2200986ab12SMaksim Yevmenkin case SDP_DATA_INT8: 2210986ab12SMaksim Yevmenkin case SDP_DATA_BOOL: 2220986ab12SMaksim Yevmenkin SDP_GET8(value.uint8, start); 2230986ab12SMaksim Yevmenkin fprintf(stdout, "u/int8/bool %u\n", value.uint8); 2240986ab12SMaksim Yevmenkin break; 2250986ab12SMaksim Yevmenkin 2260986ab12SMaksim Yevmenkin case SDP_DATA_UINT16: 2270986ab12SMaksim Yevmenkin case SDP_DATA_INT16: 2280986ab12SMaksim Yevmenkin case SDP_DATA_UUID16: 2290986ab12SMaksim Yevmenkin SDP_GET16(value.uint16, start); 2300986ab12SMaksim Yevmenkin fprintf(stdout, "u/int/uuid16 %u\n", value.uint16); 2310986ab12SMaksim Yevmenkin break; 2320986ab12SMaksim Yevmenkin 2330986ab12SMaksim Yevmenkin case SDP_DATA_UINT32: 2340986ab12SMaksim Yevmenkin case SDP_DATA_INT32: 2350986ab12SMaksim Yevmenkin case SDP_DATA_UUID32: 2360986ab12SMaksim Yevmenkin SDP_GET32(value.uint32, start); 2370986ab12SMaksim Yevmenkin fprintf(stdout, "u/int/uuid32 %u\n", value.uint32); 2380986ab12SMaksim Yevmenkin break; 2390986ab12SMaksim Yevmenkin 2400986ab12SMaksim Yevmenkin case SDP_DATA_UINT64: 2410986ab12SMaksim Yevmenkin case SDP_DATA_INT64: 2420986ab12SMaksim Yevmenkin SDP_GET64(value.uint64, start); 2434ae439a3SMaksim Yevmenkin fprintf(stdout, "u/int64 %ju\n", value.uint64); 2440986ab12SMaksim Yevmenkin break; 2450986ab12SMaksim Yevmenkin 2460986ab12SMaksim Yevmenkin case SDP_DATA_UINT128: 2470986ab12SMaksim Yevmenkin case SDP_DATA_INT128: 2480986ab12SMaksim Yevmenkin SDP_GET128(&value.int128, start); 24943d33de9SMaksim Yevmenkin fprintf(stdout, "u/int128 %#8.8x%8.8x%8.8x%8.8x\n", 250a4b187faSMaksim Yevmenkin *(uint32_t *)&value.int128.b[0], 25143d33de9SMaksim Yevmenkin *(uint32_t *)&value.int128.b[4], 25243d33de9SMaksim Yevmenkin *(uint32_t *)&value.int128.b[8], 253a4b187faSMaksim Yevmenkin *(uint32_t *)&value.int128.b[12]); 2540986ab12SMaksim Yevmenkin break; 2550986ab12SMaksim Yevmenkin 25643d33de9SMaksim Yevmenkin case SDP_DATA_UUID128: 25743d33de9SMaksim Yevmenkin SDP_GET_UUID128(&value.int128, start); 25843d33de9SMaksim Yevmenkin fprintf(stdout, "uuid128 %#8.8x-%4.4x-%4.4x-%4.4x-%4.4x%8.8x\n", 25943d33de9SMaksim Yevmenkin ntohl(*(uint32_t *)&value.int128.b[0]), 26043d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&value.int128.b[4]), 26143d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&value.int128.b[6]), 26243d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&value.int128.b[8]), 26343d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&value.int128.b[10]), 26443d33de9SMaksim Yevmenkin ntohl(*(uint32_t *)&value.int128.b[12])); 26543d33de9SMaksim Yevmenkin break; 26643d33de9SMaksim Yevmenkin 2670986ab12SMaksim Yevmenkin case SDP_DATA_STR8: 2680986ab12SMaksim Yevmenkin case SDP_DATA_URL8: 2690986ab12SMaksim Yevmenkin SDP_GET8(len, start); 270f32d9c4bSMaksim Yevmenkin for (; start < end && len > 0; start ++, len --) 271f32d9c4bSMaksim Yevmenkin fprintf(stdout, "%c", *start); 272f32d9c4bSMaksim Yevmenkin fprintf(stdout, "\n"); 2730986ab12SMaksim Yevmenkin break; 2740986ab12SMaksim Yevmenkin 2750986ab12SMaksim Yevmenkin case SDP_DATA_STR16: 2760986ab12SMaksim Yevmenkin case SDP_DATA_URL16: 2770986ab12SMaksim Yevmenkin SDP_GET16(len, start); 278f32d9c4bSMaksim Yevmenkin for (; start < end && len > 0; start ++, len --) 279f32d9c4bSMaksim Yevmenkin fprintf(stdout, "%c", *start); 280f32d9c4bSMaksim Yevmenkin fprintf(stdout, "\n"); 2810986ab12SMaksim Yevmenkin break; 2820986ab12SMaksim Yevmenkin 2830986ab12SMaksim Yevmenkin case SDP_DATA_STR32: 2840986ab12SMaksim Yevmenkin case SDP_DATA_URL32: 2850986ab12SMaksim Yevmenkin SDP_GET32(len, start); 286f32d9c4bSMaksim Yevmenkin for (; start < end && len > 0; start ++, len --) 287f32d9c4bSMaksim Yevmenkin fprintf(stdout, "%c", *start); 288f32d9c4bSMaksim Yevmenkin fprintf(stdout, "\n"); 2890986ab12SMaksim Yevmenkin break; 2900986ab12SMaksim Yevmenkin 2910986ab12SMaksim Yevmenkin case SDP_DATA_SEQ8: 2920986ab12SMaksim Yevmenkin case SDP_DATA_ALT8: 2930986ab12SMaksim Yevmenkin SDP_GET8(len, start); 294f32d9c4bSMaksim Yevmenkin for (; start < end && len > 0; start ++, len --) 2950986ab12SMaksim Yevmenkin fprintf(stdout, "%#2.2x ", *start); 2960986ab12SMaksim Yevmenkin fprintf(stdout, "\n"); 2970986ab12SMaksim Yevmenkin break; 2980986ab12SMaksim Yevmenkin 2990986ab12SMaksim Yevmenkin case SDP_DATA_SEQ16: 3000986ab12SMaksim Yevmenkin case SDP_DATA_ALT16: 3010986ab12SMaksim Yevmenkin SDP_GET16(len, start); 302f32d9c4bSMaksim Yevmenkin for (; start < end && len > 0; start ++, len --) 3030986ab12SMaksim Yevmenkin fprintf(stdout, "%#2.2x ", *start); 3040986ab12SMaksim Yevmenkin fprintf(stdout, "\n"); 3050986ab12SMaksim Yevmenkin break; 3060986ab12SMaksim Yevmenkin 3070986ab12SMaksim Yevmenkin case SDP_DATA_SEQ32: 3080986ab12SMaksim Yevmenkin case SDP_DATA_ALT32: 3090986ab12SMaksim Yevmenkin SDP_GET32(len, start); 310f32d9c4bSMaksim Yevmenkin for (; start < end && len > 0; start ++, len --) 3110986ab12SMaksim Yevmenkin fprintf(stdout, "%#2.2x ", *start); 3120986ab12SMaksim Yevmenkin fprintf(stdout, "\n"); 3130986ab12SMaksim Yevmenkin break; 3140986ab12SMaksim Yevmenkin 3150986ab12SMaksim Yevmenkin default: 3160986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Protocol Descriptor. " \ 3170986ab12SMaksim Yevmenkin "Unknown data type: %#02x\n", type); 3180986ab12SMaksim Yevmenkin return; 3190986ab12SMaksim Yevmenkin /* NOT REACHED */ 3200986ab12SMaksim Yevmenkin } 3210986ab12SMaksim Yevmenkin } 3220986ab12SMaksim Yevmenkin } /* print_protocol_descriptor */ 3230986ab12SMaksim Yevmenkin 3240986ab12SMaksim Yevmenkin static void 325a4b187faSMaksim Yevmenkin print_protocol_descriptor_list(uint8_t const *start, uint8_t const *end) 3260986ab12SMaksim Yevmenkin { 327a4b187faSMaksim Yevmenkin uint32_t type, len; 3280986ab12SMaksim Yevmenkin 3290986ab12SMaksim Yevmenkin if (end - start < 2) { 3300986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Protocol Descriptor List. " \ 3314ae439a3SMaksim Yevmenkin "Too short, len=%zd\n", end - start); 3320986ab12SMaksim Yevmenkin return; 3330986ab12SMaksim Yevmenkin } 3340986ab12SMaksim Yevmenkin 3350986ab12SMaksim Yevmenkin SDP_GET8(type, start); 3360986ab12SMaksim Yevmenkin switch (type) { 3370986ab12SMaksim Yevmenkin case SDP_DATA_SEQ8: 3380986ab12SMaksim Yevmenkin SDP_GET8(len, start); 3390986ab12SMaksim Yevmenkin break; 3400986ab12SMaksim Yevmenkin 3410986ab12SMaksim Yevmenkin case SDP_DATA_SEQ16: 3420986ab12SMaksim Yevmenkin SDP_GET16(len, start); 3430986ab12SMaksim Yevmenkin break; 3440986ab12SMaksim Yevmenkin 3450986ab12SMaksim Yevmenkin case SDP_DATA_SEQ32: 3460986ab12SMaksim Yevmenkin SDP_GET32(len, start); 3470986ab12SMaksim Yevmenkin break; 3480986ab12SMaksim Yevmenkin 3490986ab12SMaksim Yevmenkin default: 3500986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Protocol Descriptor List. " \ 3510986ab12SMaksim Yevmenkin "Not a sequence, type=%#x\n", type); 3520986ab12SMaksim Yevmenkin return; 3530986ab12SMaksim Yevmenkin /* NOT REACHED */ 3540986ab12SMaksim Yevmenkin } 3550986ab12SMaksim Yevmenkin 356f32d9c4bSMaksim Yevmenkin if (len > (end - start)) { 357f32d9c4bSMaksim Yevmenkin fprintf(stderr, "Invalid Protocol Descriptor List. " \ 358f32d9c4bSMaksim Yevmenkin "Too long, len=%d\n", len); 359f32d9c4bSMaksim Yevmenkin return; 360f32d9c4bSMaksim Yevmenkin } 361f32d9c4bSMaksim Yevmenkin 3620986ab12SMaksim Yevmenkin while (start < end) { 3630986ab12SMaksim Yevmenkin SDP_GET8(type, start); 3640986ab12SMaksim Yevmenkin switch (type) { 3650986ab12SMaksim Yevmenkin case SDP_DATA_SEQ8: 3660986ab12SMaksim Yevmenkin SDP_GET8(len, start); 3670986ab12SMaksim Yevmenkin break; 3680986ab12SMaksim Yevmenkin 3690986ab12SMaksim Yevmenkin case SDP_DATA_SEQ16: 3700986ab12SMaksim Yevmenkin SDP_GET16(len, start); 3710986ab12SMaksim Yevmenkin break; 3720986ab12SMaksim Yevmenkin 3730986ab12SMaksim Yevmenkin case SDP_DATA_SEQ32: 3740986ab12SMaksim Yevmenkin SDP_GET32(len, start); 3750986ab12SMaksim Yevmenkin break; 3760986ab12SMaksim Yevmenkin 3770986ab12SMaksim Yevmenkin default: 3780986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Protocol Descriptor List. " \ 3790986ab12SMaksim Yevmenkin "Not a sequence, type=%#x\n", type); 3800986ab12SMaksim Yevmenkin return; 3810986ab12SMaksim Yevmenkin /* NOT REACHED */ 3820986ab12SMaksim Yevmenkin } 3830986ab12SMaksim Yevmenkin 384f32d9c4bSMaksim Yevmenkin if (len > (end - start)) { 385f32d9c4bSMaksim Yevmenkin fprintf(stderr, "Invalid Protocol Descriptor List. " \ 386f32d9c4bSMaksim Yevmenkin "Too long, len=%d\n", len); 387f32d9c4bSMaksim Yevmenkin return; 388f32d9c4bSMaksim Yevmenkin } 389f32d9c4bSMaksim Yevmenkin 3900986ab12SMaksim Yevmenkin print_protocol_descriptor(start, start + len); 3910986ab12SMaksim Yevmenkin start += len; 3920986ab12SMaksim Yevmenkin } 3930986ab12SMaksim Yevmenkin } /* print_protocol_descriptor_list */ 3940986ab12SMaksim Yevmenkin 3950986ab12SMaksim Yevmenkin /* 3960986ab12SMaksim Yevmenkin * Print Bluetooth Profile Descriptor List 3970986ab12SMaksim Yevmenkin * 3980986ab12SMaksim Yevmenkin * The BluetoothProfileDescriptorList attribute consists of a data element 3990986ab12SMaksim Yevmenkin * sequence in which each element is a profile descriptor that contains 4000986ab12SMaksim Yevmenkin * information about a Bluetooth profile to which the service represented by 4010986ab12SMaksim Yevmenkin * this service record conforms. Each profile descriptor is a data element 4020986ab12SMaksim Yevmenkin * sequence whose first element is the UUID assigned to the profile and whose 4030986ab12SMaksim Yevmenkin * second element is a 16-bit profile version number. Each version of a profile 4040986ab12SMaksim Yevmenkin * is assigned a 16-bit unsigned integer profile version number, which consists 4050986ab12SMaksim Yevmenkin * of two 8-bit fields. The higher-order 8 bits contain the major version 4060986ab12SMaksim Yevmenkin * number field and the lower-order 8 bits contain the minor version number 4070986ab12SMaksim Yevmenkin * field. 4080986ab12SMaksim Yevmenkin */ 4090986ab12SMaksim Yevmenkin 4100986ab12SMaksim Yevmenkin static void 411a4b187faSMaksim Yevmenkin print_bluetooth_profile_descriptor_list(uint8_t const *start, uint8_t const *end) 4120986ab12SMaksim Yevmenkin { 413a4b187faSMaksim Yevmenkin uint32_t type, len, value; 4140986ab12SMaksim Yevmenkin 4150986ab12SMaksim Yevmenkin if (end - start < 2) { 4160986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Bluetooth Profile Descriptor List. " \ 4174ae439a3SMaksim Yevmenkin "Too short, len=%zd\n", end - start); 4180986ab12SMaksim Yevmenkin return; 4190986ab12SMaksim Yevmenkin } 4200986ab12SMaksim Yevmenkin 4210986ab12SMaksim Yevmenkin SDP_GET8(type, start); 4220986ab12SMaksim Yevmenkin switch (type) { 4230986ab12SMaksim Yevmenkin case SDP_DATA_SEQ8: 4240986ab12SMaksim Yevmenkin SDP_GET8(len, start); 4250986ab12SMaksim Yevmenkin break; 4260986ab12SMaksim Yevmenkin 4270986ab12SMaksim Yevmenkin case SDP_DATA_SEQ16: 4280986ab12SMaksim Yevmenkin SDP_GET16(len, start); 4290986ab12SMaksim Yevmenkin break; 4300986ab12SMaksim Yevmenkin 4310986ab12SMaksim Yevmenkin case SDP_DATA_SEQ32: 4320986ab12SMaksim Yevmenkin SDP_GET32(len, start); 4330986ab12SMaksim Yevmenkin break; 4340986ab12SMaksim Yevmenkin 4350986ab12SMaksim Yevmenkin default: 4360986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Bluetooth Profile Descriptor List. " \ 4370986ab12SMaksim Yevmenkin "Not a sequence, type=%#x\n", type); 4380986ab12SMaksim Yevmenkin return; 4390986ab12SMaksim Yevmenkin /* NOT REACHED */ 4400986ab12SMaksim Yevmenkin } 4410986ab12SMaksim Yevmenkin 442f32d9c4bSMaksim Yevmenkin if (len > (end - start)) { 443f32d9c4bSMaksim Yevmenkin fprintf(stderr, "Invalid Bluetooth Profile Descriptor List. " \ 444f32d9c4bSMaksim Yevmenkin "Too long, len=%d\n", len); 445f32d9c4bSMaksim Yevmenkin return; 446f32d9c4bSMaksim Yevmenkin } 447f32d9c4bSMaksim Yevmenkin 4480986ab12SMaksim Yevmenkin while (start < end) { 4490986ab12SMaksim Yevmenkin SDP_GET8(type, start); 4500986ab12SMaksim Yevmenkin switch (type) { 4510986ab12SMaksim Yevmenkin case SDP_DATA_SEQ8: 4520986ab12SMaksim Yevmenkin SDP_GET8(len, start); 4530986ab12SMaksim Yevmenkin break; 4540986ab12SMaksim Yevmenkin 4550986ab12SMaksim Yevmenkin case SDP_DATA_SEQ16: 4560986ab12SMaksim Yevmenkin SDP_GET16(len, start); 4570986ab12SMaksim Yevmenkin break; 4580986ab12SMaksim Yevmenkin 4590986ab12SMaksim Yevmenkin case SDP_DATA_SEQ32: 4600986ab12SMaksim Yevmenkin SDP_GET32(len, start); 4610986ab12SMaksim Yevmenkin break; 4620986ab12SMaksim Yevmenkin 4630986ab12SMaksim Yevmenkin default: 4640986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Bluetooth Profile " \ 4650986ab12SMaksim Yevmenkin "Descriptor List. " \ 4660986ab12SMaksim Yevmenkin "Not a sequence, type=%#x\n", type); 4670986ab12SMaksim Yevmenkin return; 4680986ab12SMaksim Yevmenkin /* NOT REACHED */ 4690986ab12SMaksim Yevmenkin } 4700986ab12SMaksim Yevmenkin 471f32d9c4bSMaksim Yevmenkin if (len > (end - start)) { 472f32d9c4bSMaksim Yevmenkin fprintf(stderr, "Invalid Bluetooth Profile " \ 473f32d9c4bSMaksim Yevmenkin "Descriptor List. " \ 474f32d9c4bSMaksim Yevmenkin "Too long, len=%d\n", len); 475f32d9c4bSMaksim Yevmenkin return; 476f32d9c4bSMaksim Yevmenkin } 477f32d9c4bSMaksim Yevmenkin 4780986ab12SMaksim Yevmenkin /* Get UUID */ 4790986ab12SMaksim Yevmenkin SDP_GET8(type, start); 4800986ab12SMaksim Yevmenkin switch (type) { 4810986ab12SMaksim Yevmenkin case SDP_DATA_UUID16: 4820986ab12SMaksim Yevmenkin SDP_GET16(value, start); 4830986ab12SMaksim Yevmenkin fprintf(stdout, "\t%s (%#4.4x) ", 4840986ab12SMaksim Yevmenkin sdp_uuid2desc(value), value); 4850986ab12SMaksim Yevmenkin break; 4860986ab12SMaksim Yevmenkin 4870986ab12SMaksim Yevmenkin case SDP_DATA_UUID32: 4880986ab12SMaksim Yevmenkin SDP_GET32(value, start); 4890986ab12SMaksim Yevmenkin fprintf(stdout, "\t%#8.8x ", value); 4900986ab12SMaksim Yevmenkin break; 4910986ab12SMaksim Yevmenkin 4920986ab12SMaksim Yevmenkin case SDP_DATA_UUID128: { 4930986ab12SMaksim Yevmenkin int128_t uuid; 4940986ab12SMaksim Yevmenkin 49543d33de9SMaksim Yevmenkin SDP_GET_UUID128(&uuid, start); 4960986ab12SMaksim Yevmenkin fprintf(stdout, "\t%#8.8x-%4.4x-%4.4x-%4.4x-%4.4x%8.8x ", 49743d33de9SMaksim Yevmenkin ntohl(*(uint32_t *)&uuid.b[0]), 49843d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&uuid.b[4]), 49943d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&uuid.b[6]), 50043d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&uuid.b[8]), 50143d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&uuid.b[10]), 50243d33de9SMaksim Yevmenkin ntohl(*(uint32_t *)&uuid.b[12])); 5030986ab12SMaksim Yevmenkin } break; 5040986ab12SMaksim Yevmenkin 5050986ab12SMaksim Yevmenkin default: 5060986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Bluetooth Profile " \ 5070986ab12SMaksim Yevmenkin "Descriptor List. " \ 5080986ab12SMaksim Yevmenkin "Not a UUID, type=%#x\n", type); 5090986ab12SMaksim Yevmenkin return; 5100986ab12SMaksim Yevmenkin /* NOT REACHED */ 5110986ab12SMaksim Yevmenkin } 5120986ab12SMaksim Yevmenkin 5130986ab12SMaksim Yevmenkin /* Get version */ 5140986ab12SMaksim Yevmenkin SDP_GET8(type, start); 5150986ab12SMaksim Yevmenkin if (type != SDP_DATA_UINT16) { 5160986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Bluetooth Profile " \ 5170986ab12SMaksim Yevmenkin "Descriptor List. " \ 5180986ab12SMaksim Yevmenkin "Invalid version type=%#x\n", type); 5190986ab12SMaksim Yevmenkin return; 5200986ab12SMaksim Yevmenkin } 5210986ab12SMaksim Yevmenkin 5220986ab12SMaksim Yevmenkin SDP_GET16(value, start); 5230986ab12SMaksim Yevmenkin fprintf(stdout, "ver. %d.%d\n", 5240986ab12SMaksim Yevmenkin (value >> 8) & 0xff, value & 0xff); 5250986ab12SMaksim Yevmenkin } 5260986ab12SMaksim Yevmenkin } /* print_bluetooth_profile_descriptor_list */ 5270986ab12SMaksim Yevmenkin 5280986ab12SMaksim Yevmenkin /* Perform SDP search command */ 5290986ab12SMaksim Yevmenkin static int 5300986ab12SMaksim Yevmenkin do_sdp_search(void *xs, int argc, char **argv) 5310986ab12SMaksim Yevmenkin { 5320986ab12SMaksim Yevmenkin char *ep = NULL; 5330986ab12SMaksim Yevmenkin int32_t n, type, value; 534a4b187faSMaksim Yevmenkin uint16_t service; 5350986ab12SMaksim Yevmenkin 5360986ab12SMaksim Yevmenkin /* Parse command line arguments */ 5370986ab12SMaksim Yevmenkin switch (argc) { 5380986ab12SMaksim Yevmenkin case 1: 5390986ab12SMaksim Yevmenkin n = strtoul(argv[0], &ep, 16); 5400986ab12SMaksim Yevmenkin if (*ep != 0) { 5410986ab12SMaksim Yevmenkin switch (tolower(argv[0][0])) { 5420986ab12SMaksim Yevmenkin case 'c': /* CIP/CTP */ 5430986ab12SMaksim Yevmenkin switch (tolower(argv[0][1])) { 5440986ab12SMaksim Yevmenkin case 'i': 5450986ab12SMaksim Yevmenkin service = SDP_SERVICE_CLASS_COMMON_ISDN_ACCESS; 5460986ab12SMaksim Yevmenkin break; 5470986ab12SMaksim Yevmenkin 5480986ab12SMaksim Yevmenkin case 't': 5490986ab12SMaksim Yevmenkin service = SDP_SERVICE_CLASS_CORDLESS_TELEPHONY; 5500986ab12SMaksim Yevmenkin break; 5510986ab12SMaksim Yevmenkin 5520986ab12SMaksim Yevmenkin default: 5530986ab12SMaksim Yevmenkin return (USAGE); 5540986ab12SMaksim Yevmenkin /* NOT REACHED */ 5550986ab12SMaksim Yevmenkin } 5560986ab12SMaksim Yevmenkin break; 5570986ab12SMaksim Yevmenkin 5580986ab12SMaksim Yevmenkin case 'd': /* DialUp Networking */ 5590986ab12SMaksim Yevmenkin service = SDP_SERVICE_CLASS_DIALUP_NETWORKING; 5600986ab12SMaksim Yevmenkin break; 5610986ab12SMaksim Yevmenkin 5620986ab12SMaksim Yevmenkin case 'f': /* Fax/OBEX File Transfer */ 5630986ab12SMaksim Yevmenkin switch (tolower(argv[0][1])) { 5640986ab12SMaksim Yevmenkin case 'a': 5650986ab12SMaksim Yevmenkin service = SDP_SERVICE_CLASS_FAX; 5660986ab12SMaksim Yevmenkin break; 5670986ab12SMaksim Yevmenkin 5680986ab12SMaksim Yevmenkin case 't': 5690986ab12SMaksim Yevmenkin service = SDP_SERVICE_CLASS_OBEX_FILE_TRANSFER; 5700986ab12SMaksim Yevmenkin break; 5710986ab12SMaksim Yevmenkin 5720986ab12SMaksim Yevmenkin default: 5730986ab12SMaksim Yevmenkin return (USAGE); 5740986ab12SMaksim Yevmenkin /* NOT REACHED */ 5750986ab12SMaksim Yevmenkin } 5760986ab12SMaksim Yevmenkin break; 5770986ab12SMaksim Yevmenkin 5780986ab12SMaksim Yevmenkin case 'g': /* GN */ 5790986ab12SMaksim Yevmenkin service = SDP_SERVICE_CLASS_GN; 5800986ab12SMaksim Yevmenkin break; 5810986ab12SMaksim Yevmenkin 5820986ab12SMaksim Yevmenkin case 'h': /* Headset/HID */ 5830986ab12SMaksim Yevmenkin switch (tolower(argv[0][1])) { 5840986ab12SMaksim Yevmenkin case 'i': 5850986ab12SMaksim Yevmenkin service = SDP_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE; 5860986ab12SMaksim Yevmenkin break; 5870986ab12SMaksim Yevmenkin 5880986ab12SMaksim Yevmenkin case 's': 5890986ab12SMaksim Yevmenkin service = SDP_SERVICE_CLASS_HEADSET; 5900986ab12SMaksim Yevmenkin break; 5910986ab12SMaksim Yevmenkin 5920986ab12SMaksim Yevmenkin default: 5930986ab12SMaksim Yevmenkin return (USAGE); 5940986ab12SMaksim Yevmenkin /* NOT REACHED */ 5950986ab12SMaksim Yevmenkin } 5960986ab12SMaksim Yevmenkin break; 5970986ab12SMaksim Yevmenkin 5980986ab12SMaksim Yevmenkin case 'l': /* LAN Access Using PPP */ 5990986ab12SMaksim Yevmenkin service = SDP_SERVICE_CLASS_LAN_ACCESS_USING_PPP; 6000986ab12SMaksim Yevmenkin break; 6010986ab12SMaksim Yevmenkin 6020986ab12SMaksim Yevmenkin case 'n': /* NAP */ 6030986ab12SMaksim Yevmenkin service = SDP_SERVICE_CLASS_NAP; 6040986ab12SMaksim Yevmenkin break; 6050986ab12SMaksim Yevmenkin 6060986ab12SMaksim Yevmenkin case 'o': /* OBEX Object Push */ 6070986ab12SMaksim Yevmenkin service = SDP_SERVICE_CLASS_OBEX_OBJECT_PUSH; 6080986ab12SMaksim Yevmenkin break; 6090986ab12SMaksim Yevmenkin 6100986ab12SMaksim Yevmenkin case 's': /* Serial Port */ 6110986ab12SMaksim Yevmenkin service = SDP_SERVICE_CLASS_SERIAL_PORT; 6120986ab12SMaksim Yevmenkin break; 6130986ab12SMaksim Yevmenkin 6140986ab12SMaksim Yevmenkin default: 6150986ab12SMaksim Yevmenkin return (USAGE); 6160986ab12SMaksim Yevmenkin /* NOT REACHED */ 6170986ab12SMaksim Yevmenkin } 6180986ab12SMaksim Yevmenkin } else 619a4b187faSMaksim Yevmenkin service = (uint16_t) n; 6200986ab12SMaksim Yevmenkin break; 6210986ab12SMaksim Yevmenkin 6220986ab12SMaksim Yevmenkin default: 6230986ab12SMaksim Yevmenkin return (USAGE); 6240986ab12SMaksim Yevmenkin } 6250986ab12SMaksim Yevmenkin 6260986ab12SMaksim Yevmenkin /* Initialize attribute values array */ 6270986ab12SMaksim Yevmenkin for (n = 0; n < values_len; n ++) { 6280986ab12SMaksim Yevmenkin values[n].flags = SDP_ATTR_INVALID; 6290986ab12SMaksim Yevmenkin values[n].attr = 0; 6300986ab12SMaksim Yevmenkin values[n].vlen = BSIZE; 6310986ab12SMaksim Yevmenkin values[n].value = buffer[n]; 6320986ab12SMaksim Yevmenkin } 6330986ab12SMaksim Yevmenkin 6340986ab12SMaksim Yevmenkin /* Do SDP Service Search Attribute Request */ 6350986ab12SMaksim Yevmenkin n = sdp_search(xs, 1, &service, attrs_len, attrs, values_len, values); 6360986ab12SMaksim Yevmenkin if (n != 0) 6370986ab12SMaksim Yevmenkin return (ERROR); 6380986ab12SMaksim Yevmenkin 6390986ab12SMaksim Yevmenkin /* Print attributes values */ 6400986ab12SMaksim Yevmenkin for (n = 0; n < values_len; n ++) { 6410986ab12SMaksim Yevmenkin if (values[n].flags != SDP_ATTR_OK) 6420986ab12SMaksim Yevmenkin break; 6430986ab12SMaksim Yevmenkin 6440986ab12SMaksim Yevmenkin switch (values[n].attr) { 6450986ab12SMaksim Yevmenkin case SDP_ATTR_SERVICE_RECORD_HANDLE: 6460986ab12SMaksim Yevmenkin fprintf(stdout, "\n"); 6470986ab12SMaksim Yevmenkin if (values[n].vlen == 5) { 6480986ab12SMaksim Yevmenkin SDP_GET8(type, values[n].value); 6490986ab12SMaksim Yevmenkin if (type == SDP_DATA_UINT32) { 6500986ab12SMaksim Yevmenkin SDP_GET32(value, values[n].value); 6510986ab12SMaksim Yevmenkin fprintf(stdout, "Record Handle: " \ 6520986ab12SMaksim Yevmenkin "%#8.8x\n", value); 6530986ab12SMaksim Yevmenkin } else 6540986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid type=%#x " \ 6550986ab12SMaksim Yevmenkin "Record Handle " \ 6560986ab12SMaksim Yevmenkin "attribute!\n", type); 6570986ab12SMaksim Yevmenkin } else 6580986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid size=%d for Record " \ 6590986ab12SMaksim Yevmenkin "Handle attribute\n", 6600986ab12SMaksim Yevmenkin values[n].vlen); 6610986ab12SMaksim Yevmenkin break; 6620986ab12SMaksim Yevmenkin 6630986ab12SMaksim Yevmenkin case SDP_ATTR_SERVICE_CLASS_ID_LIST: 6640986ab12SMaksim Yevmenkin fprintf(stdout, "Service Class ID List:\n"); 6650986ab12SMaksim Yevmenkin print_service_class_id_list(values[n].value, 6660986ab12SMaksim Yevmenkin values[n].value + values[n].vlen); 6670986ab12SMaksim Yevmenkin break; 6680986ab12SMaksim Yevmenkin 6690986ab12SMaksim Yevmenkin case SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST: 6700986ab12SMaksim Yevmenkin fprintf(stdout, "Protocol Descriptor List:\n"); 6710986ab12SMaksim Yevmenkin print_protocol_descriptor_list(values[n].value, 6720986ab12SMaksim Yevmenkin values[n].value + values[n].vlen); 6730986ab12SMaksim Yevmenkin break; 6740986ab12SMaksim Yevmenkin 6750986ab12SMaksim Yevmenkin case SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST: 6760986ab12SMaksim Yevmenkin fprintf(stdout, "Bluetooth Profile Descriptor List:\n"); 6770986ab12SMaksim Yevmenkin print_bluetooth_profile_descriptor_list(values[n].value, 6780986ab12SMaksim Yevmenkin values[n].value + values[n].vlen); 6790986ab12SMaksim Yevmenkin break; 6800986ab12SMaksim Yevmenkin 6810986ab12SMaksim Yevmenkin default: 6820986ab12SMaksim Yevmenkin fprintf(stderr, "Unexpected attribute ID=%#4.4x\n", 6830986ab12SMaksim Yevmenkin values[n].attr); 6840986ab12SMaksim Yevmenkin break; 6850986ab12SMaksim Yevmenkin } 6860986ab12SMaksim Yevmenkin } 6870986ab12SMaksim Yevmenkin 6880986ab12SMaksim Yevmenkin return (OK); 6890986ab12SMaksim Yevmenkin } /* do_sdp_search */ 6900986ab12SMaksim Yevmenkin 6910986ab12SMaksim Yevmenkin /* Perform SDP browse command */ 6920986ab12SMaksim Yevmenkin static int 6930986ab12SMaksim Yevmenkin do_sdp_browse(void *xs, int argc, char **argv) 6940986ab12SMaksim Yevmenkin { 6950986ab12SMaksim Yevmenkin #undef _STR 6960986ab12SMaksim Yevmenkin #undef STR 6970986ab12SMaksim Yevmenkin #define _STR(x) #x 6980986ab12SMaksim Yevmenkin #define STR(x) _STR(x) 6990986ab12SMaksim Yevmenkin 7000986ab12SMaksim Yevmenkin static char const * const av[] = { 7010986ab12SMaksim Yevmenkin STR(SDP_SERVICE_CLASS_PUBLIC_BROWSE_GROUP), 7020986ab12SMaksim Yevmenkin NULL 7030986ab12SMaksim Yevmenkin }; 7040986ab12SMaksim Yevmenkin 7050986ab12SMaksim Yevmenkin switch (argc) { 7060986ab12SMaksim Yevmenkin case 0: 7070986ab12SMaksim Yevmenkin argc = 1; 7080986ab12SMaksim Yevmenkin argv = (char **) av; 7090986ab12SMaksim Yevmenkin /* FALL THROUGH */ 7100986ab12SMaksim Yevmenkin case 1: 7110986ab12SMaksim Yevmenkin return (do_sdp_search(xs, argc, argv)); 7120986ab12SMaksim Yevmenkin } 7130986ab12SMaksim Yevmenkin 7140986ab12SMaksim Yevmenkin return (USAGE); 7150986ab12SMaksim Yevmenkin } /* do_sdp_browse */ 7160986ab12SMaksim Yevmenkin 7170986ab12SMaksim Yevmenkin /* List of SDP commands */ 7180986ab12SMaksim Yevmenkin struct sdp_command sdp_commands[] = { 7190986ab12SMaksim Yevmenkin { 7200986ab12SMaksim Yevmenkin "Browse [<Group>]", 7210986ab12SMaksim Yevmenkin "Browse for services. The <Group> parameter is a 16-bit UUID of the group\n" \ 7220986ab12SMaksim Yevmenkin "to browse. If omitted <Group> is set to Public Browse Group.\n\n" \ 7230986ab12SMaksim Yevmenkin "\t<Group> - xxxx; 16-bit UUID of the group to browse\n", 7240986ab12SMaksim Yevmenkin do_sdp_browse 7250986ab12SMaksim Yevmenkin }, 7260986ab12SMaksim Yevmenkin { 7270986ab12SMaksim Yevmenkin "Search <Service>", 7280986ab12SMaksim Yevmenkin "Search for the <Service>. The <Service> parameter is a 16-bit UUID of the\n" \ 7290986ab12SMaksim Yevmenkin "service to search for. For some services it is possible to use service name\n"\ 7300986ab12SMaksim Yevmenkin "instead of service UUID\n\n" \ 7310986ab12SMaksim Yevmenkin "\t<Service> - xxxx; 16-bit UUID of the service to search for\n\n" \ 7320986ab12SMaksim Yevmenkin "\tKnown service names\n" \ 7330986ab12SMaksim Yevmenkin "\t===================\n" \ 7340986ab12SMaksim Yevmenkin "\tCIP - Common ISDN Access\n" \ 7350986ab12SMaksim Yevmenkin "\tCTP - Cordless Telephony\n" \ 7360986ab12SMaksim Yevmenkin "\tDUN - DialUp Networking\n" \ 7370986ab12SMaksim Yevmenkin "\tFAX - Fax\n" \ 7380986ab12SMaksim Yevmenkin "\tFTRN - OBEX File Transfer\n" \ 7390986ab12SMaksim Yevmenkin "\tGN - GN\n" \ 7400986ab12SMaksim Yevmenkin "\tHID - Human Interface Device\n" \ 7410986ab12SMaksim Yevmenkin "\tHSET - Headset\n" \ 7420986ab12SMaksim Yevmenkin "\tLAN - LAN Access Using PPP\n" \ 7430986ab12SMaksim Yevmenkin "\tNAP - Network Access Point\n" \ 7440986ab12SMaksim Yevmenkin "\tOPUSH - OBEX Object Push\n" \ 7450986ab12SMaksim Yevmenkin "\tSP - Serial Port\n", 7460986ab12SMaksim Yevmenkin do_sdp_search 7470986ab12SMaksim Yevmenkin }, 7480986ab12SMaksim Yevmenkin { NULL, NULL, NULL } 7490986ab12SMaksim Yevmenkin }; 7500986ab12SMaksim Yevmenkin 751