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