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> 330986ab12SMaksim Yevmenkin #include <bluetooth.h> 340986ab12SMaksim Yevmenkin #include <ctype.h> 350986ab12SMaksim Yevmenkin #include <sdp.h> 360986ab12SMaksim Yevmenkin #include <stdio.h> 370986ab12SMaksim Yevmenkin #include <stdlib.h> 380986ab12SMaksim Yevmenkin #include "sdpcontrol.h" 390986ab12SMaksim Yevmenkin 400986ab12SMaksim Yevmenkin /* List of the attributes we are looking for */ 41a4b187faSMaksim Yevmenkin static uint32_t attrs[] = 420986ab12SMaksim Yevmenkin { 430986ab12SMaksim Yevmenkin SDP_ATTR_RANGE( SDP_ATTR_SERVICE_RECORD_HANDLE, 440986ab12SMaksim Yevmenkin SDP_ATTR_SERVICE_RECORD_HANDLE), 450986ab12SMaksim Yevmenkin SDP_ATTR_RANGE( SDP_ATTR_SERVICE_CLASS_ID_LIST, 460986ab12SMaksim Yevmenkin SDP_ATTR_SERVICE_CLASS_ID_LIST), 470986ab12SMaksim Yevmenkin SDP_ATTR_RANGE( SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST, 480986ab12SMaksim Yevmenkin SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST), 490986ab12SMaksim Yevmenkin SDP_ATTR_RANGE( SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST, 500986ab12SMaksim Yevmenkin SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST) 510986ab12SMaksim Yevmenkin }; 520986ab12SMaksim Yevmenkin #define attrs_len (sizeof(attrs)/sizeof(attrs[0])) 530986ab12SMaksim Yevmenkin 540986ab12SMaksim Yevmenkin /* Buffer for the attributes */ 550986ab12SMaksim Yevmenkin #define NRECS 25 /* request this much records from the SDP server */ 560986ab12SMaksim Yevmenkin #define BSIZE 256 /* one attribute buffer size */ 57a4b187faSMaksim Yevmenkin static uint8_t buffer[NRECS * attrs_len][BSIZE]; 580986ab12SMaksim Yevmenkin 590986ab12SMaksim Yevmenkin /* SDP attributes */ 600986ab12SMaksim Yevmenkin static sdp_attr_t values[NRECS * attrs_len]; 610986ab12SMaksim Yevmenkin #define values_len (sizeof(values)/sizeof(values[0])) 620986ab12SMaksim Yevmenkin 630986ab12SMaksim Yevmenkin /* 640986ab12SMaksim Yevmenkin * Print Service Class ID List 650986ab12SMaksim Yevmenkin * 660986ab12SMaksim Yevmenkin * The ServiceClassIDList attribute consists of a data element sequence in 670986ab12SMaksim Yevmenkin * which each data element is a UUID representing the service classes that 680986ab12SMaksim Yevmenkin * a given service record conforms to. The UUIDs are listed in order from 690986ab12SMaksim Yevmenkin * the most specific class to the most general class. The ServiceClassIDList 700986ab12SMaksim Yevmenkin * must contain at least one service class UUID. 710986ab12SMaksim Yevmenkin */ 720986ab12SMaksim Yevmenkin 730986ab12SMaksim Yevmenkin static void 74a4b187faSMaksim Yevmenkin print_service_class_id_list(uint8_t const *start, uint8_t const *end) 750986ab12SMaksim Yevmenkin { 76a4b187faSMaksim Yevmenkin uint32_t type, len, value; 770986ab12SMaksim Yevmenkin 780986ab12SMaksim Yevmenkin if (end - start < 2) { 790986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Service Class ID List. " \ 804ae439a3SMaksim Yevmenkin "Too short, len=%zd\n", end - start); 810986ab12SMaksim Yevmenkin return; 820986ab12SMaksim Yevmenkin } 830986ab12SMaksim Yevmenkin 840986ab12SMaksim Yevmenkin SDP_GET8(type, start); 850986ab12SMaksim Yevmenkin switch (type) { 860986ab12SMaksim Yevmenkin case SDP_DATA_SEQ8: 870986ab12SMaksim Yevmenkin SDP_GET8(len, start); 880986ab12SMaksim Yevmenkin break; 890986ab12SMaksim Yevmenkin 900986ab12SMaksim Yevmenkin case SDP_DATA_SEQ16: 910986ab12SMaksim Yevmenkin SDP_GET16(len, start); 920986ab12SMaksim Yevmenkin break; 930986ab12SMaksim Yevmenkin 940986ab12SMaksim Yevmenkin case SDP_DATA_SEQ32: 950986ab12SMaksim Yevmenkin SDP_GET32(len, start); 960986ab12SMaksim Yevmenkin break; 970986ab12SMaksim Yevmenkin 980986ab12SMaksim Yevmenkin default: 990986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Service Class ID List. " \ 1000986ab12SMaksim Yevmenkin "Not a sequence, type=%#x\n", type); 1010986ab12SMaksim Yevmenkin return; 1020986ab12SMaksim Yevmenkin /* NOT REACHED */ 1030986ab12SMaksim Yevmenkin } 1040986ab12SMaksim Yevmenkin 1050986ab12SMaksim Yevmenkin while (start < end) { 1060986ab12SMaksim Yevmenkin SDP_GET8(type, start); 1070986ab12SMaksim Yevmenkin switch (type) { 1080986ab12SMaksim Yevmenkin case SDP_DATA_UUID16: 1090986ab12SMaksim Yevmenkin SDP_GET16(value, start); 1100986ab12SMaksim Yevmenkin fprintf(stdout, "\t%s (%#4.4x)\n", 1110986ab12SMaksim Yevmenkin sdp_uuid2desc(value), value); 1120986ab12SMaksim Yevmenkin break; 1130986ab12SMaksim Yevmenkin 1140986ab12SMaksim Yevmenkin case SDP_DATA_UUID32: 1150986ab12SMaksim Yevmenkin SDP_GET32(value, start); 1160986ab12SMaksim Yevmenkin fprintf(stdout, "\t%#8.8x\n", value); 1170986ab12SMaksim Yevmenkin break; 1180986ab12SMaksim Yevmenkin 1190986ab12SMaksim Yevmenkin case SDP_DATA_UUID128: { 1200986ab12SMaksim Yevmenkin int128_t uuid; 1210986ab12SMaksim Yevmenkin 12243d33de9SMaksim Yevmenkin SDP_GET_UUID128(&uuid, start); 1230986ab12SMaksim Yevmenkin fprintf(stdout, "\t%#8.8x-%4.4x-%4.4x-%4.4x-%4.4x%8.8x\n", 12443d33de9SMaksim Yevmenkin ntohl(*(uint32_t *)&uuid.b[0]), 12543d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&uuid.b[4]), 12643d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&uuid.b[6]), 12743d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&uuid.b[8]), 12843d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&uuid.b[10]), 12943d33de9SMaksim Yevmenkin ntohl(*(uint32_t *)&uuid.b[12])); 1300986ab12SMaksim Yevmenkin } break; 1310986ab12SMaksim Yevmenkin 1320986ab12SMaksim Yevmenkin default: 1330986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Service Class ID List. " \ 1340986ab12SMaksim Yevmenkin "Not a UUID, type=%#x\n", type); 1350986ab12SMaksim Yevmenkin return; 1360986ab12SMaksim Yevmenkin /* NOT REACHED */ 1370986ab12SMaksim Yevmenkin } 1380986ab12SMaksim Yevmenkin } 1390986ab12SMaksim Yevmenkin } /* print_service_class_id_list */ 1400986ab12SMaksim Yevmenkin 1410986ab12SMaksim Yevmenkin /* 1420986ab12SMaksim Yevmenkin * Print Protocol Descriptor List 1430986ab12SMaksim Yevmenkin * 1440986ab12SMaksim Yevmenkin * If the ProtocolDescriptorList describes a single stack, it takes the form 1450986ab12SMaksim Yevmenkin * of a data element sequence in which each element of the sequence is a 1460986ab12SMaksim Yevmenkin * protocol descriptor. Each protocol descriptor is, in turn, a data element 1470986ab12SMaksim Yevmenkin * sequence whose first element is a UUID identifying the protocol and whose 1480986ab12SMaksim Yevmenkin * successive elements are protocol-specific parameters. The protocol 1490986ab12SMaksim Yevmenkin * descriptors are listed in order from the lowest layer protocol to the 1500986ab12SMaksim Yevmenkin * highest layer protocol used to gain access to the service. If it is possible 1510986ab12SMaksim Yevmenkin * for more than one kind of protocol stack to be used to gain access to the 1520986ab12SMaksim Yevmenkin * service, the ProtocolDescriptorList takes the form of a data element 1530986ab12SMaksim Yevmenkin * alternative where each member is a data element sequence as described above. 1540986ab12SMaksim Yevmenkin */ 1550986ab12SMaksim Yevmenkin 1560986ab12SMaksim Yevmenkin static void 157a4b187faSMaksim Yevmenkin print_protocol_descriptor(uint8_t const *start, uint8_t const *end) 1580986ab12SMaksim Yevmenkin { 1590986ab12SMaksim Yevmenkin union { 1600986ab12SMaksim Yevmenkin uint8_t uint8; 1610986ab12SMaksim Yevmenkin uint16_t uint16; 1620986ab12SMaksim Yevmenkin uint32_t uint32; 1630986ab12SMaksim Yevmenkin uint64_t uint64; 1640986ab12SMaksim Yevmenkin int128_t int128; 1650986ab12SMaksim Yevmenkin } value; 166a4b187faSMaksim Yevmenkin uint32_t type, len, param; 1670986ab12SMaksim Yevmenkin 1680986ab12SMaksim Yevmenkin /* Get Protocol UUID */ 1690986ab12SMaksim Yevmenkin SDP_GET8(type, start); 1700986ab12SMaksim Yevmenkin switch (type) { 1710986ab12SMaksim Yevmenkin case SDP_DATA_UUID16: 1720986ab12SMaksim Yevmenkin SDP_GET16(value.uint16, start); 1730986ab12SMaksim Yevmenkin fprintf(stdout, "\t%s (%#4.4x)\n", sdp_uuid2desc(value.uint16), 1740986ab12SMaksim Yevmenkin value.uint16); 1750986ab12SMaksim Yevmenkin break; 1760986ab12SMaksim Yevmenkin 1770986ab12SMaksim Yevmenkin case SDP_DATA_UUID32: 1780986ab12SMaksim Yevmenkin SDP_GET32(value.uint32, start); 1790986ab12SMaksim Yevmenkin fprintf(stdout, "\t%#8.8x\n", value.uint32); 1800986ab12SMaksim Yevmenkin break; 1810986ab12SMaksim Yevmenkin 1820986ab12SMaksim Yevmenkin case SDP_DATA_UUID128: 18343d33de9SMaksim Yevmenkin SDP_GET_UUID128(&value.int128, start); 1840986ab12SMaksim Yevmenkin fprintf(stdout, "\t%#8.8x-%4.4x-%4.4x-%4.4x-%4.4x%8.8x\n", 18543d33de9SMaksim Yevmenkin ntohl(*(uint32_t *)&value.int128.b[0]), 18643d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&value.int128.b[4]), 18743d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&value.int128.b[6]), 18843d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&value.int128.b[8]), 18943d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&value.int128.b[10]), 19043d33de9SMaksim Yevmenkin ntohl(*(uint32_t *)&value.int128.b[12])); 1910986ab12SMaksim Yevmenkin break; 1920986ab12SMaksim Yevmenkin 1930986ab12SMaksim Yevmenkin default: 1940986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Protocol Descriptor. " \ 1950986ab12SMaksim Yevmenkin "Not a UUID, type=%#x\n", type); 1960986ab12SMaksim Yevmenkin return; 1970986ab12SMaksim Yevmenkin /* NOT REACHED */ 1980986ab12SMaksim Yevmenkin } 1990986ab12SMaksim Yevmenkin 2000986ab12SMaksim Yevmenkin /* Protocol specific parameters */ 2010986ab12SMaksim Yevmenkin for (param = 1; start < end; param ++) { 2020986ab12SMaksim Yevmenkin fprintf(stdout, "\t\tProtocol specific parameter #%d: ", param); 2030986ab12SMaksim Yevmenkin 2040986ab12SMaksim Yevmenkin SDP_GET8(type, start); 2050986ab12SMaksim Yevmenkin switch (type) { 2060986ab12SMaksim Yevmenkin case SDP_DATA_NIL: 2070986ab12SMaksim Yevmenkin fprintf(stdout, "nil\n"); 2080986ab12SMaksim Yevmenkin break; 2090986ab12SMaksim Yevmenkin 2100986ab12SMaksim Yevmenkin case SDP_DATA_UINT8: 2110986ab12SMaksim Yevmenkin case SDP_DATA_INT8: 2120986ab12SMaksim Yevmenkin case SDP_DATA_BOOL: 2130986ab12SMaksim Yevmenkin SDP_GET8(value.uint8, start); 2140986ab12SMaksim Yevmenkin fprintf(stdout, "u/int8/bool %u\n", value.uint8); 2150986ab12SMaksim Yevmenkin break; 2160986ab12SMaksim Yevmenkin 2170986ab12SMaksim Yevmenkin case SDP_DATA_UINT16: 2180986ab12SMaksim Yevmenkin case SDP_DATA_INT16: 2190986ab12SMaksim Yevmenkin case SDP_DATA_UUID16: 2200986ab12SMaksim Yevmenkin SDP_GET16(value.uint16, start); 2210986ab12SMaksim Yevmenkin fprintf(stdout, "u/int/uuid16 %u\n", value.uint16); 2220986ab12SMaksim Yevmenkin break; 2230986ab12SMaksim Yevmenkin 2240986ab12SMaksim Yevmenkin case SDP_DATA_UINT32: 2250986ab12SMaksim Yevmenkin case SDP_DATA_INT32: 2260986ab12SMaksim Yevmenkin case SDP_DATA_UUID32: 2270986ab12SMaksim Yevmenkin SDP_GET32(value.uint32, start); 2280986ab12SMaksim Yevmenkin fprintf(stdout, "u/int/uuid32 %u\n", value.uint32); 2290986ab12SMaksim Yevmenkin break; 2300986ab12SMaksim Yevmenkin 2310986ab12SMaksim Yevmenkin case SDP_DATA_UINT64: 2320986ab12SMaksim Yevmenkin case SDP_DATA_INT64: 2330986ab12SMaksim Yevmenkin SDP_GET64(value.uint64, start); 2344ae439a3SMaksim Yevmenkin fprintf(stdout, "u/int64 %ju\n", value.uint64); 2350986ab12SMaksim Yevmenkin break; 2360986ab12SMaksim Yevmenkin 2370986ab12SMaksim Yevmenkin case SDP_DATA_UINT128: 2380986ab12SMaksim Yevmenkin case SDP_DATA_INT128: 2390986ab12SMaksim Yevmenkin SDP_GET128(&value.int128, start); 24043d33de9SMaksim Yevmenkin fprintf(stdout, "u/int128 %#8.8x%8.8x%8.8x%8.8x\n", 241a4b187faSMaksim Yevmenkin *(uint32_t *)&value.int128.b[0], 24243d33de9SMaksim Yevmenkin *(uint32_t *)&value.int128.b[4], 24343d33de9SMaksim Yevmenkin *(uint32_t *)&value.int128.b[8], 244a4b187faSMaksim Yevmenkin *(uint32_t *)&value.int128.b[12]); 2450986ab12SMaksim Yevmenkin break; 2460986ab12SMaksim Yevmenkin 24743d33de9SMaksim Yevmenkin case SDP_DATA_UUID128: 24843d33de9SMaksim Yevmenkin SDP_GET_UUID128(&value.int128, start); 24943d33de9SMaksim Yevmenkin fprintf(stdout, "uuid128 %#8.8x-%4.4x-%4.4x-%4.4x-%4.4x%8.8x\n", 25043d33de9SMaksim Yevmenkin ntohl(*(uint32_t *)&value.int128.b[0]), 25143d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&value.int128.b[4]), 25243d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&value.int128.b[6]), 25343d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&value.int128.b[8]), 25443d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&value.int128.b[10]), 25543d33de9SMaksim Yevmenkin ntohl(*(uint32_t *)&value.int128.b[12])); 25643d33de9SMaksim Yevmenkin break; 25743d33de9SMaksim Yevmenkin 2580986ab12SMaksim Yevmenkin case SDP_DATA_STR8: 2590986ab12SMaksim Yevmenkin case SDP_DATA_URL8: 2600986ab12SMaksim Yevmenkin SDP_GET8(len, start); 2610986ab12SMaksim Yevmenkin fprintf(stdout, "%*.*s\n", len, len, (char *) start); 2620986ab12SMaksim Yevmenkin start += len; 2630986ab12SMaksim Yevmenkin break; 2640986ab12SMaksim Yevmenkin 2650986ab12SMaksim Yevmenkin case SDP_DATA_STR16: 2660986ab12SMaksim Yevmenkin case SDP_DATA_URL16: 2670986ab12SMaksim Yevmenkin SDP_GET16(len, start); 2680986ab12SMaksim Yevmenkin fprintf(stdout, "%*.*s\n", len, len, (char *) start); 2690986ab12SMaksim Yevmenkin start += len; 2700986ab12SMaksim Yevmenkin break; 2710986ab12SMaksim Yevmenkin 2720986ab12SMaksim Yevmenkin case SDP_DATA_STR32: 2730986ab12SMaksim Yevmenkin case SDP_DATA_URL32: 2740986ab12SMaksim Yevmenkin SDP_GET32(len, start); 2750986ab12SMaksim Yevmenkin fprintf(stdout, "%*.*s\n", len, len, (char *) start); 2760986ab12SMaksim Yevmenkin start += len; 2770986ab12SMaksim Yevmenkin break; 2780986ab12SMaksim Yevmenkin 2790986ab12SMaksim Yevmenkin case SDP_DATA_SEQ8: 2800986ab12SMaksim Yevmenkin case SDP_DATA_ALT8: 2810986ab12SMaksim Yevmenkin SDP_GET8(len, start); 2820986ab12SMaksim Yevmenkin for (; len > 0; start ++, len --) 2830986ab12SMaksim Yevmenkin fprintf(stdout, "%#2.2x ", *start); 2840986ab12SMaksim Yevmenkin fprintf(stdout, "\n"); 2850986ab12SMaksim Yevmenkin break; 2860986ab12SMaksim Yevmenkin 2870986ab12SMaksim Yevmenkin case SDP_DATA_SEQ16: 2880986ab12SMaksim Yevmenkin case SDP_DATA_ALT16: 2890986ab12SMaksim Yevmenkin SDP_GET16(len, start); 2900986ab12SMaksim Yevmenkin for (; len > 0; start ++, len --) 2910986ab12SMaksim Yevmenkin fprintf(stdout, "%#2.2x ", *start); 2920986ab12SMaksim Yevmenkin fprintf(stdout, "\n"); 2930986ab12SMaksim Yevmenkin break; 2940986ab12SMaksim Yevmenkin 2950986ab12SMaksim Yevmenkin case SDP_DATA_SEQ32: 2960986ab12SMaksim Yevmenkin case SDP_DATA_ALT32: 2970986ab12SMaksim Yevmenkin SDP_GET32(len, start); 2980986ab12SMaksim Yevmenkin for (; len > 0; start ++, len --) 2990986ab12SMaksim Yevmenkin fprintf(stdout, "%#2.2x ", *start); 3000986ab12SMaksim Yevmenkin fprintf(stdout, "\n"); 3010986ab12SMaksim Yevmenkin break; 3020986ab12SMaksim Yevmenkin 3030986ab12SMaksim Yevmenkin default: 3040986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Protocol Descriptor. " \ 3050986ab12SMaksim Yevmenkin "Unknown data type: %#02x\n", type); 3060986ab12SMaksim Yevmenkin return; 3070986ab12SMaksim Yevmenkin /* NOT REACHED */ 3080986ab12SMaksim Yevmenkin } 3090986ab12SMaksim Yevmenkin } 3100986ab12SMaksim Yevmenkin } /* print_protocol_descriptor */ 3110986ab12SMaksim Yevmenkin 3120986ab12SMaksim Yevmenkin static void 313a4b187faSMaksim Yevmenkin print_protocol_descriptor_list(uint8_t const *start, uint8_t const *end) 3140986ab12SMaksim Yevmenkin { 315a4b187faSMaksim Yevmenkin uint32_t type, len; 3160986ab12SMaksim Yevmenkin 3170986ab12SMaksim Yevmenkin if (end - start < 2) { 3180986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Protocol Descriptor List. " \ 3194ae439a3SMaksim Yevmenkin "Too short, len=%zd\n", end - start); 3200986ab12SMaksim Yevmenkin return; 3210986ab12SMaksim Yevmenkin } 3220986ab12SMaksim Yevmenkin 3230986ab12SMaksim Yevmenkin SDP_GET8(type, start); 3240986ab12SMaksim Yevmenkin switch (type) { 3250986ab12SMaksim Yevmenkin case SDP_DATA_SEQ8: 3260986ab12SMaksim Yevmenkin SDP_GET8(len, start); 3270986ab12SMaksim Yevmenkin break; 3280986ab12SMaksim Yevmenkin 3290986ab12SMaksim Yevmenkin case SDP_DATA_SEQ16: 3300986ab12SMaksim Yevmenkin SDP_GET16(len, start); 3310986ab12SMaksim Yevmenkin break; 3320986ab12SMaksim Yevmenkin 3330986ab12SMaksim Yevmenkin case SDP_DATA_SEQ32: 3340986ab12SMaksim Yevmenkin SDP_GET32(len, start); 3350986ab12SMaksim Yevmenkin break; 3360986ab12SMaksim Yevmenkin 3370986ab12SMaksim Yevmenkin default: 3380986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Protocol Descriptor List. " \ 3390986ab12SMaksim Yevmenkin "Not a sequence, type=%#x\n", type); 3400986ab12SMaksim Yevmenkin return; 3410986ab12SMaksim Yevmenkin /* NOT REACHED */ 3420986ab12SMaksim Yevmenkin } 3430986ab12SMaksim Yevmenkin 3440986ab12SMaksim Yevmenkin while (start < end) { 3450986ab12SMaksim Yevmenkin SDP_GET8(type, start); 3460986ab12SMaksim Yevmenkin switch (type) { 3470986ab12SMaksim Yevmenkin case SDP_DATA_SEQ8: 3480986ab12SMaksim Yevmenkin SDP_GET8(len, start); 3490986ab12SMaksim Yevmenkin break; 3500986ab12SMaksim Yevmenkin 3510986ab12SMaksim Yevmenkin case SDP_DATA_SEQ16: 3520986ab12SMaksim Yevmenkin SDP_GET16(len, start); 3530986ab12SMaksim Yevmenkin break; 3540986ab12SMaksim Yevmenkin 3550986ab12SMaksim Yevmenkin case SDP_DATA_SEQ32: 3560986ab12SMaksim Yevmenkin SDP_GET32(len, start); 3570986ab12SMaksim Yevmenkin break; 3580986ab12SMaksim Yevmenkin 3590986ab12SMaksim Yevmenkin default: 3600986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Protocol Descriptor List. " \ 3610986ab12SMaksim Yevmenkin "Not a sequence, type=%#x\n", type); 3620986ab12SMaksim Yevmenkin return; 3630986ab12SMaksim Yevmenkin /* NOT REACHED */ 3640986ab12SMaksim Yevmenkin } 3650986ab12SMaksim Yevmenkin 3660986ab12SMaksim Yevmenkin print_protocol_descriptor(start, start + len); 3670986ab12SMaksim Yevmenkin start += len; 3680986ab12SMaksim Yevmenkin } 3690986ab12SMaksim Yevmenkin } /* print_protocol_descriptor_list */ 3700986ab12SMaksim Yevmenkin 3710986ab12SMaksim Yevmenkin /* 3720986ab12SMaksim Yevmenkin * Print Bluetooth Profile Descriptor List 3730986ab12SMaksim Yevmenkin * 3740986ab12SMaksim Yevmenkin * The BluetoothProfileDescriptorList attribute consists of a data element 3750986ab12SMaksim Yevmenkin * sequence in which each element is a profile descriptor that contains 3760986ab12SMaksim Yevmenkin * information about a Bluetooth profile to which the service represented by 3770986ab12SMaksim Yevmenkin * this service record conforms. Each profile descriptor is a data element 3780986ab12SMaksim Yevmenkin * sequence whose first element is the UUID assigned to the profile and whose 3790986ab12SMaksim Yevmenkin * second element is a 16-bit profile version number. Each version of a profile 3800986ab12SMaksim Yevmenkin * is assigned a 16-bit unsigned integer profile version number, which consists 3810986ab12SMaksim Yevmenkin * of two 8-bit fields. The higher-order 8 bits contain the major version 3820986ab12SMaksim Yevmenkin * number field and the lower-order 8 bits contain the minor version number 3830986ab12SMaksim Yevmenkin * field. 3840986ab12SMaksim Yevmenkin */ 3850986ab12SMaksim Yevmenkin 3860986ab12SMaksim Yevmenkin static void 387a4b187faSMaksim Yevmenkin print_bluetooth_profile_descriptor_list(uint8_t const *start, uint8_t const *end) 3880986ab12SMaksim Yevmenkin { 389a4b187faSMaksim Yevmenkin uint32_t type, len, value; 3900986ab12SMaksim Yevmenkin 3910986ab12SMaksim Yevmenkin if (end - start < 2) { 3920986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Bluetooth Profile Descriptor List. " \ 3934ae439a3SMaksim Yevmenkin "Too short, len=%zd\n", end - start); 3940986ab12SMaksim Yevmenkin return; 3950986ab12SMaksim Yevmenkin } 3960986ab12SMaksim Yevmenkin 3970986ab12SMaksim Yevmenkin SDP_GET8(type, start); 3980986ab12SMaksim Yevmenkin switch (type) { 3990986ab12SMaksim Yevmenkin case SDP_DATA_SEQ8: 4000986ab12SMaksim Yevmenkin SDP_GET8(len, start); 4010986ab12SMaksim Yevmenkin break; 4020986ab12SMaksim Yevmenkin 4030986ab12SMaksim Yevmenkin case SDP_DATA_SEQ16: 4040986ab12SMaksim Yevmenkin SDP_GET16(len, start); 4050986ab12SMaksim Yevmenkin break; 4060986ab12SMaksim Yevmenkin 4070986ab12SMaksim Yevmenkin case SDP_DATA_SEQ32: 4080986ab12SMaksim Yevmenkin SDP_GET32(len, start); 4090986ab12SMaksim Yevmenkin break; 4100986ab12SMaksim Yevmenkin 4110986ab12SMaksim Yevmenkin default: 4120986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Bluetooth Profile Descriptor List. " \ 4130986ab12SMaksim Yevmenkin "Not a sequence, type=%#x\n", type); 4140986ab12SMaksim Yevmenkin return; 4150986ab12SMaksim Yevmenkin /* NOT REACHED */ 4160986ab12SMaksim Yevmenkin } 4170986ab12SMaksim Yevmenkin 4180986ab12SMaksim Yevmenkin while (start < end) { 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 " \ 4350986ab12SMaksim Yevmenkin "Descriptor List. " \ 4360986ab12SMaksim Yevmenkin "Not a sequence, type=%#x\n", type); 4370986ab12SMaksim Yevmenkin return; 4380986ab12SMaksim Yevmenkin /* NOT REACHED */ 4390986ab12SMaksim Yevmenkin } 4400986ab12SMaksim Yevmenkin 4410986ab12SMaksim Yevmenkin /* Get UUID */ 4420986ab12SMaksim Yevmenkin SDP_GET8(type, start); 4430986ab12SMaksim Yevmenkin switch (type) { 4440986ab12SMaksim Yevmenkin case SDP_DATA_UUID16: 4450986ab12SMaksim Yevmenkin SDP_GET16(value, start); 4460986ab12SMaksim Yevmenkin fprintf(stdout, "\t%s (%#4.4x) ", 4470986ab12SMaksim Yevmenkin sdp_uuid2desc(value), value); 4480986ab12SMaksim Yevmenkin break; 4490986ab12SMaksim Yevmenkin 4500986ab12SMaksim Yevmenkin case SDP_DATA_UUID32: 4510986ab12SMaksim Yevmenkin SDP_GET32(value, start); 4520986ab12SMaksim Yevmenkin fprintf(stdout, "\t%#8.8x ", value); 4530986ab12SMaksim Yevmenkin break; 4540986ab12SMaksim Yevmenkin 4550986ab12SMaksim Yevmenkin case SDP_DATA_UUID128: { 4560986ab12SMaksim Yevmenkin int128_t uuid; 4570986ab12SMaksim Yevmenkin 45843d33de9SMaksim Yevmenkin SDP_GET_UUID128(&uuid, start); 4590986ab12SMaksim Yevmenkin fprintf(stdout, "\t%#8.8x-%4.4x-%4.4x-%4.4x-%4.4x%8.8x ", 46043d33de9SMaksim Yevmenkin ntohl(*(uint32_t *)&uuid.b[0]), 46143d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&uuid.b[4]), 46243d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&uuid.b[6]), 46343d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&uuid.b[8]), 46443d33de9SMaksim Yevmenkin ntohs(*(uint16_t *)&uuid.b[10]), 46543d33de9SMaksim Yevmenkin ntohl(*(uint32_t *)&uuid.b[12])); 4660986ab12SMaksim Yevmenkin } break; 4670986ab12SMaksim Yevmenkin 4680986ab12SMaksim Yevmenkin default: 4690986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Bluetooth Profile " \ 4700986ab12SMaksim Yevmenkin "Descriptor List. " \ 4710986ab12SMaksim Yevmenkin "Not a UUID, type=%#x\n", type); 4720986ab12SMaksim Yevmenkin return; 4730986ab12SMaksim Yevmenkin /* NOT REACHED */ 4740986ab12SMaksim Yevmenkin } 4750986ab12SMaksim Yevmenkin 4760986ab12SMaksim Yevmenkin /* Get version */ 4770986ab12SMaksim Yevmenkin SDP_GET8(type, start); 4780986ab12SMaksim Yevmenkin if (type != SDP_DATA_UINT16) { 4790986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid Bluetooth Profile " \ 4800986ab12SMaksim Yevmenkin "Descriptor List. " \ 4810986ab12SMaksim Yevmenkin "Invalid version type=%#x\n", type); 4820986ab12SMaksim Yevmenkin return; 4830986ab12SMaksim Yevmenkin } 4840986ab12SMaksim Yevmenkin 4850986ab12SMaksim Yevmenkin SDP_GET16(value, start); 4860986ab12SMaksim Yevmenkin fprintf(stdout, "ver. %d.%d\n", 4870986ab12SMaksim Yevmenkin (value >> 8) & 0xff, value & 0xff); 4880986ab12SMaksim Yevmenkin } 4890986ab12SMaksim Yevmenkin } /* print_bluetooth_profile_descriptor_list */ 4900986ab12SMaksim Yevmenkin 4910986ab12SMaksim Yevmenkin /* Perform SDP search command */ 4920986ab12SMaksim Yevmenkin static int 4930986ab12SMaksim Yevmenkin do_sdp_search(void *xs, int argc, char **argv) 4940986ab12SMaksim Yevmenkin { 4950986ab12SMaksim Yevmenkin char *ep = NULL; 4960986ab12SMaksim Yevmenkin int32_t n, type, value; 497a4b187faSMaksim Yevmenkin uint16_t service; 4980986ab12SMaksim Yevmenkin 4990986ab12SMaksim Yevmenkin /* Parse command line arguments */ 5000986ab12SMaksim Yevmenkin switch (argc) { 5010986ab12SMaksim Yevmenkin case 1: 5020986ab12SMaksim Yevmenkin n = strtoul(argv[0], &ep, 16); 5030986ab12SMaksim Yevmenkin if (*ep != 0) { 5040986ab12SMaksim Yevmenkin switch (tolower(argv[0][0])) { 5050986ab12SMaksim Yevmenkin case 'c': /* CIP/CTP */ 5060986ab12SMaksim Yevmenkin switch (tolower(argv[0][1])) { 5070986ab12SMaksim Yevmenkin case 'i': 5080986ab12SMaksim Yevmenkin service = SDP_SERVICE_CLASS_COMMON_ISDN_ACCESS; 5090986ab12SMaksim Yevmenkin break; 5100986ab12SMaksim Yevmenkin 5110986ab12SMaksim Yevmenkin case 't': 5120986ab12SMaksim Yevmenkin service = SDP_SERVICE_CLASS_CORDLESS_TELEPHONY; 5130986ab12SMaksim Yevmenkin break; 5140986ab12SMaksim Yevmenkin 5150986ab12SMaksim Yevmenkin default: 5160986ab12SMaksim Yevmenkin return (USAGE); 5170986ab12SMaksim Yevmenkin /* NOT REACHED */ 5180986ab12SMaksim Yevmenkin } 5190986ab12SMaksim Yevmenkin break; 5200986ab12SMaksim Yevmenkin 5210986ab12SMaksim Yevmenkin case 'd': /* DialUp Networking */ 5220986ab12SMaksim Yevmenkin service = SDP_SERVICE_CLASS_DIALUP_NETWORKING; 5230986ab12SMaksim Yevmenkin break; 5240986ab12SMaksim Yevmenkin 5250986ab12SMaksim Yevmenkin case 'f': /* Fax/OBEX File Transfer */ 5260986ab12SMaksim Yevmenkin switch (tolower(argv[0][1])) { 5270986ab12SMaksim Yevmenkin case 'a': 5280986ab12SMaksim Yevmenkin service = SDP_SERVICE_CLASS_FAX; 5290986ab12SMaksim Yevmenkin break; 5300986ab12SMaksim Yevmenkin 5310986ab12SMaksim Yevmenkin case 't': 5320986ab12SMaksim Yevmenkin service = SDP_SERVICE_CLASS_OBEX_FILE_TRANSFER; 5330986ab12SMaksim Yevmenkin break; 5340986ab12SMaksim Yevmenkin 5350986ab12SMaksim Yevmenkin default: 5360986ab12SMaksim Yevmenkin return (USAGE); 5370986ab12SMaksim Yevmenkin /* NOT REACHED */ 5380986ab12SMaksim Yevmenkin } 5390986ab12SMaksim Yevmenkin break; 5400986ab12SMaksim Yevmenkin 5410986ab12SMaksim Yevmenkin case 'g': /* GN */ 5420986ab12SMaksim Yevmenkin service = SDP_SERVICE_CLASS_GN; 5430986ab12SMaksim Yevmenkin break; 5440986ab12SMaksim Yevmenkin 5450986ab12SMaksim Yevmenkin case 'h': /* Headset/HID */ 5460986ab12SMaksim Yevmenkin switch (tolower(argv[0][1])) { 5470986ab12SMaksim Yevmenkin case 'i': 5480986ab12SMaksim Yevmenkin service = SDP_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE; 5490986ab12SMaksim Yevmenkin break; 5500986ab12SMaksim Yevmenkin 5510986ab12SMaksim Yevmenkin case 's': 5520986ab12SMaksim Yevmenkin service = SDP_SERVICE_CLASS_HEADSET; 5530986ab12SMaksim Yevmenkin break; 5540986ab12SMaksim Yevmenkin 5550986ab12SMaksim Yevmenkin default: 5560986ab12SMaksim Yevmenkin return (USAGE); 5570986ab12SMaksim Yevmenkin /* NOT REACHED */ 5580986ab12SMaksim Yevmenkin } 5590986ab12SMaksim Yevmenkin break; 5600986ab12SMaksim Yevmenkin 5610986ab12SMaksim Yevmenkin case 'l': /* LAN Access Using PPP */ 5620986ab12SMaksim Yevmenkin service = SDP_SERVICE_CLASS_LAN_ACCESS_USING_PPP; 5630986ab12SMaksim Yevmenkin break; 5640986ab12SMaksim Yevmenkin 5650986ab12SMaksim Yevmenkin case 'n': /* NAP */ 5660986ab12SMaksim Yevmenkin service = SDP_SERVICE_CLASS_NAP; 5670986ab12SMaksim Yevmenkin break; 5680986ab12SMaksim Yevmenkin 5690986ab12SMaksim Yevmenkin case 'o': /* OBEX Object Push */ 5700986ab12SMaksim Yevmenkin service = SDP_SERVICE_CLASS_OBEX_OBJECT_PUSH; 5710986ab12SMaksim Yevmenkin break; 5720986ab12SMaksim Yevmenkin 5730986ab12SMaksim Yevmenkin case 's': /* Serial Port */ 5740986ab12SMaksim Yevmenkin service = SDP_SERVICE_CLASS_SERIAL_PORT; 5750986ab12SMaksim Yevmenkin break; 5760986ab12SMaksim Yevmenkin 5770986ab12SMaksim Yevmenkin default: 5780986ab12SMaksim Yevmenkin return (USAGE); 5790986ab12SMaksim Yevmenkin /* NOT REACHED */ 5800986ab12SMaksim Yevmenkin } 5810986ab12SMaksim Yevmenkin } else 582a4b187faSMaksim Yevmenkin service = (uint16_t) n; 5830986ab12SMaksim Yevmenkin break; 5840986ab12SMaksim Yevmenkin 5850986ab12SMaksim Yevmenkin default: 5860986ab12SMaksim Yevmenkin return (USAGE); 5870986ab12SMaksim Yevmenkin } 5880986ab12SMaksim Yevmenkin 5890986ab12SMaksim Yevmenkin if (service < SDP_SERVICE_CLASS_SERVICE_DISCOVERY_SERVER) 5900986ab12SMaksim Yevmenkin return (USAGE); 5910986ab12SMaksim Yevmenkin 5920986ab12SMaksim Yevmenkin /* Initialize attribute values array */ 5930986ab12SMaksim Yevmenkin for (n = 0; n < values_len; n ++) { 5940986ab12SMaksim Yevmenkin values[n].flags = SDP_ATTR_INVALID; 5950986ab12SMaksim Yevmenkin values[n].attr = 0; 5960986ab12SMaksim Yevmenkin values[n].vlen = BSIZE; 5970986ab12SMaksim Yevmenkin values[n].value = buffer[n]; 5980986ab12SMaksim Yevmenkin } 5990986ab12SMaksim Yevmenkin 6000986ab12SMaksim Yevmenkin /* Do SDP Service Search Attribute Request */ 6010986ab12SMaksim Yevmenkin n = sdp_search(xs, 1, &service, attrs_len, attrs, values_len, values); 6020986ab12SMaksim Yevmenkin if (n != 0) 6030986ab12SMaksim Yevmenkin return (ERROR); 6040986ab12SMaksim Yevmenkin 6050986ab12SMaksim Yevmenkin /* Print attributes values */ 6060986ab12SMaksim Yevmenkin for (n = 0; n < values_len; n ++) { 6070986ab12SMaksim Yevmenkin if (values[n].flags != SDP_ATTR_OK) 6080986ab12SMaksim Yevmenkin break; 6090986ab12SMaksim Yevmenkin 6100986ab12SMaksim Yevmenkin switch (values[n].attr) { 6110986ab12SMaksim Yevmenkin case SDP_ATTR_SERVICE_RECORD_HANDLE: 6120986ab12SMaksim Yevmenkin fprintf(stdout, "\n"); 6130986ab12SMaksim Yevmenkin if (values[n].vlen == 5) { 6140986ab12SMaksim Yevmenkin SDP_GET8(type, values[n].value); 6150986ab12SMaksim Yevmenkin if (type == SDP_DATA_UINT32) { 6160986ab12SMaksim Yevmenkin SDP_GET32(value, values[n].value); 6170986ab12SMaksim Yevmenkin fprintf(stdout, "Record Handle: " \ 6180986ab12SMaksim Yevmenkin "%#8.8x\n", value); 6190986ab12SMaksim Yevmenkin } else 6200986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid type=%#x " \ 6210986ab12SMaksim Yevmenkin "Record Handle " \ 6220986ab12SMaksim Yevmenkin "attribute!\n", type); 6230986ab12SMaksim Yevmenkin } else 6240986ab12SMaksim Yevmenkin fprintf(stderr, "Invalid size=%d for Record " \ 6250986ab12SMaksim Yevmenkin "Handle attribute\n", 6260986ab12SMaksim Yevmenkin values[n].vlen); 6270986ab12SMaksim Yevmenkin break; 6280986ab12SMaksim Yevmenkin 6290986ab12SMaksim Yevmenkin case SDP_ATTR_SERVICE_CLASS_ID_LIST: 6300986ab12SMaksim Yevmenkin fprintf(stdout, "Service Class ID List:\n"); 6310986ab12SMaksim Yevmenkin print_service_class_id_list(values[n].value, 6320986ab12SMaksim Yevmenkin values[n].value + values[n].vlen); 6330986ab12SMaksim Yevmenkin break; 6340986ab12SMaksim Yevmenkin 6350986ab12SMaksim Yevmenkin case SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST: 6360986ab12SMaksim Yevmenkin fprintf(stdout, "Protocol Descriptor List:\n"); 6370986ab12SMaksim Yevmenkin print_protocol_descriptor_list(values[n].value, 6380986ab12SMaksim Yevmenkin values[n].value + values[n].vlen); 6390986ab12SMaksim Yevmenkin break; 6400986ab12SMaksim Yevmenkin 6410986ab12SMaksim Yevmenkin case SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST: 6420986ab12SMaksim Yevmenkin fprintf(stdout, "Bluetooth Profile Descriptor List:\n"); 6430986ab12SMaksim Yevmenkin print_bluetooth_profile_descriptor_list(values[n].value, 6440986ab12SMaksim Yevmenkin values[n].value + values[n].vlen); 6450986ab12SMaksim Yevmenkin break; 6460986ab12SMaksim Yevmenkin 6470986ab12SMaksim Yevmenkin default: 6480986ab12SMaksim Yevmenkin fprintf(stderr, "Unexpected attribute ID=%#4.4x\n", 6490986ab12SMaksim Yevmenkin values[n].attr); 6500986ab12SMaksim Yevmenkin break; 6510986ab12SMaksim Yevmenkin } 6520986ab12SMaksim Yevmenkin } 6530986ab12SMaksim Yevmenkin 6540986ab12SMaksim Yevmenkin return (OK); 6550986ab12SMaksim Yevmenkin } /* do_sdp_search */ 6560986ab12SMaksim Yevmenkin 6570986ab12SMaksim Yevmenkin /* Perform SDP browse command */ 6580986ab12SMaksim Yevmenkin static int 6590986ab12SMaksim Yevmenkin do_sdp_browse(void *xs, int argc, char **argv) 6600986ab12SMaksim Yevmenkin { 6610986ab12SMaksim Yevmenkin #undef _STR 6620986ab12SMaksim Yevmenkin #undef STR 6630986ab12SMaksim Yevmenkin #define _STR(x) #x 6640986ab12SMaksim Yevmenkin #define STR(x) _STR(x) 6650986ab12SMaksim Yevmenkin 6660986ab12SMaksim Yevmenkin static char const * const av[] = { 6670986ab12SMaksim Yevmenkin STR(SDP_SERVICE_CLASS_PUBLIC_BROWSE_GROUP), 6680986ab12SMaksim Yevmenkin NULL 6690986ab12SMaksim Yevmenkin }; 6700986ab12SMaksim Yevmenkin 6710986ab12SMaksim Yevmenkin switch (argc) { 6720986ab12SMaksim Yevmenkin case 0: 6730986ab12SMaksim Yevmenkin argc = 1; 6740986ab12SMaksim Yevmenkin argv = (char **) av; 6750986ab12SMaksim Yevmenkin /* FALL THROUGH */ 6760986ab12SMaksim Yevmenkin case 1: 6770986ab12SMaksim Yevmenkin return (do_sdp_search(xs, argc, argv)); 6780986ab12SMaksim Yevmenkin } 6790986ab12SMaksim Yevmenkin 6800986ab12SMaksim Yevmenkin return (USAGE); 6810986ab12SMaksim Yevmenkin } /* do_sdp_browse */ 6820986ab12SMaksim Yevmenkin 6830986ab12SMaksim Yevmenkin /* List of SDP commands */ 6840986ab12SMaksim Yevmenkin struct sdp_command sdp_commands[] = { 6850986ab12SMaksim Yevmenkin { 6860986ab12SMaksim Yevmenkin "Browse [<Group>]", 6870986ab12SMaksim Yevmenkin "Browse for services. The <Group> parameter is a 16-bit UUID of the group\n" \ 6880986ab12SMaksim Yevmenkin "to browse. If omitted <Group> is set to Public Browse Group.\n\n" \ 6890986ab12SMaksim Yevmenkin "\t<Group> - xxxx; 16-bit UUID of the group to browse\n", 6900986ab12SMaksim Yevmenkin do_sdp_browse 6910986ab12SMaksim Yevmenkin }, 6920986ab12SMaksim Yevmenkin { 6930986ab12SMaksim Yevmenkin "Search <Service>", 6940986ab12SMaksim Yevmenkin "Search for the <Service>. The <Service> parameter is a 16-bit UUID of the\n" \ 6950986ab12SMaksim Yevmenkin "service to search for. For some services it is possible to use service name\n"\ 6960986ab12SMaksim Yevmenkin "instead of service UUID\n\n" \ 6970986ab12SMaksim Yevmenkin "\t<Service> - xxxx; 16-bit UUID of the service to search for\n\n" \ 6980986ab12SMaksim Yevmenkin "\tKnown service names\n" \ 6990986ab12SMaksim Yevmenkin "\t===================\n" \ 7000986ab12SMaksim Yevmenkin "\tCIP - Common ISDN Access\n" \ 7010986ab12SMaksim Yevmenkin "\tCTP - Cordless Telephony\n" \ 7020986ab12SMaksim Yevmenkin "\tDUN - DialUp Networking\n" \ 7030986ab12SMaksim Yevmenkin "\tFAX - Fax\n" \ 7040986ab12SMaksim Yevmenkin "\tFTRN - OBEX File Transfer\n" \ 7050986ab12SMaksim Yevmenkin "\tGN - GN\n" \ 7060986ab12SMaksim Yevmenkin "\tHID - Human Interface Device\n" \ 7070986ab12SMaksim Yevmenkin "\tHSET - Headset\n" \ 7080986ab12SMaksim Yevmenkin "\tLAN - LAN Access Using PPP\n" \ 7090986ab12SMaksim Yevmenkin "\tNAP - Network Access Point\n" \ 7100986ab12SMaksim Yevmenkin "\tOPUSH - OBEX Object Push\n" \ 7110986ab12SMaksim Yevmenkin "\tSP - Serial Port\n", 7120986ab12SMaksim Yevmenkin do_sdp_search 7130986ab12SMaksim Yevmenkin }, 7140986ab12SMaksim Yevmenkin { NULL, NULL, NULL } 7150986ab12SMaksim Yevmenkin }; 7160986ab12SMaksim Yevmenkin 717