Home | History | Annotate | Download | only in tools
      1 /*
      2  *
      3  *  BlueZ - Bluetooth protocol stack for Linux
      4  *
      5  *  Copyright (C) 2001-2002  Nokia Corporation
      6  *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk (at) qualcomm.com>
      7  *  Copyright (C) 2002-2009  Marcel Holtmann <marcel (at) holtmann.org>
      8  *  Copyright (C) 2002-2003  Stephen Crane <steve.crane (at) rococosoft.com>
      9  *  Copyright (C) 2002-2003  Jean Tourrilhes <jt (at) hpl.hp.com>
     10  *
     11  *
     12  *  This program is free software; you can redistribute it and/or modify
     13  *  it under the terms of the GNU General Public License as published by
     14  *  the Free Software Foundation; either version 2 of the License, or
     15  *  (at your option) any later version.
     16  *
     17  *  This program is distributed in the hope that it will be useful,
     18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     20  *  GNU General Public License for more details.
     21  *
     22  *  You should have received a copy of the GNU General Public License
     23  *  along with this program; if not, write to the Free Software
     24  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     25  *
     26  */
     27 
     28 #ifdef HAVE_CONFIG_H
     29 #include <config.h>
     30 #endif
     31 
     32 #include <stdio.h>
     33 #include <errno.h>
     34 #include <ctype.h>
     35 #include <stdlib.h>
     36 #include <string.h>
     37 #include <getopt.h>
     38 #include <sys/socket.h>
     39 
     40 #include <bluetooth/bluetooth.h>
     41 #include <bluetooth/hci.h>
     42 #include <bluetooth/hci_lib.h>
     43 #include <bluetooth/sdp.h>
     44 #include <bluetooth/sdp_lib.h>
     45 
     46 #include <netinet/in.h>
     47 
     48 #include "sdp-xml.h"
     49 
     50 #ifndef APPLE_AGENT_SVCLASS_ID
     51 #define APPLE_AGENT_SVCLASS_ID 0x2112
     52 #endif
     53 
     54 #define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, 0)) != -1)
     55 
     56 /*
     57  * Convert a string to a BDADDR, with a few "enhancements" - Jean II
     58  */
     59 static int estr2ba(char *str, bdaddr_t *ba)
     60 {
     61 	/* Only trap "local", "any" is already dealt with */
     62 	if(!strcmp(str, "local")) {
     63 		bacpy(ba, BDADDR_LOCAL);
     64 		return 0;
     65 	}
     66 	return str2ba(str, ba);
     67 }
     68 
     69 #define DEFAULT_VIEW	0	/* Display only known attribute */
     70 #define TREE_VIEW	1	/* Display full attribute tree */
     71 #define RAW_VIEW	2	/* Display raw tree */
     72 #define XML_VIEW	3	/* Display xml tree */
     73 
     74 /* Pass args to the inquiry/search handler */
     75 struct search_context {
     76 	char		*svc;		/* Service */
     77 	uuid_t		group;		/* Browse group */
     78 	int		view;		/* View mode */
     79 	uint32_t	handle;		/* Service record handle */
     80 };
     81 
     82 typedef int (*handler_t)(bdaddr_t *bdaddr, struct search_context *arg);
     83 
     84 static char UUID_str[MAX_LEN_UUID_STR];
     85 static bdaddr_t interface;
     86 
     87 /* Definition of attribute members */
     88 struct member_def {
     89 	char *name;
     90 };
     91 
     92 /* Definition of an attribute */
     93 struct attrib_def {
     94 	int			num;		/* Numeric ID - 16 bits */
     95 	char			*name;		/* User readable name */
     96 	struct member_def	*members;	/* Definition of attribute args */
     97 	int			member_max;	/* Max of attribute arg definitions */
     98 };
     99 
    100 /* Definition of a service or protocol */
    101 struct uuid_def {
    102 	int			num;		/* Numeric ID - 16 bits */
    103 	char			*name;		/* User readable name */
    104 	struct attrib_def	*attribs;	/* Specific attribute definitions */
    105 	int			attrib_max;	/* Max of attribute definitions */
    106 };
    107 
    108 /* Context information about current attribute */
    109 struct attrib_context {
    110 	struct uuid_def		*service;	/* Service UUID, if known */
    111 	struct attrib_def	*attrib;	/* Description of the attribute */
    112 	int			member_index;	/* Index of current attribute member */
    113 };
    114 
    115 /* Context information about the whole service */
    116 struct service_context {
    117 	struct uuid_def		*service;	/* Service UUID, if known */
    118 };
    119 
    120 /* Allow us to do nice formatting of the lists */
    121 static char *indent_spaces = "                                         ";
    122 
    123 /* ID of the service attribute.
    124  * Most attributes after 0x200 are defined based on the service, so
    125  * we need to find what is the service (which is messy) - Jean II */
    126 #define SERVICE_ATTR	0x1
    127 
    128 /* Definition of the optional arguments in protocol list */
    129 static struct member_def protocol_members[] = {
    130 	{ "Protocol"		},
    131 	{ "Channel/Port"	},
    132 	{ "Version"		},
    133 };
    134 
    135 /* Definition of the optional arguments in profile list */
    136 static struct member_def profile_members[] = {
    137 	{ "Profile"	},
    138 	{ "Version"	},
    139 };
    140 
    141 /* Definition of the optional arguments in Language list */
    142 static struct member_def language_members[] = {
    143 	{ "Code ISO639"		},
    144 	{ "Encoding"		},
    145 	{ "Base Offset"		},
    146 };
    147 
    148 /* Name of the various common attributes. See BT assigned numbers */
    149 static struct attrib_def attrib_names[] = {
    150 	{ 0x0, "ServiceRecordHandle", NULL, 0 },
    151 	{ 0x1, "ServiceClassIDList", NULL, 0 },
    152 	{ 0x2, "ServiceRecordState", NULL, 0 },
    153 	{ 0x3, "ServiceID", NULL, 0 },
    154 	{ 0x4, "ProtocolDescriptorList",
    155 		protocol_members, sizeof(protocol_members)/sizeof(struct member_def) },
    156 	{ 0x5, "BrowseGroupList", NULL, 0 },
    157 	{ 0x6, "LanguageBaseAttributeIDList",
    158 		language_members, sizeof(language_members)/sizeof(struct member_def) },
    159 	{ 0x7, "ServiceInfoTimeToLive", NULL, 0 },
    160 	{ 0x8, "ServiceAvailability", NULL, 0 },
    161 	{ 0x9, "BluetoothProfileDescriptorList",
    162 		profile_members, sizeof(profile_members)/sizeof(struct member_def) },
    163 	{ 0xA, "DocumentationURL", NULL, 0 },
    164 	{ 0xB, "ClientExecutableURL", NULL, 0 },
    165 	{ 0xC, "IconURL", NULL, 0 },
    166 	{ 0xD, "AdditionalProtocolDescriptorLists", NULL, 0 },
    167 	/* Definitions after that are tricky (per profile or offset) */
    168 };
    169 
    170 const int attrib_max = sizeof(attrib_names)/sizeof(struct attrib_def);
    171 
    172 /* Name of the various SPD attributes. See BT assigned numbers */
    173 static struct attrib_def sdp_attrib_names[] = {
    174 	{ 0x200, "VersionNumberList", NULL, 0 },
    175 	{ 0x201, "ServiceDatabaseState", NULL, 0 },
    176 };
    177 
    178 /* Name of the various SPD attributes. See BT assigned numbers */
    179 static struct attrib_def browse_attrib_names[] = {
    180 	{ 0x200, "GroupID", NULL, 0 },
    181 };
    182 
    183 /* Name of the various Device ID attributes. See Device Id spec. */
    184 static struct attrib_def did_attrib_names[] = {
    185 	{ 0x200, "SpecificationID", NULL, 0 },
    186 	{ 0x201, "VendorID", NULL, 0 },
    187 	{ 0x202, "ProductID", NULL, 0 },
    188 	{ 0x203, "Version", NULL, 0 },
    189 	{ 0x204, "PrimaryRecord", NULL, 0 },
    190 	{ 0x205, "VendorIDSource", NULL, 0 },
    191 };
    192 
    193 /* Name of the various HID attributes. See HID spec. */
    194 static struct attrib_def hid_attrib_names[] = {
    195 	{ 0x200, "DeviceReleaseNum", NULL, 0 },
    196 	{ 0x201, "ParserVersion", NULL, 0 },
    197 	{ 0x202, "DeviceSubclass", NULL, 0 },
    198 	{ 0x203, "CountryCode", NULL, 0 },
    199 	{ 0x204, "VirtualCable", NULL, 0 },
    200 	{ 0x205, "ReconnectInitiate", NULL, 0 },
    201 	{ 0x206, "DescriptorList", NULL, 0 },
    202 	{ 0x207, "LangIDBaseList", NULL, 0 },
    203 	{ 0x208, "SDPDisable", NULL, 0 },
    204 	{ 0x209, "BatteryPower", NULL, 0 },
    205 	{ 0x20a, "RemoteWakeup", NULL, 0 },
    206 	{ 0x20b, "ProfileVersion", NULL, 0 },
    207 	{ 0x20c, "SupervisionTimeout", NULL, 0 },
    208 	{ 0x20d, "NormallyConnectable", NULL, 0 },
    209 	{ 0x20e, "BootDevice", NULL, 0 },
    210 };
    211 
    212 /* Name of the various PAN attributes. See BT assigned numbers */
    213 /* Note : those need to be double checked - Jean II */
    214 static struct attrib_def pan_attrib_names[] = {
    215 	{ 0x200, "IpSubnet", NULL, 0 },		/* Obsolete ??? */
    216 	{ 0x30A, "SecurityDescription", NULL, 0 },
    217 	{ 0x30B, "NetAccessType", NULL, 0 },
    218 	{ 0x30C, "MaxNetAccessrate", NULL, 0 },
    219 	{ 0x30D, "IPv4Subnet", NULL, 0 },
    220 	{ 0x30E, "IPv6Subnet", NULL, 0 },
    221 };
    222 
    223 /* Name of the various Generic-Audio attributes. See BT assigned numbers */
    224 /* Note : totally untested - Jean II */
    225 static struct attrib_def audio_attrib_names[] = {
    226 	{ 0x302, "Remote audio volume control", NULL, 0 },
    227 };
    228 
    229 /* Same for the UUIDs. See BT assigned numbers */
    230 static struct uuid_def uuid16_names[] = {
    231 	/* -- Protocols -- */
    232 	{ 0x0001, "SDP", NULL, 0 },
    233 	{ 0x0002, "UDP", NULL, 0 },
    234 	{ 0x0003, "RFCOMM", NULL, 0 },
    235 	{ 0x0004, "TCP", NULL, 0 },
    236 	{ 0x0005, "TCS-BIN", NULL, 0 },
    237 	{ 0x0006, "TCS-AT", NULL, 0 },
    238 	{ 0x0008, "OBEX", NULL, 0 },
    239 	{ 0x0009, "IP", NULL, 0 },
    240 	{ 0x000a, "FTP", NULL, 0 },
    241 	{ 0x000c, "HTTP", NULL, 0 },
    242 	{ 0x000e, "WSP", NULL, 0 },
    243 	{ 0x000f, "BNEP", NULL, 0 },
    244 	{ 0x0010, "UPnP/ESDP", NULL, 0 },
    245 	{ 0x0011, "HIDP", NULL, 0 },
    246 	{ 0x0012, "HardcopyControlChannel", NULL, 0 },
    247 	{ 0x0014, "HardcopyDataChannel", NULL, 0 },
    248 	{ 0x0016, "HardcopyNotification", NULL, 0 },
    249 	{ 0x0017, "AVCTP", NULL, 0 },
    250 	{ 0x0019, "AVDTP", NULL, 0 },
    251 	{ 0x001b, "CMTP", NULL, 0 },
    252 	{ 0x001d, "UDI_C-Plane", NULL, 0 },
    253 	{ 0x0100, "L2CAP", NULL, 0 },
    254 	/* -- Services -- */
    255 	{ 0x1000, "ServiceDiscoveryServerServiceClassID",
    256 		sdp_attrib_names, sizeof(sdp_attrib_names)/sizeof(struct attrib_def) },
    257 	{ 0x1001, "BrowseGroupDescriptorServiceClassID",
    258 		browse_attrib_names, sizeof(browse_attrib_names)/sizeof(struct attrib_def) },
    259 	{ 0x1002, "PublicBrowseGroup", NULL, 0 },
    260 	{ 0x1101, "SerialPort", NULL, 0 },
    261 	{ 0x1102, "LANAccessUsingPPP", NULL, 0 },
    262 	{ 0x1103, "DialupNetworking (DUN)", NULL, 0 },
    263 	{ 0x1104, "IrMCSync", NULL, 0 },
    264 	{ 0x1105, "OBEXObjectPush", NULL, 0 },
    265 	{ 0x1106, "OBEXFileTransfer", NULL, 0 },
    266 	{ 0x1107, "IrMCSyncCommand", NULL, 0 },
    267 	{ 0x1108, "Headset",
    268 		audio_attrib_names, sizeof(audio_attrib_names)/sizeof(struct attrib_def) },
    269 	{ 0x1109, "CordlessTelephony", NULL, 0 },
    270 	{ 0x110a, "AudioSource", NULL, 0 },
    271 	{ 0x110b, "AudioSink", NULL, 0 },
    272 	{ 0x110c, "RemoteControlTarget", NULL, 0 },
    273 	{ 0x110d, "AdvancedAudio", NULL, 0 },
    274 	{ 0x110e, "RemoteControl", NULL, 0 },
    275 	{ 0x110f, "VideoConferencing", NULL, 0 },
    276 	{ 0x1110, "Intercom", NULL, 0 },
    277 	{ 0x1111, "Fax", NULL, 0 },
    278 	{ 0x1112, "HeadsetAudioGateway", NULL, 0 },
    279 	{ 0x1113, "WAP", NULL, 0 },
    280 	{ 0x1114, "WAP Client", NULL, 0 },
    281 	{ 0x1115, "PANU (PAN/BNEP)",
    282 		pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) },
    283 	{ 0x1116, "NAP (PAN/BNEP)",
    284 		pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) },
    285 	{ 0x1117, "GN (PAN/BNEP)",
    286 		pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) },
    287 	{ 0x1118, "DirectPrinting (BPP)", NULL, 0 },
    288 	{ 0x1119, "ReferencePrinting (BPP)", NULL, 0 },
    289 	{ 0x111a, "Imaging (BIP)", NULL, 0 },
    290 	{ 0x111b, "ImagingResponder (BIP)", NULL, 0 },
    291 	{ 0x111c, "ImagingAutomaticArchive (BIP)", NULL, 0 },
    292 	{ 0x111d, "ImagingReferencedObjects (BIP)", NULL, 0 },
    293 	{ 0x111e, "Handsfree", NULL, 0 },
    294 	{ 0x111f, "HandsfreeAudioGateway", NULL, 0 },
    295 	{ 0x1120, "DirectPrintingReferenceObjectsService (BPP)", NULL, 0 },
    296 	{ 0x1121, "ReflectedUI (BPP)", NULL, 0 },
    297 	{ 0x1122, "BasicPrinting (BPP)", NULL, 0 },
    298 	{ 0x1123, "PrintingStatus (BPP)", NULL, 0 },
    299 	{ 0x1124, "HumanInterfaceDeviceService (HID)",
    300 		hid_attrib_names, sizeof(hid_attrib_names)/sizeof(struct attrib_def) },
    301 	{ 0x1125, "HardcopyCableReplacement (HCR)", NULL, 0 },
    302 	{ 0x1126, "HCR_Print (HCR)", NULL, 0 },
    303 	{ 0x1127, "HCR_Scan (HCR)", NULL, 0 },
    304 	{ 0x1128, "Common ISDN Access (CIP)", NULL, 0 },
    305 	{ 0x1129, "VideoConferencingGW (VCP)", NULL, 0 },
    306 	{ 0x112a, "UDI-MT", NULL, 0 },
    307 	{ 0x112b, "UDI-TA", NULL, 0 },
    308 	{ 0x112c, "Audio/Video", NULL, 0 },
    309 	{ 0x112d, "SIM Access (SAP)", NULL, 0 },
    310 	{ 0x112e, "Phonebook Access (PBAP) - PCE", NULL, 0 },
    311 	{ 0x112f, "Phonebook Access (PBAP) - PSE", NULL, 0 },
    312 	{ 0x1130, "Phonebook Access (PBAP)", NULL, 0 },
    313 	/* ... */
    314 	{ 0x1200, "PnPInformation",
    315 		did_attrib_names, sizeof(did_attrib_names)/sizeof(struct attrib_def) },
    316 	{ 0x1201, "GenericNetworking", NULL, 0 },
    317 	{ 0x1202, "GenericFileTransfer", NULL, 0 },
    318 	{ 0x1203, "GenericAudio",
    319 		audio_attrib_names, sizeof(audio_attrib_names)/sizeof(struct attrib_def) },
    320 	{ 0x1204, "GenericTelephony", NULL, 0 },
    321 	/* ... */
    322 	{ 0x1303, "VideoSource", NULL, 0 },
    323 	{ 0x1304, "VideoSink", NULL, 0 },
    324 	{ 0x1305, "VideoDistribution", NULL, 0 },
    325 	{ 0x1400, "MDP", NULL, 0 },
    326 	{ 0x1401, "MDPSource", NULL, 0 },
    327 	{ 0x1402, "MDPSink", NULL, 0 },
    328 	{ 0x2112, "AppleAgent", NULL, 0 },
    329 };
    330 
    331 static const int uuid16_max = sizeof(uuid16_names)/sizeof(struct uuid_def);
    332 
    333 static void sdp_data_printf(sdp_data_t *, struct attrib_context *, int);
    334 
    335 /*
    336  * Parse a UUID.
    337  * The BT assigned numbers only list UUID16, so I'm not sure the
    338  * other types will ever get used...
    339  */
    340 static void sdp_uuid_printf(uuid_t *uuid, struct attrib_context *context, int indent)
    341 {
    342 	if (uuid) {
    343 		if (uuid->type == SDP_UUID16) {
    344 			uint16_t uuidNum = uuid->value.uuid16;
    345 			struct uuid_def *uuidDef = NULL;
    346 			int i;
    347 
    348 			for (i = 0; i < uuid16_max; i++)
    349 				if (uuid16_names[i].num == uuidNum) {
    350 					uuidDef = &uuid16_names[i];
    351 					break;
    352 				}
    353 
    354 			/* Check if it's the service attribute */
    355 			if (context->attrib && context->attrib->num == SERVICE_ATTR) {
    356 				/* We got the service ID !!! */
    357 				context->service = uuidDef;
    358 			}
    359 
    360 			if (uuidDef)
    361 				printf("%.*sUUID16 : 0x%.4x - %s\n",
    362 					indent, indent_spaces, uuidNum, uuidDef->name);
    363 			else
    364 				printf("%.*sUUID16 : 0x%.4x\n",
    365 					indent, indent_spaces, uuidNum);
    366 		} else if (uuid->type == SDP_UUID32) {
    367 			struct uuid_def *uuidDef = NULL;
    368 			int i;
    369 
    370 			if (!(uuid->value.uuid32 & 0xffff0000)) {
    371 				uint16_t uuidNum = uuid->value.uuid32;
    372 				for (i = 0; i < uuid16_max; i++)
    373 					if (uuid16_names[i].num == uuidNum) {
    374 						uuidDef = &uuid16_names[i];
    375 						break;
    376 					}
    377 			}
    378 
    379 			if (uuidDef)
    380 				printf("%.*sUUID32 : 0x%.8x - %s\n",
    381 					indent, indent_spaces, uuid->value.uuid32, uuidDef->name);
    382 			else
    383 				printf("%.*sUUID32 : 0x%.8x\n",
    384 					indent, indent_spaces, uuid->value.uuid32);
    385 		} else if (uuid->type == SDP_UUID128) {
    386 			unsigned int data0;
    387 			unsigned short data1;
    388 			unsigned short data2;
    389 			unsigned short data3;
    390 			unsigned int data4;
    391 			unsigned short data5;
    392 
    393 			memcpy(&data0, &uuid->value.uuid128.data[0], 4);
    394 			memcpy(&data1, &uuid->value.uuid128.data[4], 2);
    395 			memcpy(&data2, &uuid->value.uuid128.data[6], 2);
    396 			memcpy(&data3, &uuid->value.uuid128.data[8], 2);
    397 			memcpy(&data4, &uuid->value.uuid128.data[10], 4);
    398 			memcpy(&data5, &uuid->value.uuid128.data[14], 2);
    399 
    400 			printf("%.*sUUID128 : 0x%.8x-%.4x-%.4x-%.4x-%.8x-%.4x\n",
    401 				indent, indent_spaces,
    402 				ntohl(data0), ntohs(data1), ntohs(data2),
    403 				ntohs(data3), ntohl(data4), ntohs(data5));
    404 		} else
    405 			printf("%.*sEnum type of UUID not set\n",
    406 				indent, indent_spaces);
    407 	} else
    408 		printf("%.*sNull passed to print UUID\n",
    409 				indent, indent_spaces);
    410 }
    411 
    412 /*
    413  * Parse a sequence of data elements (i.e. a list)
    414  */
    415 static void printf_dataseq(sdp_data_t * pData, struct attrib_context *context, int indent)
    416 {
    417 	sdp_data_t *sdpdata = NULL;
    418 
    419 	sdpdata = pData;
    420 	if (sdpdata) {
    421 		context->member_index = 0;
    422 		do {
    423 			sdp_data_printf(sdpdata, context, indent + 2);
    424 			sdpdata = sdpdata->next;
    425 			context->member_index++;
    426 		} while (sdpdata);
    427 	} else {
    428 		printf("%.*sBroken dataseq link\n", indent, indent_spaces);
    429 	}
    430 }
    431 
    432 /*
    433  * Parse a single data element (either in the attribute or in a data
    434  * sequence).
    435  */
    436 static void sdp_data_printf(sdp_data_t *sdpdata, struct attrib_context *context, int indent)
    437 {
    438 	char *member_name = NULL;
    439 
    440 	/* Find member name. Almost black magic ;-) */
    441 	if (context && context->attrib && context->attrib->members &&
    442 			context->member_index < context->attrib->member_max) {
    443 		member_name = context->attrib->members[context->member_index].name;
    444 	}
    445 
    446 	switch (sdpdata->dtd) {
    447 	case SDP_DATA_NIL:
    448 		printf("%.*sNil\n", indent, indent_spaces);
    449 		break;
    450 	case SDP_BOOL:
    451 	case SDP_UINT8:
    452 	case SDP_UINT16:
    453 	case SDP_UINT32:
    454 	case SDP_UINT64:
    455 	case SDP_UINT128:
    456 	case SDP_INT8:
    457 	case SDP_INT16:
    458 	case SDP_INT32:
    459 	case SDP_INT64:
    460 	case SDP_INT128:
    461 		if (member_name) {
    462 			printf("%.*s%s (Integer) : 0x%x\n",
    463 				indent, indent_spaces, member_name, sdpdata->val.uint32);
    464 		} else {
    465 			printf("%.*sInteger : 0x%x\n", indent, indent_spaces,
    466 				sdpdata->val.uint32);
    467 		}
    468 		break;
    469 
    470 	case SDP_UUID16:
    471 	case SDP_UUID32:
    472 	case SDP_UUID128:
    473 		//printf("%.*sUUID\n", indent, indent_spaces);
    474 		sdp_uuid_printf(&sdpdata->val.uuid, context, indent);
    475 		break;
    476 
    477 	case SDP_TEXT_STR8:
    478 	case SDP_TEXT_STR16:
    479 	case SDP_TEXT_STR32:
    480 		if (sdpdata->unitSize > (int) strlen(sdpdata->val.str)) {
    481 			int i;
    482 			printf("%.*sData :", indent, indent_spaces);
    483 			for (i = 0; i < sdpdata->unitSize; i++)
    484 				printf(" %02x", (unsigned char) sdpdata->val.str[i]);
    485 			printf("\n");
    486 		} else
    487 			printf("%.*sText : \"%s\"\n", indent, indent_spaces, sdpdata->val.str);
    488 		break;
    489 	case SDP_URL_STR8:
    490 	case SDP_URL_STR16:
    491 	case SDP_URL_STR32:
    492 		printf("%.*sURL : %s\n", indent, indent_spaces, sdpdata->val.str);
    493 		break;
    494 
    495 	case SDP_SEQ8:
    496 	case SDP_SEQ16:
    497 	case SDP_SEQ32:
    498 		printf("%.*sData Sequence\n", indent, indent_spaces);
    499 		printf_dataseq(sdpdata->val.dataseq, context, indent);
    500 		break;
    501 
    502 	case SDP_ALT8:
    503 	case SDP_ALT16:
    504 	case SDP_ALT32:
    505 		printf("%.*sData Sequence Alternates\n", indent, indent_spaces);
    506 		printf_dataseq(sdpdata->val.dataseq, context, indent);
    507 		break;
    508 	}
    509 }
    510 
    511 /*
    512  * Parse a single attribute.
    513  */
    514 static void print_tree_attr_func(void *value, void *userData)
    515 {
    516 	sdp_data_t *sdpdata = NULL;
    517 	uint16_t attrId;
    518 	struct service_context *service = (struct service_context *) userData;
    519 	struct attrib_context context;
    520 	struct attrib_def *attrDef = NULL;
    521 	int i;
    522 
    523 	sdpdata = (sdp_data_t *)value;
    524 	attrId = sdpdata->attrId;
    525 	/* Search amongst the generic attributes */
    526 	for (i = 0; i < attrib_max; i++)
    527 		if (attrib_names[i].num == attrId) {
    528 			attrDef = &attrib_names[i];
    529 			break;
    530 		}
    531 	/* Search amongst the specific attributes of this service */
    532 	if ((attrDef == NULL) && (service->service != NULL) &&
    533 				(service->service->attribs != NULL)) {
    534 		struct attrib_def *svc_attribs = service->service->attribs;
    535 		int		svc_attrib_max = service->service->attrib_max;
    536 		for (i = 0; i < svc_attrib_max; i++)
    537 			if (svc_attribs[i].num == attrId) {
    538 				attrDef = &svc_attribs[i];
    539 				break;
    540 			}
    541 	}
    542 
    543 	if (attrDef)
    544 		printf("Attribute Identifier : 0x%x - %s\n", attrId, attrDef->name);
    545 	else
    546 		printf("Attribute Identifier : 0x%x\n", attrId);
    547 	/* Build context */
    548 	context.service = service->service;
    549 	context.attrib = attrDef;
    550 	context.member_index = 0;
    551 	/* Parse attribute members */
    552 	if (sdpdata)
    553 		sdp_data_printf(sdpdata, &context, 2);
    554 	else
    555 		printf("  NULL value\n");
    556 	/* Update service */
    557 	service->service = context.service;
    558 }
    559 
    560 /*
    561  * Main entry point of this library. Parse a SDP record.
    562  * We assume the record has already been read, parsed and cached
    563  * locally. Jean II
    564  */
    565 static void print_tree_attr(sdp_record_t *rec)
    566 {
    567 	if (rec && rec->attrlist) {
    568 		struct service_context service = { NULL };
    569 		sdp_list_foreach(rec->attrlist, print_tree_attr_func, &service);
    570 	}
    571 }
    572 
    573 static void print_raw_data(sdp_data_t *data, int indent)
    574 {
    575 	struct uuid_def *def;
    576 	int i, hex;
    577 
    578 	if (!data)
    579 		return;
    580 
    581 	for (i = 0; i < indent; i++)
    582 		printf("\t");
    583 
    584 	switch (data->dtd) {
    585 	case SDP_DATA_NIL:
    586 		printf("NIL\n");
    587 		break;
    588 	case SDP_BOOL:
    589 		printf("Bool %s\n", data->val.uint8 ? "True" : "False");
    590 		break;
    591 	case SDP_UINT8:
    592 		printf("UINT8 0x%02x\n", data->val.uint8);
    593 		break;
    594 	case SDP_UINT16:
    595 		printf("UINT16 0x%04x\n", data->val.uint16);
    596 		break;
    597 	case SDP_UINT32:
    598 		printf("UINT32 0x%08x\n", data->val.uint32);
    599 		break;
    600 	case SDP_UINT64:
    601 		printf("UINT64 0x%016jx\n", data->val.uint64);
    602 		break;
    603 	case SDP_UINT128:
    604 		printf("UINT128 ...\n");
    605 		break;
    606 	case SDP_INT8:
    607 		printf("INT8 %d\n", data->val.int8);
    608 		break;
    609 	case SDP_INT16:
    610 		printf("INT16 %d\n", data->val.int16);
    611 		break;
    612 	case SDP_INT32:
    613 		printf("INT32 %d\n", data->val.int32);
    614 		break;
    615 	case SDP_INT64:
    616 		printf("INT64 %jd\n", data->val.int64);
    617 		break;
    618 	case SDP_INT128:
    619 		printf("INT128 ...\n");
    620 		break;
    621 	case SDP_UUID16:
    622 	case SDP_UUID32:
    623 	case SDP_UUID128:
    624 		switch (data->val.uuid.type) {
    625 		case SDP_UUID16:
    626 			def = NULL;
    627 			for (i = 0; i < uuid16_max; i++)
    628 				if (uuid16_names[i].num == data->val.uuid.value.uuid16) {
    629 					def = &uuid16_names[i];
    630 					break;
    631 				}
    632 			if (def)
    633 				printf("UUID16 0x%04x - %s\n", data->val.uuid.value.uuid16, def->name);
    634 			else
    635 				printf("UUID16 0x%04x\n", data->val.uuid.value.uuid16);
    636 			break;
    637 		case SDP_UUID32:
    638 			def = NULL;
    639 			if (!(data->val.uuid.value.uuid32 & 0xffff0000)) {
    640 				uint16_t value = data->val.uuid.value.uuid32;
    641 				for (i = 0; i < uuid16_max; i++)
    642 					if (uuid16_names[i].num == value) {
    643 						def = &uuid16_names[i];
    644 						break;
    645 					}
    646 			}
    647 			if (def)
    648 				printf("UUID32 0x%08x - %s\n", data->val.uuid.value.uuid32, def->name);
    649 			else
    650 				printf("UUID32 0x%08x\n", data->val.uuid.value.uuid32);
    651 			break;
    652 		case SDP_UUID128:
    653 			printf("UUID128 ");
    654 			for (i = 0; i < 16; i++) {
    655 				switch (i) {
    656 				case 4:
    657 				case 6:
    658 				case 8:
    659 				case 10:
    660 					printf("-");
    661 					break;
    662 				}
    663 				printf("%02x", (unsigned char ) data->val.uuid.value.uuid128.data[i]);
    664 			}
    665 			printf("\n");
    666 			break;
    667 		default:
    668 			printf("UUID type 0x%02x\n", data->val.uuid.type);
    669 			break;
    670 		}
    671 		break;
    672 	case SDP_TEXT_STR8:
    673 	case SDP_TEXT_STR16:
    674 	case SDP_TEXT_STR32:
    675 		hex = 0;
    676 		for (i = 0; i < data->unitSize; i++) {
    677 			if (i == (data->unitSize - 1) && data->val.str[i] == '\0')
    678 				break;
    679 			if (!isprint(data->val.str[i])) {
    680 				hex = 1;
    681 				break;
    682 			}
    683 		}
    684 		if (hex) {
    685 			printf("Data");
    686 			for (i = 0; i < data->unitSize; i++)
    687 				printf(" %02x", (unsigned char) data->val.str[i]);
    688 		} else {
    689 			printf("String ");
    690 			for (i = 0; i < data->unitSize; i++)
    691 				printf("%c", data->val.str[i]);
    692 		}
    693 		printf("\n");
    694 		break;
    695 	case SDP_URL_STR8:
    696 	case SDP_URL_STR16:
    697 	case SDP_URL_STR32:
    698 		printf("URL %s\n", data->val.str);
    699 		break;
    700 	case SDP_SEQ8:
    701 	case SDP_SEQ16:
    702 	case SDP_SEQ32:
    703 		printf("Sequence\n");
    704 		print_raw_data(data->val.dataseq, indent + 1);
    705 		break;
    706 	case SDP_ALT8:
    707 	case SDP_ALT16:
    708 	case SDP_ALT32:
    709 		printf("Alternate\n");
    710 		print_raw_data(data->val.dataseq, indent + 1);
    711 		break;
    712 	default:
    713 		printf("Unknown type 0x%02x\n", data->dtd);
    714 		break;
    715 	}
    716 
    717 	print_raw_data(data->next, indent);
    718 }
    719 
    720 static void print_raw_attr_func(void *value, void *userData)
    721 {
    722 	sdp_data_t *data = (sdp_data_t *) value;
    723 	struct attrib_def *def = NULL;
    724 	int i;
    725 
    726 	/* Search amongst the generic attributes */
    727 	for (i = 0; i < attrib_max; i++)
    728 		if (attrib_names[i].num == data->attrId) {
    729 			def = &attrib_names[i];
    730 			break;
    731 		}
    732 
    733 	if (def)
    734 		printf("\tAttribute 0x%04x - %s\n", data->attrId, def->name);
    735 	else
    736 		printf("\tAttribute 0x%04x\n", data->attrId);
    737 
    738 	if (data)
    739 		print_raw_data(data, 2);
    740 	else
    741 		printf("  NULL value\n");
    742 }
    743 
    744 static void print_raw_attr(sdp_record_t *rec)
    745 {
    746 	if (rec && rec->attrlist) {
    747 		printf("Sequence\n");
    748 		sdp_list_foreach(rec->attrlist, print_raw_attr_func, 0);
    749 	}
    750 }
    751 
    752 /*
    753  * Set attributes with single values in SDP record
    754  * Jean II
    755  */
    756 static int set_attrib(sdp_session_t *sess, uint32_t handle, uint16_t attrib, char *value)
    757 {
    758 	sdp_list_t *attrid_list;
    759 	uint32_t range = 0x0000ffff;
    760 	sdp_record_t *rec;
    761 	int ret;
    762 
    763 	/* Get the old SDP record */
    764 	attrid_list = sdp_list_append(NULL, &range);
    765 	rec = sdp_service_attr_req(sess, handle, SDP_ATTR_REQ_RANGE, attrid_list);
    766 	sdp_list_free(attrid_list, NULL);
    767 
    768 	if (!rec) {
    769 		printf("Service get request failed.\n");
    770 		return -1;
    771 	}
    772 
    773 	/* Check the type of attribute */
    774 	if (!strncasecmp(value, "u0x", 3)) {
    775 		/* UUID16 */
    776 		uint16_t value_int = 0;
    777 		uuid_t value_uuid;
    778 		value_int = strtoul(value + 3, NULL, 16);
    779 		sdp_uuid16_create(&value_uuid, value_int);
    780 		printf("Adding attrib 0x%X uuid16 0x%X to record 0x%X\n",
    781 			attrib, value_int, handle);
    782 
    783 		sdp_attr_add_new(rec, attrib, SDP_UUID16, &value_uuid.value.uuid16);
    784 	} else if (!strncasecmp(value, "0x", 2)) {
    785 		/* Int */
    786 		uint32_t value_int;
    787 		value_int = strtoul(value + 2, NULL, 16);
    788 		printf("Adding attrib 0x%X int 0x%X to record 0x%X\n",
    789 			attrib, value_int, handle);
    790 
    791 		sdp_attr_add_new(rec, attrib, SDP_UINT32, &value_int);
    792 	} else {
    793 		/* String */
    794 		printf("Adding attrib 0x%X string \"%s\" to record 0x%X\n",
    795 			attrib, value, handle);
    796 
    797 		/* Add/Update our attribute to the record */
    798 		sdp_attr_add_new(rec, attrib, SDP_TEXT_STR8, value);
    799 	}
    800 
    801 	/* Update on the server */
    802 	ret = sdp_device_record_update(sess, &interface, rec);
    803 	if (ret < 0)
    804 		printf("Service Record update failed (%d).\n", errno);
    805 	sdp_record_free(rec);
    806 	return ret;
    807 }
    808 
    809 static struct option set_options[] = {
    810 	{ "help",	0, 0, 'h' },
    811 	{ 0, 0, 0, 0 }
    812 };
    813 
    814 static const char *set_help =
    815 	"Usage:\n"
    816 	"\tget record_handle attrib_id attrib_value\n";
    817 
    818 /*
    819  * Add an attribute to an existing SDP record on the local SDP server
    820  */
    821 static int cmd_setattr(int argc, char **argv)
    822 {
    823 	int opt, status;
    824 	uint32_t handle;
    825 	uint16_t attrib;
    826 	sdp_session_t *sess;
    827 
    828 	for_each_opt(opt, set_options, NULL) {
    829 		switch(opt) {
    830 		default:
    831 			printf("%s", set_help);
    832 			return -1;
    833 		}
    834 	}
    835 
    836 	argc -= optind;
    837 	argv += optind;
    838 
    839 	if (argc < 3) {
    840 		printf("%s", set_help);
    841 		return -1;
    842 	}
    843 
    844 	/* Convert command line args */
    845 	handle = strtoul(argv[0], NULL, 16);
    846 	attrib = strtoul(argv[1], NULL, 16);
    847 
    848 	/* Do it */
    849 	sess = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, 0);
    850 	if (!sess)
    851 		return -1;
    852 
    853 	status = set_attrib(sess, handle, attrib, argv[2]);
    854 	sdp_close(sess);
    855 
    856 	return status;
    857 }
    858 
    859 /*
    860  * We do only simple data sequences. Sequence of sequences is a pain ;-)
    861  * Jean II
    862  */
    863 static int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attrib, int argc, char **argv)
    864 {
    865 	sdp_list_t *attrid_list;
    866 	uint32_t range = 0x0000ffff;
    867 	sdp_record_t *rec;
    868 	sdp_data_t *pSequenceHolder = NULL;
    869 	void **dtdArray;
    870 	void **valueArray;
    871 	void **allocArray;
    872 	uint8_t uuid16 = SDP_UUID16;
    873 	uint8_t uint32 = SDP_UINT32;
    874 	uint8_t str8 = SDP_TEXT_STR8;
    875 	int i, ret = 0;
    876 
    877 	/* Get the old SDP record */
    878 	attrid_list = sdp_list_append(NULL, &range);
    879 	rec = sdp_service_attr_req(session, handle, SDP_ATTR_REQ_RANGE, attrid_list);
    880 	sdp_list_free(attrid_list, NULL);
    881 
    882 	if (!rec) {
    883 		printf("Service get request failed.\n");
    884 		return -1;
    885 	}
    886 
    887 	/* Create arrays */
    888 	dtdArray = (void **)malloc(argc * sizeof(void *));
    889 	valueArray = (void **)malloc(argc * sizeof(void *));
    890 	allocArray = (void **)malloc(argc * sizeof(void *));
    891 
    892 	/* Loop on all args, add them in arrays */
    893 	for (i = 0; i < argc; i++) {
    894 		/* Check the type of attribute */
    895 		if (!strncasecmp(argv[i], "u0x", 3)) {
    896 			/* UUID16 */
    897 			uint16_t value_int = strtoul((argv[i]) + 3, NULL, 16);
    898 			uuid_t *value_uuid = (uuid_t *) malloc(sizeof(uuid_t));
    899 			allocArray[i] = value_uuid;
    900 			sdp_uuid16_create(value_uuid, value_int);
    901 
    902 			printf("Adding uuid16 0x%X to record 0x%X\n", value_int, handle);
    903 			dtdArray[i] = &uuid16;
    904 			valueArray[i] = &value_uuid->value.uuid16;
    905 		} else if (!strncasecmp(argv[i], "0x", 2)) {
    906 			/* Int */
    907 			uint32_t *value_int = (uint32_t *) malloc(sizeof(int));
    908 			allocArray[i] = value_int;
    909 			*value_int = strtoul((argv[i]) + 2, NULL, 16);
    910 
    911 			printf("Adding int 0x%X to record 0x%X\n", *value_int, handle);
    912 			dtdArray[i] = &uint32;
    913 			valueArray[i] = value_int;
    914 		} else {
    915 			/* String */
    916 			printf("Adding string \"%s\" to record 0x%X\n", argv[i], handle);
    917 			dtdArray[i] = &str8;
    918 			valueArray[i] = argv[i];
    919 		}
    920 	}
    921 
    922 	/* Add this sequence to the attrib list */
    923 	pSequenceHolder = sdp_seq_alloc(dtdArray, valueArray, argc);
    924 	if (pSequenceHolder) {
    925 		sdp_attr_replace(rec, attrib, pSequenceHolder);
    926 
    927 		/* Update on the server */
    928 		ret = sdp_device_record_update(session, &interface, rec);
    929 		if (ret < 0)
    930 			printf("Service Record update failed (%d).\n", errno);
    931 	} else
    932 		printf("Failed to create pSequenceHolder\n");
    933 
    934 	/* Cleanup */
    935 	for (i = 0; i < argc; i++)
    936 		free(allocArray[i]);
    937 
    938 	free(dtdArray);
    939 	free(valueArray);
    940 	free(allocArray);
    941 
    942 	sdp_record_free(rec);
    943 
    944 	return ret;
    945 }
    946 
    947 static struct option seq_options[] = {
    948 	{ "help",	0, 0, 'h' },
    949 	{ 0, 0, 0, 0 }
    950 };
    951 
    952 static const char *seq_help =
    953 	"Usage:\n"
    954 	"\tget record_handle attrib_id attrib_values\n";
    955 
    956 /*
    957  * Add an attribute sequence to an existing SDP record
    958  * on the local SDP server
    959  */
    960 static int cmd_setseq(int argc, char **argv)
    961 {
    962 	int opt, status;
    963 	uint32_t handle;
    964 	uint16_t attrib;
    965 	sdp_session_t *sess;
    966 
    967 	for_each_opt(opt, seq_options, NULL) {
    968 		switch(opt) {
    969 		default:
    970 			printf("%s", seq_help);
    971 			return -1;
    972 		}
    973 	}
    974 
    975 	argc -= optind;
    976 	argv += optind;
    977 
    978 	if (argc < 3) {
    979 		printf("%s", seq_help);
    980 		return -1;
    981 	}
    982 
    983 	/* Convert command line args */
    984 	handle = strtoul(argv[0], NULL, 16);
    985 	attrib = strtoul(argv[1], NULL, 16);
    986 
    987 	argc -= 2;
    988 	argv += 2;
    989 
    990 	/* Do it */
    991 	sess = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, 0);
    992 	if (!sess)
    993 		return -1;
    994 
    995 	status = set_attribseq(sess, handle, attrib, argc, argv);
    996 	sdp_close(sess);
    997 
    998 	return status;
    999 }
   1000 
   1001 static void print_service_class(void *value, void *userData)
   1002 {
   1003 	char ServiceClassUUID_str[MAX_LEN_SERVICECLASS_UUID_STR];
   1004 	uuid_t *uuid = (uuid_t *)value;
   1005 
   1006 	sdp_uuid2strn(uuid, UUID_str, MAX_LEN_UUID_STR);
   1007 	sdp_svclass_uuid2strn(uuid, ServiceClassUUID_str, MAX_LEN_SERVICECLASS_UUID_STR);
   1008 	if (uuid->type != SDP_UUID128)
   1009 		printf("  \"%s\" (0x%s)\n", ServiceClassUUID_str, UUID_str);
   1010 	else
   1011 		printf("  UUID 128: %s\n", UUID_str);
   1012 }
   1013 
   1014 static void print_service_desc(void *value, void *user)
   1015 {
   1016 	char str[MAX_LEN_PROTOCOL_UUID_STR];
   1017 	sdp_data_t *p = (sdp_data_t *)value, *s;
   1018 	int i = 0, proto = 0;
   1019 
   1020 	for (; p; p = p->next, i++) {
   1021 		switch (p->dtd) {
   1022 		case SDP_UUID16:
   1023 		case SDP_UUID32:
   1024 		case SDP_UUID128:
   1025 			sdp_uuid2strn(&p->val.uuid, UUID_str, MAX_LEN_UUID_STR);
   1026 			sdp_proto_uuid2strn(&p->val.uuid, str, sizeof(str));
   1027 			proto = sdp_uuid_to_proto(&p->val.uuid);
   1028 			printf("  \"%s\" (0x%s)\n", str, UUID_str);
   1029 			break;
   1030 		case SDP_UINT8:
   1031 			if (proto == RFCOMM_UUID)
   1032 				printf("    Channel: %d\n", p->val.uint8);
   1033 			else
   1034 				printf("    uint8: 0x%x\n", p->val.uint8);
   1035 			break;
   1036 		case SDP_UINT16:
   1037 			if (proto == L2CAP_UUID) {
   1038 				if (i == 1)
   1039 					printf("    PSM: %d\n", p->val.uint16);
   1040 				else
   1041 					printf("    Version: 0x%04x\n", p->val.uint16);
   1042 			} else if (proto == BNEP_UUID)
   1043 				if (i == 1)
   1044 					printf("    Version: 0x%04x\n", p->val.uint16);
   1045 				else
   1046 					printf("    uint16: 0x%x\n", p->val.uint16);
   1047 			else
   1048 				printf("    uint16: 0x%x\n", p->val.uint16);
   1049 			break;
   1050 		case SDP_SEQ16:
   1051 			printf("    SEQ16:");
   1052 			for (s = p->val.dataseq; s; s = s->next)
   1053 				printf(" %x", s->val.uint16);
   1054 			printf("\n");
   1055 			break;
   1056 		case SDP_SEQ8:
   1057 			printf("    SEQ8:");
   1058 			for (s = p->val.dataseq; s; s = s->next)
   1059 				printf(" %x", s->val.uint8);
   1060 			printf("\n");
   1061 			break;
   1062 		default:
   1063 			printf("    FIXME: dtd=0%x\n", p->dtd);
   1064 			break;
   1065 		}
   1066 	}
   1067 }
   1068 
   1069 static void print_lang_attr(void *value, void *user)
   1070 {
   1071 	sdp_lang_attr_t *lang = (sdp_lang_attr_t *)value;
   1072 	printf("  code_ISO639: 0x%02x\n", lang->code_ISO639);
   1073 	printf("  encoding:    0x%02x\n", lang->encoding);
   1074 	printf("  base_offset: 0x%02x\n", lang->base_offset);
   1075 }
   1076 
   1077 static void print_access_protos(void *value, void *userData)
   1078 {
   1079 	sdp_list_t *protDescSeq = (sdp_list_t *)value;
   1080 	sdp_list_foreach(protDescSeq, print_service_desc, 0);
   1081 }
   1082 
   1083 static void print_profile_desc(void *value, void *userData)
   1084 {
   1085 	sdp_profile_desc_t *desc = (sdp_profile_desc_t *)value;
   1086 	char str[MAX_LEN_PROFILEDESCRIPTOR_UUID_STR];
   1087 
   1088 	sdp_uuid2strn(&desc->uuid, UUID_str, MAX_LEN_UUID_STR);
   1089 	sdp_profile_uuid2strn(&desc->uuid, str, MAX_LEN_PROFILEDESCRIPTOR_UUID_STR);
   1090 
   1091 	printf("  \"%s\" (0x%s)\n", str, UUID_str);
   1092 	if (desc->version)
   1093 		printf("    Version: 0x%04x\n", desc->version);
   1094 }
   1095 
   1096 /*
   1097  * Parse a SDP record in user friendly form.
   1098  */
   1099 static void print_service_attr(sdp_record_t *rec)
   1100 {
   1101 	sdp_list_t *list = 0, *proto = 0;
   1102 
   1103 	sdp_record_print(rec);
   1104 
   1105 	printf("Service RecHandle: 0x%x\n", rec->handle);
   1106 
   1107 	if (sdp_get_service_classes(rec, &list) == 0) {
   1108 		printf("Service Class ID List:\n");
   1109 		sdp_list_foreach(list, print_service_class, 0);
   1110 		sdp_list_free(list, free);
   1111 	}
   1112 	if (sdp_get_access_protos(rec, &proto) == 0) {
   1113 		printf("Protocol Descriptor List:\n");
   1114 		sdp_list_foreach(proto, print_access_protos, 0);
   1115 		sdp_list_foreach(proto, (sdp_list_func_t)sdp_list_free, 0);
   1116 		sdp_list_free(proto, 0);
   1117 	}
   1118 	if (sdp_get_lang_attr(rec, &list) == 0) {
   1119 		printf("Language Base Attr List:\n");
   1120 		sdp_list_foreach(list, print_lang_attr, 0);
   1121 		sdp_list_free(list, free);
   1122 	}
   1123 	if (sdp_get_profile_descs(rec, &list) == 0) {
   1124 		printf("Profile Descriptor List:\n");
   1125 		sdp_list_foreach(list, print_profile_desc, 0);
   1126 		sdp_list_free(list, free);
   1127 	}
   1128 }
   1129 
   1130 /*
   1131  * Support for Service (de)registration
   1132  */
   1133 typedef struct {
   1134 	uint32_t handle;
   1135 	char *name;
   1136 	char *provider;
   1137 	char *desc;
   1138 	unsigned int class;
   1139 	unsigned int profile;
   1140 	uint16_t psm;
   1141 	uint8_t channel;
   1142 	uint8_t network;
   1143 } svc_info_t;
   1144 
   1145 static void add_lang_attr(sdp_record_t *r)
   1146 {
   1147 	sdp_lang_attr_t base_lang;
   1148 	sdp_list_t *langs = 0;
   1149 
   1150 	/* UTF-8 MIBenum (http://www.iana.org/assignments/character-sets) */
   1151 	base_lang.code_ISO639 = (0x65 << 8) | 0x6e;
   1152 	base_lang.encoding = 106;
   1153 	base_lang.base_offset = SDP_PRIMARY_LANG_BASE;
   1154 	langs = sdp_list_append(0, &base_lang);
   1155 	sdp_set_lang_attr(r, langs);
   1156 	sdp_list_free(langs, 0);
   1157 }
   1158 
   1159 static int add_sp(sdp_session_t *session, svc_info_t *si)
   1160 {
   1161 	sdp_list_t *svclass_id, *apseq, *proto[2], *profiles, *root, *aproto;
   1162 	uuid_t root_uuid, sp_uuid, l2cap, rfcomm;
   1163 	sdp_profile_desc_t profile;
   1164 	sdp_record_t record;
   1165 	uint8_t u8 = si->channel ? si->channel : 1;
   1166 	sdp_data_t *channel;
   1167 	int ret = 0;
   1168 
   1169 	memset(&record, 0, sizeof(sdp_record_t));
   1170 	record.handle = si->handle;
   1171 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   1172 	root = sdp_list_append(0, &root_uuid);
   1173 	sdp_set_browse_groups(&record, root);
   1174 	sdp_list_free(root, 0);
   1175 
   1176 	sdp_uuid16_create(&sp_uuid, SERIAL_PORT_SVCLASS_ID);
   1177 	svclass_id = sdp_list_append(0, &sp_uuid);
   1178 	sdp_set_service_classes(&record, svclass_id);
   1179 	sdp_list_free(svclass_id, 0);
   1180 
   1181 	sdp_uuid16_create(&profile.uuid, SERIAL_PORT_PROFILE_ID);
   1182 	profile.version = 0x0100;
   1183 	profiles = sdp_list_append(0, &profile);
   1184 	sdp_set_profile_descs(&record, profiles);
   1185 	sdp_list_free(profiles, 0);
   1186 
   1187 	sdp_uuid16_create(&l2cap, L2CAP_UUID);
   1188 	proto[0] = sdp_list_append(0, &l2cap);
   1189 	apseq = sdp_list_append(0, proto[0]);
   1190 
   1191 	sdp_uuid16_create(&rfcomm, RFCOMM_UUID);
   1192 	proto[1] = sdp_list_append(0, &rfcomm);
   1193 	channel = sdp_data_alloc(SDP_UINT8, &u8);
   1194 	proto[1] = sdp_list_append(proto[1], channel);
   1195 	apseq = sdp_list_append(apseq, proto[1]);
   1196 
   1197 	aproto = sdp_list_append(0, apseq);
   1198 	sdp_set_access_protos(&record, aproto);
   1199 
   1200 	add_lang_attr(&record);
   1201 
   1202 	sdp_set_info_attr(&record, "Serial Port", "BlueZ", "COM Port");
   1203 
   1204 	sdp_set_url_attr(&record, "http://www.bluez.org/",
   1205 			"http://www.bluez.org/", "http://www.bluez.org/");
   1206 
   1207 	sdp_set_service_id(&record, sp_uuid);
   1208 	sdp_set_service_ttl(&record, 0xffff);
   1209 	sdp_set_service_avail(&record, 0xff);
   1210 	sdp_set_record_state(&record, 0x00001234);
   1211 
   1212 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   1213 		printf("Service Record registration failed\n");
   1214 		ret = -1;
   1215 		goto end;
   1216 	}
   1217 
   1218 	printf("Serial Port service registered\n");
   1219 
   1220 end:
   1221 	sdp_data_free(channel);
   1222 	sdp_list_free(proto[0], 0);
   1223 	sdp_list_free(proto[1], 0);
   1224 	sdp_list_free(apseq, 0);
   1225 	sdp_list_free(aproto, 0);
   1226 
   1227 	return ret;
   1228 }
   1229 
   1230 static int add_dun(sdp_session_t *session, svc_info_t *si)
   1231 {
   1232 	sdp_list_t *svclass_id, *pfseq, *apseq, *root, *aproto;
   1233 	uuid_t rootu, dun, gn, l2cap, rfcomm;
   1234 	sdp_profile_desc_t profile;
   1235 	sdp_list_t *proto[2];
   1236 	sdp_record_t record;
   1237 	uint8_t u8 = si->channel ? si->channel : 2;
   1238 	sdp_data_t *channel;
   1239 	int ret = 0;
   1240 
   1241 	memset(&record, 0, sizeof(sdp_record_t));
   1242 	record.handle = si->handle;
   1243 
   1244 	sdp_uuid16_create(&rootu, PUBLIC_BROWSE_GROUP);
   1245 	root = sdp_list_append(0, &rootu);
   1246 	sdp_set_browse_groups(&record, root);
   1247 
   1248 	sdp_uuid16_create(&dun, DIALUP_NET_SVCLASS_ID);
   1249 	svclass_id = sdp_list_append(0, &dun);
   1250 	sdp_uuid16_create(&gn,  GENERIC_NETWORKING_SVCLASS_ID);
   1251 	svclass_id = sdp_list_append(svclass_id, &gn);
   1252 	sdp_set_service_classes(&record, svclass_id);
   1253 
   1254 	sdp_uuid16_create(&profile.uuid, DIALUP_NET_PROFILE_ID);
   1255 	profile.version = 0x0100;
   1256 	pfseq = sdp_list_append(0, &profile);
   1257 	sdp_set_profile_descs(&record, pfseq);
   1258 
   1259 	sdp_uuid16_create(&l2cap, L2CAP_UUID);
   1260 	proto[0] = sdp_list_append(0, &l2cap);
   1261 	apseq = sdp_list_append(0, proto[0]);
   1262 
   1263 	sdp_uuid16_create(&rfcomm, RFCOMM_UUID);
   1264 	proto[1] = sdp_list_append(0, &rfcomm);
   1265 	channel = sdp_data_alloc(SDP_UINT8, &u8);
   1266 	proto[1] = sdp_list_append(proto[1], channel);
   1267 	apseq = sdp_list_append(apseq, proto[1]);
   1268 
   1269 	aproto = sdp_list_append(0, apseq);
   1270 	sdp_set_access_protos(&record, aproto);
   1271 
   1272 	sdp_set_info_attr(&record, "Dial-Up Networking", 0, 0);
   1273 
   1274 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   1275 		printf("Service Record registration failed\n");
   1276 		ret = -1;
   1277 		goto end;
   1278 	}
   1279 
   1280 	printf("Dial-Up Networking service registered\n");
   1281 
   1282 end:
   1283 	sdp_data_free(channel);
   1284 	sdp_list_free(proto[0], 0);
   1285 	sdp_list_free(proto[1], 0);
   1286 	sdp_list_free(apseq, 0);
   1287 	sdp_list_free(aproto, 0);
   1288 
   1289 	return ret;
   1290 }
   1291 
   1292 static int add_fax(sdp_session_t *session, svc_info_t *si)
   1293 {
   1294 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
   1295 	uuid_t root_uuid, fax_uuid, tel_uuid, l2cap_uuid, rfcomm_uuid;
   1296 	sdp_profile_desc_t profile;
   1297 	sdp_list_t *aproto, *proto[2];
   1298 	sdp_record_t record;
   1299 	uint8_t u8 = si->channel? si->channel : 3;
   1300 	sdp_data_t *channel;
   1301 	int ret = 0;
   1302 
   1303 	memset(&record, 0, sizeof(sdp_record_t));
   1304 	record.handle = si->handle;
   1305 
   1306 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   1307 	root = sdp_list_append(0, &root_uuid);
   1308 	sdp_set_browse_groups(&record, root);
   1309 
   1310 	sdp_uuid16_create(&fax_uuid, FAX_SVCLASS_ID);
   1311 	svclass_id = sdp_list_append(0, &fax_uuid);
   1312 	sdp_uuid16_create(&tel_uuid, GENERIC_TELEPHONY_SVCLASS_ID);
   1313 	svclass_id = sdp_list_append(svclass_id, &tel_uuid);
   1314 	sdp_set_service_classes(&record, svclass_id);
   1315 
   1316 	sdp_uuid16_create(&profile.uuid, FAX_PROFILE_ID);
   1317 	profile.version = 0x0100;
   1318 	pfseq = sdp_list_append(0, &profile);
   1319 	sdp_set_profile_descs(&record, pfseq);
   1320 
   1321 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
   1322 	proto[0] = sdp_list_append(0, &l2cap_uuid);
   1323 	apseq = sdp_list_append(0, proto[0]);
   1324 
   1325 	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
   1326 	proto[1] = sdp_list_append(0, &rfcomm_uuid);
   1327 	channel = sdp_data_alloc(SDP_UINT8, &u8);
   1328 	proto[1] = sdp_list_append(proto[1], channel);
   1329 	apseq  = sdp_list_append(apseq, proto[1]);
   1330 
   1331 	aproto = sdp_list_append(0, apseq);
   1332 	sdp_set_access_protos(&record, aproto);
   1333 
   1334 	sdp_set_info_attr(&record, "Fax", 0, 0);
   1335 
   1336 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   1337 		printf("Service Record registration failed\n");
   1338 		ret = -1;
   1339 		goto end;
   1340 	}
   1341 	printf("Fax service registered\n");
   1342 end:
   1343 	sdp_data_free(channel);
   1344 	sdp_list_free(proto[0], 0);
   1345 	sdp_list_free(proto[1], 0);
   1346 	sdp_list_free(apseq, 0);
   1347 	sdp_list_free(aproto, 0);
   1348 	return ret;
   1349 }
   1350 
   1351 static int add_lan(sdp_session_t *session, svc_info_t *si)
   1352 {
   1353 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
   1354 	uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid;
   1355 	sdp_profile_desc_t profile;
   1356 	sdp_list_t *aproto, *proto[2];
   1357 	sdp_record_t record;
   1358 	uint8_t u8 = si->channel ? si->channel : 4;
   1359 	sdp_data_t *channel;
   1360 	int ret = 0;
   1361 
   1362 	memset(&record, 0, sizeof(sdp_record_t));
   1363 	record.handle = si->handle;
   1364 
   1365 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   1366 	root = sdp_list_append(0, &root_uuid);
   1367 	sdp_set_browse_groups(&record, root);
   1368 
   1369 	sdp_uuid16_create(&svclass_uuid, LAN_ACCESS_SVCLASS_ID);
   1370 	svclass_id = sdp_list_append(0, &svclass_uuid);
   1371 	sdp_set_service_classes(&record, svclass_id);
   1372 
   1373 	sdp_uuid16_create(&profile.uuid, LAN_ACCESS_PROFILE_ID);
   1374 	profile.version = 0x0100;
   1375 	pfseq = sdp_list_append(0, &profile);
   1376 	sdp_set_profile_descs(&record, pfseq);
   1377 
   1378 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
   1379 	proto[0] = sdp_list_append(0, &l2cap_uuid);
   1380 	apseq = sdp_list_append(0, proto[0]);
   1381 
   1382 	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
   1383 	proto[1] = sdp_list_append(0, &rfcomm_uuid);
   1384 	channel = sdp_data_alloc(SDP_UINT8, &u8);
   1385 	proto[1] = sdp_list_append(proto[1], channel);
   1386 	apseq = sdp_list_append(apseq, proto[1]);
   1387 
   1388 	aproto = sdp_list_append(0, apseq);
   1389 	sdp_set_access_protos(&record, aproto);
   1390 
   1391 	sdp_set_info_attr(&record, "LAN Access over PPP", 0, 0);
   1392 
   1393 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   1394 		printf("Service Record registration failed\n");
   1395 		ret = -1;
   1396 		goto end;
   1397 	}
   1398 
   1399 	printf("LAN Access service registered\n");
   1400 
   1401 end:
   1402 	sdp_data_free(channel);
   1403 	sdp_list_free(proto[0], 0);
   1404 	sdp_list_free(proto[1], 0);
   1405 	sdp_list_free(apseq, 0);
   1406 	sdp_list_free(aproto, 0);
   1407 
   1408 	return ret;
   1409 }
   1410 
   1411 static int add_headset(sdp_session_t *session, svc_info_t *si)
   1412 {
   1413 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
   1414 	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid, l2cap_uuid, rfcomm_uuid;
   1415 	sdp_profile_desc_t profile;
   1416 	sdp_list_t *aproto, *proto[2];
   1417 	sdp_record_t record;
   1418 	uint8_t u8 = si->channel ? si->channel : 5;
   1419 	sdp_data_t *channel;
   1420 	int ret = 0;
   1421 
   1422 	memset(&record, 0, sizeof(sdp_record_t));
   1423 	record.handle = si->handle;
   1424 
   1425 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   1426 	root = sdp_list_append(0, &root_uuid);
   1427 	sdp_set_browse_groups(&record, root);
   1428 
   1429 	sdp_uuid16_create(&svclass_uuid, HEADSET_SVCLASS_ID);
   1430 	svclass_id = sdp_list_append(0, &svclass_uuid);
   1431 	sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID);
   1432 	svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid);
   1433 	sdp_set_service_classes(&record, svclass_id);
   1434 
   1435 	sdp_uuid16_create(&profile.uuid, HEADSET_PROFILE_ID);
   1436 	profile.version = 0x0100;
   1437 	pfseq = sdp_list_append(0, &profile);
   1438 	sdp_set_profile_descs(&record, pfseq);
   1439 
   1440 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
   1441 	proto[0] = sdp_list_append(0, &l2cap_uuid);
   1442 	apseq = sdp_list_append(0, proto[0]);
   1443 
   1444 	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
   1445 	proto[1] = sdp_list_append(0, &rfcomm_uuid);
   1446 	channel = sdp_data_alloc(SDP_UINT8, &u8);
   1447 	proto[1] = sdp_list_append(proto[1], channel);
   1448 	apseq = sdp_list_append(apseq, proto[1]);
   1449 
   1450 	aproto = sdp_list_append(0, apseq);
   1451 	sdp_set_access_protos(&record, aproto);
   1452 
   1453 	sdp_set_info_attr(&record, "Headset", 0, 0);
   1454 
   1455 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   1456 		printf("Service Record registration failed\n");
   1457 		ret = -1;
   1458 		goto end;
   1459 	}
   1460 
   1461 	printf("Headset service registered\n");
   1462 
   1463 end:
   1464 	sdp_data_free(channel);
   1465 	sdp_list_free(proto[0], 0);
   1466 	sdp_list_free(proto[1], 0);
   1467 	sdp_list_free(apseq, 0);
   1468 	sdp_list_free(aproto, 0);
   1469 
   1470 	return ret;
   1471 }
   1472 
   1473 static int add_headset_ag(sdp_session_t *session, svc_info_t *si)
   1474 {
   1475 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
   1476 	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid, l2cap_uuid, rfcomm_uuid;
   1477 	sdp_profile_desc_t profile;
   1478 	sdp_list_t *aproto, *proto[2];
   1479 	sdp_record_t record;
   1480 	uint8_t u8 = si->channel ? si->channel : 7;
   1481 	uint16_t u16 = 0x17;
   1482 	sdp_data_t *channel, *features;
   1483 	uint8_t netid = si->network ? si->network : 0x01; // ???? profile document
   1484 	sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid);
   1485 	int ret = 0;
   1486 
   1487 	memset(&record, 0, sizeof(sdp_record_t));
   1488 	record.handle = si->handle;
   1489 
   1490 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   1491 	root = sdp_list_append(0, &root_uuid);
   1492 	sdp_set_browse_groups(&record, root);
   1493 
   1494 	sdp_uuid16_create(&svclass_uuid, HEADSET_AGW_SVCLASS_ID);
   1495 	svclass_id = sdp_list_append(0, &svclass_uuid);
   1496 	sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID);
   1497 	svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid);
   1498 	sdp_set_service_classes(&record, svclass_id);
   1499 
   1500 	sdp_uuid16_create(&profile.uuid, HEADSET_PROFILE_ID);
   1501 	profile.version = 0x0100;
   1502 	pfseq = sdp_list_append(0, &profile);
   1503 	sdp_set_profile_descs(&record, pfseq);
   1504 
   1505 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
   1506 	proto[0] = sdp_list_append(0, &l2cap_uuid);
   1507 	apseq = sdp_list_append(0, proto[0]);
   1508 
   1509 	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
   1510 	proto[1] = sdp_list_append(0, &rfcomm_uuid);
   1511 	channel = sdp_data_alloc(SDP_UINT8, &u8);
   1512 	proto[1] = sdp_list_append(proto[1], channel);
   1513 	apseq = sdp_list_append(apseq, proto[1]);
   1514 
   1515 	features = sdp_data_alloc(SDP_UINT16, &u16);
   1516 	sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features);
   1517 
   1518 	aproto = sdp_list_append(0, apseq);
   1519 	sdp_set_access_protos(&record, aproto);
   1520 
   1521 	sdp_set_info_attr(&record, "Voice Gateway", 0, 0);
   1522 
   1523 	sdp_attr_add(&record, SDP_ATTR_EXTERNAL_NETWORK, network);
   1524 
   1525 	if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) {
   1526 		printf("Service Record registration failed\n");
   1527 		ret = -1;
   1528 		goto end;
   1529 	}
   1530 
   1531 	printf("Headset AG service registered\n");
   1532 
   1533 end:
   1534 	sdp_data_free(channel);
   1535 	sdp_list_free(proto[0], 0);
   1536 	sdp_list_free(proto[1], 0);
   1537 	sdp_list_free(apseq, 0);
   1538 	sdp_list_free(aproto, 0);
   1539 
   1540 	return ret;
   1541 }
   1542 
   1543 static int add_handsfree(sdp_session_t *session, svc_info_t *si)
   1544 {
   1545 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
   1546 	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid, l2cap_uuid, rfcomm_uuid;
   1547 	sdp_profile_desc_t profile;
   1548 	sdp_list_t *aproto, *proto[2];
   1549 	sdp_record_t record;
   1550 	uint8_t u8 = si->channel ? si->channel : 6;
   1551 	uint16_t u16 = 0x31;
   1552 	sdp_data_t *channel, *features;
   1553 	int ret = 0;
   1554 
   1555 	memset(&record, 0, sizeof(sdp_record_t));
   1556 	record.handle = si->handle;
   1557 
   1558 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   1559 	root = sdp_list_append(0, &root_uuid);
   1560 	sdp_set_browse_groups(&record, root);
   1561 
   1562 	sdp_uuid16_create(&svclass_uuid, HANDSFREE_SVCLASS_ID);
   1563 	svclass_id = sdp_list_append(0, &svclass_uuid);
   1564 	sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID);
   1565 	svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid);
   1566 	sdp_set_service_classes(&record, svclass_id);
   1567 
   1568 	sdp_uuid16_create(&profile.uuid, HANDSFREE_PROFILE_ID);
   1569 	profile.version = 0x0101;
   1570 	pfseq = sdp_list_append(0, &profile);
   1571 	sdp_set_profile_descs(&record, pfseq);
   1572 
   1573 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
   1574 	proto[0] = sdp_list_append(0, &l2cap_uuid);
   1575 	apseq = sdp_list_append(0, proto[0]);
   1576 
   1577 	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
   1578 	proto[1] = sdp_list_append(0, &rfcomm_uuid);
   1579 	channel = sdp_data_alloc(SDP_UINT8, &u8);
   1580 	proto[1] = sdp_list_append(proto[1], channel);
   1581 	apseq = sdp_list_append(apseq, proto[1]);
   1582 
   1583 	features = sdp_data_alloc(SDP_UINT16, &u16);
   1584 	sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features);
   1585 
   1586 	aproto = sdp_list_append(0, apseq);
   1587 	sdp_set_access_protos(&record, aproto);
   1588 
   1589 	sdp_set_info_attr(&record, "Handsfree", 0, 0);
   1590 
   1591 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   1592 		printf("Service Record registration failed\n");
   1593 		ret = -1;
   1594 		goto end;
   1595 	}
   1596 
   1597 	printf("Handsfree service registered\n");
   1598 
   1599 end:
   1600 	sdp_data_free(channel);
   1601 	sdp_list_free(proto[0], 0);
   1602 	sdp_list_free(proto[1], 0);
   1603 	sdp_list_free(apseq, 0);
   1604 	sdp_list_free(aproto, 0);
   1605 
   1606 	return ret;
   1607 }
   1608 
   1609 static int add_handsfree_ag(sdp_session_t *session, svc_info_t *si)
   1610 {
   1611 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
   1612 	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid, l2cap_uuid, rfcomm_uuid;
   1613 	sdp_profile_desc_t profile;
   1614 	sdp_list_t *aproto, *proto[2];
   1615 	sdp_record_t record;
   1616 	uint8_t u8 = si->channel ? si->channel : 7;
   1617 	uint16_t u16 = 0x17;
   1618 #ifdef ANDROID
   1619 	u16 = 0x07;
   1620 #endif
   1621 	sdp_data_t *channel, *features;
   1622 	uint8_t netid = si->network ? si->network : 0x01; // ???? profile document
   1623 	sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid);
   1624 	int ret = 0;
   1625 
   1626 	memset(&record, 0, sizeof(sdp_record_t));
   1627 	record.handle = si->handle;
   1628 
   1629 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   1630 	root = sdp_list_append(0, &root_uuid);
   1631 	sdp_set_browse_groups(&record, root);
   1632 
   1633 	sdp_uuid16_create(&svclass_uuid, HANDSFREE_AGW_SVCLASS_ID);
   1634 	svclass_id = sdp_list_append(0, &svclass_uuid);
   1635 	sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID);
   1636 	svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid);
   1637 	sdp_set_service_classes(&record, svclass_id);
   1638 
   1639 	sdp_uuid16_create(&profile.uuid, HANDSFREE_PROFILE_ID);
   1640 	profile.version = 0x0105;
   1641 	pfseq = sdp_list_append(0, &profile);
   1642 	sdp_set_profile_descs(&record, pfseq);
   1643 
   1644 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
   1645 	proto[0] = sdp_list_append(0, &l2cap_uuid);
   1646 	apseq = sdp_list_append(0, proto[0]);
   1647 
   1648 	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
   1649 	proto[1] = sdp_list_append(0, &rfcomm_uuid);
   1650 	channel = sdp_data_alloc(SDP_UINT8, &u8);
   1651 	proto[1] = sdp_list_append(proto[1], channel);
   1652 	apseq = sdp_list_append(apseq, proto[1]);
   1653 
   1654 	features = sdp_data_alloc(SDP_UINT16, &u16);
   1655 	sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features);
   1656 
   1657 	aproto = sdp_list_append(0, apseq);
   1658 	sdp_set_access_protos(&record, aproto);
   1659 
   1660 	sdp_set_info_attr(&record, "Voice Gateway", 0, 0);
   1661 
   1662 	sdp_attr_add(&record, SDP_ATTR_EXTERNAL_NETWORK, network);
   1663 
   1664 	if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) {
   1665 		printf("Service Record registration failed\n");
   1666 		ret = -1;
   1667 		goto end;
   1668 	}
   1669 
   1670 	printf("Handsfree AG service registered\n");
   1671 
   1672 end:
   1673 	sdp_data_free(channel);
   1674 	sdp_list_free(proto[0], 0);
   1675 	sdp_list_free(proto[1], 0);
   1676 	sdp_list_free(apseq, 0);
   1677 	sdp_list_free(aproto, 0);
   1678 
   1679 	return ret;
   1680 }
   1681 
   1682 static int add_simaccess(sdp_session_t *session, svc_info_t *si)
   1683 {
   1684 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
   1685 	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid, l2cap_uuid, rfcomm_uuid;
   1686 	sdp_profile_desc_t profile;
   1687 	sdp_list_t *aproto, *proto[2];
   1688 	sdp_record_t record;
   1689 	uint8_t u8 = si->channel? si->channel : 8;
   1690 	uint16_t u16 = 0x31;
   1691 	sdp_data_t *channel, *features;
   1692 	int ret = 0;
   1693 
   1694 	memset((void *)&record, 0, sizeof(sdp_record_t));
   1695 	record.handle = si->handle;
   1696 
   1697 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   1698 	root = sdp_list_append(0, &root_uuid);
   1699 	sdp_set_browse_groups(&record, root);
   1700 
   1701 	sdp_uuid16_create(&svclass_uuid, SAP_SVCLASS_ID);
   1702 	svclass_id = sdp_list_append(0, &svclass_uuid);
   1703 	sdp_uuid16_create(&ga_svclass_uuid, GENERIC_TELEPHONY_SVCLASS_ID);
   1704 	svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid);
   1705 	sdp_set_service_classes(&record, svclass_id);
   1706 
   1707 	sdp_uuid16_create(&profile.uuid, SAP_PROFILE_ID);
   1708 	profile.version = 0x0101;
   1709 	pfseq = sdp_list_append(0, &profile);
   1710 	sdp_set_profile_descs(&record, pfseq);
   1711 
   1712 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
   1713 	proto[0] = sdp_list_append(0, &l2cap_uuid);
   1714 	apseq = sdp_list_append(0, proto[0]);
   1715 
   1716 	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
   1717 	proto[1] = sdp_list_append(0, &rfcomm_uuid);
   1718 	channel = sdp_data_alloc(SDP_UINT8, &u8);
   1719 	proto[1] = sdp_list_append(proto[1], channel);
   1720 	apseq = sdp_list_append(apseq, proto[1]);
   1721 
   1722 	features = sdp_data_alloc(SDP_UINT16, &u16);
   1723 	sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features);
   1724 
   1725 	aproto = sdp_list_append(0, apseq);
   1726 	sdp_set_access_protos(&record, aproto);
   1727 
   1728 	sdp_set_info_attr(&record, "SIM Access", 0, 0);
   1729 
   1730 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   1731 		printf("Service Record registration failed\n");
   1732 		ret = -1;
   1733 		goto end;
   1734 	}
   1735 
   1736 	printf("SIM Access service registered\n");
   1737 
   1738 end:
   1739 	sdp_data_free(channel);
   1740 	sdp_list_free(proto[0], 0);
   1741 	sdp_list_free(proto[1], 0);
   1742 	sdp_list_free(apseq, 0);
   1743 	sdp_list_free(aproto, 0);
   1744 
   1745 	return ret;
   1746 }
   1747 
   1748 static int add_opush(sdp_session_t *session, svc_info_t *si)
   1749 {
   1750 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
   1751 	uuid_t root_uuid, opush_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid;
   1752 	sdp_profile_desc_t profile[1];
   1753 	sdp_list_t *aproto, *proto[3];
   1754 	sdp_record_t record;
   1755 	uint8_t chan = si->channel ? si->channel : 9;
   1756 	sdp_data_t *channel;
   1757 	uint8_t formats[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0xff };
   1758 	void *dtds[sizeof(formats)], *values[sizeof(formats)];
   1759 	unsigned int i;
   1760 	uint8_t dtd = SDP_UINT8;
   1761 	sdp_data_t *sflist;
   1762 	int ret = 0;
   1763 
   1764 	memset(&record, 0, sizeof(sdp_record_t));
   1765 	record.handle = si->handle;
   1766 
   1767 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   1768 	root = sdp_list_append(0, &root_uuid);
   1769 	sdp_set_browse_groups(&record, root);
   1770 
   1771 	sdp_uuid16_create(&opush_uuid, OBEX_OBJPUSH_SVCLASS_ID);
   1772 	svclass_id = sdp_list_append(0, &opush_uuid);
   1773 	sdp_set_service_classes(&record, svclass_id);
   1774 
   1775 	sdp_uuid16_create(&profile[0].uuid, OBEX_OBJPUSH_PROFILE_ID);
   1776 	profile[0].version = 0x0100;
   1777 	pfseq = sdp_list_append(0, profile);
   1778 	sdp_set_profile_descs(&record, pfseq);
   1779 
   1780 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
   1781 	proto[0] = sdp_list_append(0, &l2cap_uuid);
   1782 	apseq = sdp_list_append(0, proto[0]);
   1783 
   1784 	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
   1785 	proto[1] = sdp_list_append(0, &rfcomm_uuid);
   1786 	channel = sdp_data_alloc(SDP_UINT8, &chan);
   1787 	proto[1] = sdp_list_append(proto[1], channel);
   1788 	apseq = sdp_list_append(apseq, proto[1]);
   1789 
   1790 	sdp_uuid16_create(&obex_uuid, OBEX_UUID);
   1791 	proto[2] = sdp_list_append(0, &obex_uuid);
   1792 	apseq = sdp_list_append(apseq, proto[2]);
   1793 
   1794 	aproto = sdp_list_append(0, apseq);
   1795 	sdp_set_access_protos(&record, aproto);
   1796 
   1797 	for (i = 0; i < sizeof(formats); i++) {
   1798 		dtds[i] = &dtd;
   1799 		values[i] = &formats[i];
   1800 	}
   1801 	sflist = sdp_seq_alloc(dtds, values, sizeof(formats));
   1802 	sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FORMATS_LIST, sflist);
   1803 
   1804 	sdp_set_info_attr(&record, "OBEX Object Push", 0, 0);
   1805 
   1806 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   1807 		printf("Service Record registration failed\n");
   1808 		ret = -1;
   1809 		goto end;
   1810 	}
   1811 
   1812 	printf("OBEX Object Push service registered\n");
   1813 
   1814 end:
   1815 	sdp_data_free(channel);
   1816 	sdp_list_free(proto[0], 0);
   1817 	sdp_list_free(proto[1], 0);
   1818 	sdp_list_free(proto[2], 0);
   1819 	sdp_list_free(apseq, 0);
   1820 	sdp_list_free(aproto, 0);
   1821 
   1822 	return ret;
   1823 }
   1824 
   1825 static int add_pbap(sdp_session_t *session, svc_info_t *si)
   1826 {
   1827 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
   1828 	uuid_t root_uuid, pbap_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid;
   1829 	sdp_profile_desc_t profile[1];
   1830 	sdp_list_t *aproto, *proto[3];
   1831 	sdp_record_t record;
   1832 	uint8_t chan = si->channel ? si->channel : 19;
   1833 	sdp_data_t *channel;
   1834 	uint8_t formats[] = {0x01};
   1835 	void *dtds[sizeof(formats)], *values[sizeof(formats)];
   1836 	int i;
   1837 	uint8_t dtd = SDP_UINT8;
   1838 	sdp_data_t *sflist;
   1839 	int ret = 0;
   1840 
   1841 	memset(&record, 0, sizeof(sdp_record_t));
   1842 	record.handle = si->handle;
   1843 
   1844 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   1845 	root = sdp_list_append(0, &root_uuid);
   1846 	sdp_set_browse_groups(&record, root);
   1847 
   1848 	sdp_uuid16_create(&pbap_uuid, PBAP_PSE_SVCLASS_ID);
   1849 	svclass_id = sdp_list_append(0, &pbap_uuid);
   1850 	sdp_set_service_classes(&record, svclass_id);
   1851 
   1852 	sdp_uuid16_create(&profile[0].uuid, PBAP_PROFILE_ID);
   1853 	profile[0].version = 0x0100;
   1854 	pfseq = sdp_list_append(0, profile);
   1855 	sdp_set_profile_descs(&record, pfseq);
   1856 
   1857 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
   1858 	proto[0] = sdp_list_append(0, &l2cap_uuid);
   1859 	apseq = sdp_list_append(0, proto[0]);
   1860 
   1861 	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
   1862 	proto[1] = sdp_list_append(0, &rfcomm_uuid);
   1863 	channel = sdp_data_alloc(SDP_UINT8, &chan);
   1864 	proto[1] = sdp_list_append(proto[1], channel);
   1865 	apseq = sdp_list_append(apseq, proto[1]);
   1866 
   1867 	sdp_uuid16_create(&obex_uuid, OBEX_UUID);
   1868 	proto[2] = sdp_list_append(0, &obex_uuid);
   1869 	apseq = sdp_list_append(apseq, proto[2]);
   1870 
   1871 	aproto = sdp_list_append(0, apseq);
   1872 	sdp_set_access_protos(&record, aproto);
   1873 
   1874 	sflist = sdp_data_alloc(dtd,formats);
   1875 	sdp_attr_add(&record, SDP_ATTR_SUPPORTED_REPOSITORIES, sflist);
   1876 
   1877 	sdp_set_info_attr(&record, "OBEX Phonebook Access Server", 0, 0);
   1878 
   1879 	if (sdp_device_record_register(session, &interface, &record,
   1880 			SDP_RECORD_PERSIST) < 0) {
   1881 		printf("Service Record registration failed\n");
   1882 		ret = -1;
   1883 		goto end;
   1884 	}
   1885 
   1886 	printf("PBAP service registered\n");
   1887 
   1888 end:
   1889 	sdp_data_free(channel);
   1890 	sdp_list_free(proto[0], 0);
   1891 	sdp_list_free(proto[1], 0);
   1892 	sdp_list_free(proto[2], 0);
   1893 	sdp_list_free(apseq, 0);
   1894 	sdp_list_free(aproto, 0);
   1895 
   1896 	return ret;
   1897 }
   1898 
   1899 static int add_ftp(sdp_session_t *session, svc_info_t *si)
   1900 {
   1901 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
   1902 	uuid_t root_uuid, ftrn_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid;
   1903 	sdp_profile_desc_t profile[1];
   1904 	sdp_list_t *aproto, *proto[3];
   1905 	sdp_record_t record;
   1906 	uint8_t u8 = si->channel ? si->channel: 10;
   1907 	sdp_data_t *channel;
   1908 	int ret = 0;
   1909 
   1910 	memset(&record, 0, sizeof(sdp_record_t));
   1911 	record.handle = si->handle;
   1912 
   1913 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   1914 	root = sdp_list_append(0, &root_uuid);
   1915 	sdp_set_browse_groups(&record, root);
   1916 
   1917 	sdp_uuid16_create(&ftrn_uuid, OBEX_FILETRANS_SVCLASS_ID);
   1918 	svclass_id = sdp_list_append(0, &ftrn_uuid);
   1919 	sdp_set_service_classes(&record, svclass_id);
   1920 
   1921 	sdp_uuid16_create(&profile[0].uuid, OBEX_FILETRANS_PROFILE_ID);
   1922 	profile[0].version = 0x0100;
   1923 	pfseq = sdp_list_append(0, &profile[0]);
   1924 	sdp_set_profile_descs(&record, pfseq);
   1925 
   1926 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
   1927 	proto[0] = sdp_list_append(0, &l2cap_uuid);
   1928 	apseq = sdp_list_append(0, proto[0]);
   1929 
   1930 	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
   1931 	proto[1] = sdp_list_append(0, &rfcomm_uuid);
   1932 	channel = sdp_data_alloc(SDP_UINT8, &u8);
   1933 	proto[1] = sdp_list_append(proto[1], channel);
   1934 	apseq = sdp_list_append(apseq, proto[1]);
   1935 
   1936 	sdp_uuid16_create(&obex_uuid, OBEX_UUID);
   1937 	proto[2] = sdp_list_append(0, &obex_uuid);
   1938 	apseq = sdp_list_append(apseq, proto[2]);
   1939 
   1940 	aproto = sdp_list_append(0, apseq);
   1941 	sdp_set_access_protos(&record, aproto);
   1942 
   1943 	sdp_set_info_attr(&record, "OBEX File Transfer", 0, 0);
   1944 
   1945 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   1946 		printf("Service Record registration failed\n");
   1947 		ret = -1;
   1948 		goto end;
   1949 	}
   1950 
   1951 	printf("OBEX File Transfer service registered\n");
   1952 
   1953 end:
   1954 	sdp_data_free(channel);
   1955 	sdp_list_free(proto[0], 0);
   1956 	sdp_list_free(proto[1], 0);
   1957 	sdp_list_free(proto[2], 0);
   1958 	sdp_list_free(apseq, 0);
   1959 	sdp_list_free(aproto, 0);
   1960 
   1961 	return ret;
   1962 }
   1963 
   1964 static int add_directprint(sdp_session_t *session, svc_info_t *si)
   1965 {
   1966 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
   1967 	uuid_t root_uuid, opush_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid;
   1968 	sdp_profile_desc_t profile[1];
   1969 	sdp_list_t *aproto, *proto[3];
   1970 	sdp_record_t record;
   1971 	uint8_t chan = si->channel ? si->channel : 12;
   1972 	sdp_data_t *channel;
   1973 	int ret = 0;
   1974 
   1975 	memset(&record, 0, sizeof(sdp_record_t));
   1976 	record.handle = si->handle;
   1977 
   1978 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   1979 	root = sdp_list_append(0, &root_uuid);
   1980 	sdp_set_browse_groups(&record, root);
   1981 
   1982 	sdp_uuid16_create(&opush_uuid, DIRECT_PRINTING_SVCLASS_ID);
   1983 	svclass_id = sdp_list_append(0, &opush_uuid);
   1984 	sdp_set_service_classes(&record, svclass_id);
   1985 
   1986 	sdp_uuid16_create(&profile[0].uuid, BASIC_PRINTING_PROFILE_ID);
   1987 	profile[0].version = 0x0100;
   1988 	pfseq = sdp_list_append(0, profile);
   1989 	sdp_set_profile_descs(&record, pfseq);
   1990 
   1991 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
   1992 	proto[0] = sdp_list_append(0, &l2cap_uuid);
   1993 	apseq = sdp_list_append(0, proto[0]);
   1994 
   1995 	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
   1996 	proto[1] = sdp_list_append(0, &rfcomm_uuid);
   1997 	channel = sdp_data_alloc(SDP_UINT8, &chan);
   1998 	proto[1] = sdp_list_append(proto[1], channel);
   1999 	apseq = sdp_list_append(apseq, proto[1]);
   2000 
   2001 	sdp_uuid16_create(&obex_uuid, OBEX_UUID);
   2002 	proto[2] = sdp_list_append(0, &obex_uuid);
   2003 	apseq = sdp_list_append(apseq, proto[2]);
   2004 
   2005 	aproto = sdp_list_append(0, apseq);
   2006 	sdp_set_access_protos(&record, aproto);
   2007 
   2008 	sdp_set_info_attr(&record, "Direct Printing", 0, 0);
   2009 
   2010 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   2011 		printf("Service Record registration failed\n");
   2012 		ret = -1;
   2013 		goto end;
   2014 	}
   2015 
   2016 	printf("Direct Printing service registered\n");
   2017 
   2018 end:
   2019 	sdp_data_free(channel);
   2020 	sdp_list_free(proto[0], 0);
   2021 	sdp_list_free(proto[1], 0);
   2022 	sdp_list_free(proto[2], 0);
   2023 	sdp_list_free(apseq, 0);
   2024 	sdp_list_free(aproto, 0);
   2025 
   2026 	return ret;
   2027 }
   2028 
   2029 static int add_nap(sdp_session_t *session, svc_info_t *si)
   2030 {
   2031 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
   2032 	uuid_t root_uuid, ftrn_uuid, l2cap_uuid, bnep_uuid;
   2033 	sdp_profile_desc_t profile[1];
   2034 	sdp_list_t *aproto, *proto[2];
   2035 	sdp_record_t record;
   2036 	uint16_t lp = 0x000f, ver = 0x0100;
   2037 	sdp_data_t *psm, *version;
   2038 	int ret = 0;
   2039 
   2040 	memset(&record, 0, sizeof(sdp_record_t));
   2041 	record.handle = si->handle;
   2042 
   2043 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   2044 	root = sdp_list_append(0, &root_uuid);
   2045 	sdp_set_browse_groups(&record, root);
   2046 
   2047 	sdp_uuid16_create(&ftrn_uuid, NAP_SVCLASS_ID);
   2048 	svclass_id = sdp_list_append(0, &ftrn_uuid);
   2049 	sdp_set_service_classes(&record, svclass_id);
   2050 
   2051 	sdp_uuid16_create(&profile[0].uuid, NAP_PROFILE_ID);
   2052 	profile[0].version = 0x0100;
   2053 	pfseq = sdp_list_append(0, &profile[0]);
   2054 	sdp_set_profile_descs(&record, pfseq);
   2055 
   2056 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
   2057 	proto[0] = sdp_list_append(0, &l2cap_uuid);
   2058 	psm = sdp_data_alloc(SDP_UINT16, &lp);
   2059 	proto[0] = sdp_list_append(proto[0], psm);
   2060 	apseq = sdp_list_append(0, proto[0]);
   2061 
   2062 	sdp_uuid16_create(&bnep_uuid, BNEP_UUID);
   2063 	proto[1] = sdp_list_append(0, &bnep_uuid);
   2064 	version  = sdp_data_alloc(SDP_UINT16, &ver);
   2065 	proto[1] = sdp_list_append(proto[1], version);
   2066 
   2067 	{
   2068 		uint16_t ptype[4] = { 0x0010, 0x0020, 0x0030, 0x0040 };
   2069 		sdp_data_t *head, *pseq;
   2070 		int p;
   2071 
   2072 		for (p = 0, head = NULL; p < 4; p++) {
   2073 			sdp_data_t *data = sdp_data_alloc(SDP_UINT16, &ptype[p]);
   2074 			head = sdp_seq_append(head, data);
   2075 		}
   2076 		pseq = sdp_data_alloc(SDP_SEQ16, head);
   2077 		proto[1] = sdp_list_append(proto[1], pseq);
   2078 	}
   2079 
   2080 	apseq = sdp_list_append(apseq, proto[1]);
   2081 
   2082 	aproto = sdp_list_append(0, apseq);
   2083 	sdp_set_access_protos(&record, aproto);
   2084 
   2085 	sdp_set_info_attr(&record, "Network Access Point Service", 0, 0);
   2086 
   2087 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   2088 		printf("Service Record registration failed\n");
   2089 		ret = -1;
   2090 		goto end;
   2091 	}
   2092 
   2093 	printf("NAP service registered\n");
   2094 
   2095 end:
   2096 	sdp_data_free(version);
   2097 	sdp_data_free(psm);
   2098 	sdp_list_free(proto[0], 0);
   2099 	sdp_list_free(proto[1], 0);
   2100 	sdp_list_free(apseq, 0);
   2101 	sdp_list_free(aproto, 0);
   2102 
   2103 	return ret;
   2104 }
   2105 
   2106 static int add_gn(sdp_session_t *session, svc_info_t *si)
   2107 {
   2108 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
   2109 	uuid_t root_uuid, ftrn_uuid, l2cap_uuid, bnep_uuid;
   2110 	sdp_profile_desc_t profile[1];
   2111 	sdp_list_t *aproto, *proto[2];
   2112 	sdp_record_t record;
   2113 	uint16_t lp = 0x000f, ver = 0x0100;
   2114 	sdp_data_t *psm, *version;
   2115 	int ret = 0;
   2116 
   2117 	memset(&record, 0, sizeof(sdp_record_t));
   2118 	record.handle = si->handle;
   2119 
   2120 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   2121 	root = sdp_list_append(0, &root_uuid);
   2122 	sdp_set_browse_groups(&record, root);
   2123 
   2124 	sdp_uuid16_create(&ftrn_uuid, GN_SVCLASS_ID);
   2125 	svclass_id = sdp_list_append(0, &ftrn_uuid);
   2126 	sdp_set_service_classes(&record, svclass_id);
   2127 
   2128 	sdp_uuid16_create(&profile[0].uuid, GN_PROFILE_ID);
   2129 	profile[0].version = 0x0100;
   2130 	pfseq = sdp_list_append(0, &profile[0]);
   2131 	sdp_set_profile_descs(&record, pfseq);
   2132 
   2133 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
   2134 	proto[0] = sdp_list_append(0, &l2cap_uuid);
   2135 	psm = sdp_data_alloc(SDP_UINT16, &lp);
   2136 	proto[0] = sdp_list_append(proto[0], psm);
   2137 	apseq = sdp_list_append(0, proto[0]);
   2138 
   2139 	sdp_uuid16_create(&bnep_uuid, BNEP_UUID);
   2140 	proto[1] = sdp_list_append(0, &bnep_uuid);
   2141 	version = sdp_data_alloc(SDP_UINT16, &ver);
   2142 	proto[1] = sdp_list_append(proto[1], version);
   2143 	apseq = sdp_list_append(apseq, proto[1]);
   2144 
   2145 	aproto = sdp_list_append(0, apseq);
   2146 	sdp_set_access_protos(&record, aproto);
   2147 
   2148 	sdp_set_info_attr(&record, "Group Network Service", 0, 0);
   2149 
   2150 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   2151 		printf("Service Record registration failed\n");
   2152 		ret = -1;
   2153 		goto end;
   2154 	}
   2155 
   2156 	printf("GN service registered\n");
   2157 
   2158 end:
   2159 	sdp_data_free(version);
   2160 	sdp_data_free(psm);
   2161 	sdp_list_free(proto[0], 0);
   2162 	sdp_list_free(proto[1], 0);
   2163 	sdp_list_free(apseq, 0);
   2164 	sdp_list_free(aproto, 0);
   2165 
   2166 	return ret;
   2167 }
   2168 
   2169 static int add_panu(sdp_session_t *session, svc_info_t *si)
   2170 {
   2171 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
   2172 	uuid_t root_uuid, ftrn_uuid, l2cap_uuid, bnep_uuid;
   2173 	sdp_profile_desc_t profile[1];
   2174 	sdp_list_t *aproto, *proto[2];
   2175 	sdp_record_t record;
   2176 	uint16_t lp = 0x000f, ver = 0x0100;
   2177 	sdp_data_t *psm, *version;
   2178 	int ret = 0;
   2179 
   2180 	memset(&record, 0, sizeof(sdp_record_t));
   2181 	record.handle = si->handle;
   2182 
   2183 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   2184 	root = sdp_list_append(NULL, &root_uuid);
   2185 	sdp_set_browse_groups(&record, root);
   2186 	sdp_list_free(root, NULL);
   2187 
   2188 	sdp_uuid16_create(&ftrn_uuid, PANU_SVCLASS_ID);
   2189 	svclass_id = sdp_list_append(NULL, &ftrn_uuid);
   2190 	sdp_set_service_classes(&record, svclass_id);
   2191 	sdp_list_free(svclass_id, NULL);
   2192 
   2193 	sdp_uuid16_create(&profile[0].uuid, PANU_PROFILE_ID);
   2194 	profile[0].version = 0x0100;
   2195 	pfseq = sdp_list_append(NULL, &profile[0]);
   2196 	sdp_set_profile_descs(&record, pfseq);
   2197 	sdp_list_free(pfseq, NULL);
   2198 
   2199 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
   2200 	proto[0] = sdp_list_append(NULL, &l2cap_uuid);
   2201 	psm = sdp_data_alloc(SDP_UINT16, &lp);
   2202 	proto[0] = sdp_list_append(proto[0], psm);
   2203 	apseq = sdp_list_append(NULL, proto[0]);
   2204 
   2205 	sdp_uuid16_create(&bnep_uuid, BNEP_UUID);
   2206 	proto[1] = sdp_list_append(NULL, &bnep_uuid);
   2207 	version = sdp_data_alloc(SDP_UINT16, &ver);
   2208 	proto[1] = sdp_list_append(proto[1], version);
   2209 	apseq = sdp_list_append(apseq, proto[1]);
   2210 
   2211 	aproto = sdp_list_append(NULL, apseq);
   2212 	sdp_set_access_protos(&record, aproto);
   2213 
   2214 	sdp_set_info_attr(&record, "PAN User", NULL, NULL);
   2215 
   2216 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   2217 		printf("Service Record registration failed\n");
   2218 		ret = -1;
   2219 		goto end;
   2220 	}
   2221 
   2222 	printf("PANU service registered\n");
   2223 
   2224 end:
   2225 	sdp_data_free(version);
   2226 	sdp_data_free(psm);
   2227 	sdp_list_free(proto[0], 0);
   2228 	sdp_list_free(proto[1], 0);
   2229 	sdp_list_free(apseq, 0);
   2230 	sdp_list_free(aproto, 0);
   2231 
   2232 	return ret;
   2233 }
   2234 
   2235 static int add_hid_keyb(sdp_session_t *session, svc_info_t *si)
   2236 {
   2237 	sdp_record_t record;
   2238 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
   2239 	uuid_t root_uuid, hidkb_uuid, l2cap_uuid, hidp_uuid;
   2240 	sdp_profile_desc_t profile[1];
   2241 	sdp_list_t *aproto, *proto[3];
   2242 	sdp_data_t *psm, *lang_lst, *lang_lst2, *hid_spec_lst, *hid_spec_lst2;
   2243 	unsigned int i;
   2244 	uint8_t dtd = SDP_UINT16;
   2245 	uint8_t dtd2 = SDP_UINT8;
   2246 	uint8_t dtd_data = SDP_TEXT_STR8;
   2247 	void *dtds[2];
   2248 	void *values[2];
   2249 	void *dtds2[2];
   2250 	void *values2[2];
   2251 	int leng[2];
   2252 	uint8_t hid_spec_type = 0x22;
   2253 	uint16_t hid_attr_lang[] = { 0x409, 0x100 };
   2254 	static const uint16_t ctrl = 0x11;
   2255 	static const uint16_t intr = 0x13;
   2256 	static const uint16_t hid_attr[] = { 0x100, 0x111, 0x40, 0x0d, 0x01, 0x01 };
   2257 	static const uint16_t hid_attr2[] = { 0x0, 0x01, 0x100, 0x1f40, 0x01, 0x01 };
   2258 	const uint8_t hid_spec[] = {
   2259 		0x05, 0x01, // usage page
   2260 		0x09, 0x06, // keyboard
   2261 		0xa1, 0x01, // key codes
   2262 		0x85, 0x01, // minimum
   2263 		0x05, 0x07, // max
   2264 		0x19, 0xe0, // logical min
   2265 		0x29, 0xe7, // logical max
   2266 		0x15, 0x00, // report size
   2267 		0x25, 0x01, // report count
   2268 		0x75, 0x01, // input data variable absolute
   2269 		0x95, 0x08, // report count
   2270 		0x81, 0x02, // report size
   2271 		0x75, 0x08,
   2272 		0x95, 0x01,
   2273 		0x81, 0x01,
   2274 		0x75, 0x01,
   2275 		0x95, 0x05,
   2276 		0x05, 0x08,
   2277 		0x19, 0x01,
   2278 		0x29, 0x05,
   2279 		0x91, 0x02,
   2280 		0x75, 0x03,
   2281 		0x95, 0x01,
   2282 		0x91, 0x01,
   2283 		0x75, 0x08,
   2284 		0x95, 0x06,
   2285 		0x15, 0x00,
   2286 		0x26, 0xff,
   2287 		0x00, 0x05,
   2288 		0x07, 0x19,
   2289 		0x00, 0x2a,
   2290 		0xff, 0x00,
   2291 		0x81, 0x00,
   2292 		0x75, 0x01,
   2293 		0x95, 0x01,
   2294 		0x15, 0x00,
   2295 		0x25, 0x01,
   2296 		0x05, 0x0c,
   2297 		0x09, 0xb8,
   2298 		0x81, 0x06,
   2299 		0x09, 0xe2,
   2300 		0x81, 0x06,
   2301 		0x09, 0xe9,
   2302 		0x81, 0x02,
   2303 		0x09, 0xea,
   2304 		0x81, 0x02,
   2305 		0x75, 0x01,
   2306 		0x95, 0x04,
   2307 		0x81, 0x01,
   2308 		0xc0         // end tag
   2309 	};
   2310 
   2311 	memset(&record, 0, sizeof(sdp_record_t));
   2312 	record.handle = si->handle;
   2313 
   2314 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   2315 	root = sdp_list_append(0, &root_uuid);
   2316 	sdp_set_browse_groups(&record, root);
   2317 
   2318 	add_lang_attr(&record);
   2319 
   2320 	sdp_uuid16_create(&hidkb_uuid, HID_SVCLASS_ID);
   2321 	svclass_id = sdp_list_append(0, &hidkb_uuid);
   2322 	sdp_set_service_classes(&record, svclass_id);
   2323 
   2324 	sdp_uuid16_create(&profile[0].uuid, HID_PROFILE_ID);
   2325 	profile[0].version = 0x0100;
   2326 	pfseq = sdp_list_append(0, profile);
   2327 	sdp_set_profile_descs(&record, pfseq);
   2328 
   2329 	/* protocols */
   2330 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
   2331 	proto[1] = sdp_list_append(0, &l2cap_uuid);
   2332 	psm = sdp_data_alloc(SDP_UINT16, &ctrl);
   2333 	proto[1] = sdp_list_append(proto[1], psm);
   2334 	apseq = sdp_list_append(0, proto[1]);
   2335 
   2336 	sdp_uuid16_create(&hidp_uuid, HIDP_UUID);
   2337 	proto[2] = sdp_list_append(0, &hidp_uuid);
   2338 	apseq = sdp_list_append(apseq, proto[2]);
   2339 
   2340 	aproto = sdp_list_append(0, apseq);
   2341 	sdp_set_access_protos(&record, aproto);
   2342 
   2343 	/* additional protocols */
   2344 	proto[1] = sdp_list_append(0, &l2cap_uuid);
   2345 	psm = sdp_data_alloc(SDP_UINT16, &intr);
   2346 	proto[1] = sdp_list_append(proto[1], psm);
   2347 	apseq = sdp_list_append(0, proto[1]);
   2348 
   2349 	sdp_uuid16_create(&hidp_uuid, HIDP_UUID);
   2350 	proto[2] = sdp_list_append(0, &hidp_uuid);
   2351 	apseq = sdp_list_append(apseq, proto[2]);
   2352 
   2353 	aproto = sdp_list_append(0, apseq);
   2354 	sdp_set_add_access_protos(&record, aproto);
   2355 
   2356 	sdp_set_info_attr(&record, "HID Keyboard", NULL, NULL);
   2357 
   2358 	for (i = 0; i < sizeof(hid_attr) / 2; i++)
   2359 		sdp_attr_add_new(&record,
   2360 					SDP_ATTR_HID_DEVICE_RELEASE_NUMBER + i,
   2361 					SDP_UINT16, &hid_attr[i]);
   2362 
   2363 	dtds[0] = &dtd2;
   2364 	values[0] = &hid_spec_type;
   2365 	dtds[1] = &dtd_data;
   2366 	values[1] = (uint8_t *) hid_spec;
   2367 	leng[0] = 0;
   2368 	leng[1] = sizeof(hid_spec);
   2369 	hid_spec_lst = sdp_seq_alloc_with_length(dtds, values, leng, 2);
   2370 	hid_spec_lst2 = sdp_data_alloc(SDP_SEQ8, hid_spec_lst);
   2371 	sdp_attr_add(&record, SDP_ATTR_HID_DESCRIPTOR_LIST, hid_spec_lst2);
   2372 
   2373 	for (i = 0; i < sizeof(hid_attr_lang) / 2; i++) {
   2374 		dtds2[i] = &dtd;
   2375 		values2[i] = &hid_attr_lang[i];
   2376 	}
   2377 
   2378 	lang_lst = sdp_seq_alloc(dtds2, values2, sizeof(hid_attr_lang) / 2);
   2379 	lang_lst2 = sdp_data_alloc(SDP_SEQ8, lang_lst);
   2380 	sdp_attr_add(&record, SDP_ATTR_HID_LANG_ID_BASE_LIST, lang_lst2);
   2381 
   2382 	sdp_attr_add_new(&record, SDP_ATTR_HID_SDP_DISABLE, SDP_UINT16, &hid_attr2[0]);
   2383 
   2384 	for (i = 0; i < sizeof(hid_attr2) / 2 - 1; i++)
   2385 		sdp_attr_add_new(&record, SDP_ATTR_HID_REMOTE_WAKEUP + i,
   2386 						SDP_UINT16, &hid_attr2[i + 1]);
   2387 
   2388 	if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) {
   2389 		printf("Service Record registration failed\n");
   2390 		return -1;
   2391 	}
   2392 
   2393 	printf("HID keyboard service registered\n");
   2394 
   2395 	return 0;
   2396 }
   2397 
   2398 static int add_hid_wiimote(sdp_session_t *session, svc_info_t *si)
   2399 {
   2400 	sdp_record_t record;
   2401 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
   2402 	uuid_t root_uuid, hid_uuid, l2cap_uuid, hidp_uuid;
   2403 	sdp_profile_desc_t profile[1];
   2404 	sdp_list_t *aproto, *proto[3];
   2405 	sdp_data_t *psm, *lang_lst, *lang_lst2, *hid_spec_lst, *hid_spec_lst2;
   2406 	unsigned int i;
   2407 	uint8_t dtd = SDP_UINT16;
   2408 	uint8_t dtd2 = SDP_UINT8;
   2409 	uint8_t dtd_data = SDP_TEXT_STR8;
   2410 	void *dtds[2];
   2411 	void *values[2];
   2412 	void *dtds2[2];
   2413 	void *values2[2];
   2414 	int leng[2];
   2415 	uint8_t hid_spec_type = 0x22;
   2416 	uint16_t hid_attr_lang[] = { 0x409, 0x100 };
   2417 	uint16_t ctrl = 0x11, intr = 0x13;
   2418 	uint16_t hid_release = 0x0100, parser_version = 0x0111;
   2419 	uint8_t subclass = 0x04, country = 0x33;
   2420 	uint8_t virtual_cable = 0, reconnect = 1, sdp_disable = 0;
   2421 	uint8_t battery = 1, remote_wakeup = 1;
   2422 	uint16_t profile_version = 0x0100, superv_timeout = 0x0c80;
   2423 	uint8_t norm_connect = 0, boot_device = 0;
   2424 	const uint8_t hid_spec[] = {
   2425 		0x05, 0x01, 0x09, 0x05, 0xa1, 0x01, 0x85, 0x10,
   2426 		0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95,
   2427 		0x01, 0x06, 0x00, 0xff, 0x09, 0x01, 0x91, 0x00,
   2428 		0x85, 0x11, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00,
   2429 		0x85, 0x12, 0x95, 0x02, 0x09, 0x01, 0x91, 0x00,
   2430 		0x85, 0x13, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00,
   2431 		0x85, 0x14, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00,
   2432 		0x85, 0x15, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00,
   2433 		0x85, 0x16, 0x95, 0x15, 0x09, 0x01, 0x91, 0x00,
   2434 		0x85, 0x17, 0x95, 0x06, 0x09, 0x01, 0x91, 0x00,
   2435 		0x85, 0x18, 0x95, 0x15, 0x09, 0x01, 0x91, 0x00,
   2436 		0x85, 0x19, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00,
   2437 		0x85, 0x1a, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00,
   2438 		0x85, 0x20, 0x95, 0x06, 0x09, 0x01, 0x81, 0x00,
   2439 		0x85, 0x21, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00,
   2440 		0x85, 0x22, 0x95, 0x04, 0x09, 0x01, 0x81, 0x00,
   2441 		0x85, 0x30, 0x95, 0x02, 0x09, 0x01, 0x81, 0x00,
   2442 		0x85, 0x31, 0x95, 0x05, 0x09, 0x01, 0x81, 0x00,
   2443 		0x85, 0x32, 0x95, 0x0a, 0x09, 0x01, 0x81, 0x00,
   2444 		0x85, 0x33, 0x95, 0x11, 0x09, 0x01, 0x81, 0x00,
   2445 		0x85, 0x34, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00,
   2446 		0x85, 0x35, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00,
   2447 		0x85, 0x36, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00,
   2448 		0x85, 0x37, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00,
   2449 		0x85, 0x3d, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00,
   2450 		0x85, 0x3e, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00,
   2451 		0x85, 0x3f, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00,
   2452 		0xc0, 0x00
   2453 	};
   2454 
   2455 	memset(&record, 0, sizeof(sdp_record_t));
   2456 	record.handle = si->handle;
   2457 
   2458 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   2459 	root = sdp_list_append(NULL, &root_uuid);
   2460 	sdp_set_browse_groups(&record, root);
   2461 
   2462 	sdp_uuid16_create(&hid_uuid, HID_SVCLASS_ID);
   2463 	svclass_id = sdp_list_append(NULL, &hid_uuid);
   2464 	sdp_set_service_classes(&record, svclass_id);
   2465 
   2466 	sdp_uuid16_create(&profile[0].uuid, HID_PROFILE_ID);
   2467 	profile[0].version = 0x0100;
   2468 	pfseq = sdp_list_append(NULL, profile);
   2469 	sdp_set_profile_descs(&record, pfseq);
   2470 
   2471 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
   2472 	proto[1] = sdp_list_append(0, &l2cap_uuid);
   2473 	psm = sdp_data_alloc(SDP_UINT16, &ctrl);
   2474 	proto[1] = sdp_list_append(proto[1], psm);
   2475 	apseq = sdp_list_append(0, proto[1]);
   2476 
   2477 	sdp_uuid16_create(&hidp_uuid, HIDP_UUID);
   2478 	proto[2] = sdp_list_append(0, &hidp_uuid);
   2479 	apseq = sdp_list_append(apseq, proto[2]);
   2480 
   2481 	aproto = sdp_list_append(0, apseq);
   2482 	sdp_set_access_protos(&record, aproto);
   2483 
   2484 	proto[1] = sdp_list_append(0, &l2cap_uuid);
   2485 	psm = sdp_data_alloc(SDP_UINT16, &intr);
   2486 	proto[1] = sdp_list_append(proto[1], psm);
   2487 	apseq = sdp_list_append(0, proto[1]);
   2488 
   2489 	sdp_uuid16_create(&hidp_uuid, HIDP_UUID);
   2490 	proto[2] = sdp_list_append(0, &hidp_uuid);
   2491 	apseq = sdp_list_append(apseq, proto[2]);
   2492 
   2493 	aproto = sdp_list_append(0, apseq);
   2494 	sdp_set_add_access_protos(&record, aproto);
   2495 
   2496 	add_lang_attr(&record);
   2497 
   2498 	sdp_set_info_attr(&record, "Nintendo RVL-CNT-01",
   2499 					"Nintendo", "Nintendo RVL-CNT-01");
   2500 
   2501 	sdp_attr_add_new(&record, SDP_ATTR_HID_DEVICE_RELEASE_NUMBER,
   2502 						SDP_UINT16, &hid_release);
   2503 
   2504 	sdp_attr_add_new(&record, SDP_ATTR_HID_PARSER_VERSION,
   2505 						SDP_UINT16, &parser_version);
   2506 
   2507 	sdp_attr_add_new(&record, SDP_ATTR_HID_DEVICE_SUBCLASS,
   2508 						SDP_UINT8, &subclass);
   2509 
   2510 	sdp_attr_add_new(&record, SDP_ATTR_HID_COUNTRY_CODE,
   2511 						SDP_UINT8, &country);
   2512 
   2513 	sdp_attr_add_new(&record, SDP_ATTR_HID_VIRTUAL_CABLE,
   2514 						SDP_BOOL, &virtual_cable);
   2515 
   2516 	sdp_attr_add_new(&record, SDP_ATTR_HID_RECONNECT_INITIATE,
   2517 						SDP_BOOL, &reconnect);
   2518 
   2519 	dtds[0] = &dtd2;
   2520 	values[0] = &hid_spec_type;
   2521 	dtds[1] = &dtd_data;
   2522 	values[1] = (uint8_t *) hid_spec;
   2523 	leng[0] = 0;
   2524 	leng[1] = sizeof(hid_spec);
   2525 	hid_spec_lst = sdp_seq_alloc_with_length(dtds, values, leng, 2);
   2526 	hid_spec_lst2 = sdp_data_alloc(SDP_SEQ8, hid_spec_lst);
   2527 	sdp_attr_add(&record, SDP_ATTR_HID_DESCRIPTOR_LIST, hid_spec_lst2);
   2528 
   2529 	for (i = 0; i < sizeof(hid_attr_lang) / 2; i++) {
   2530 		dtds2[i] = &dtd;
   2531 		values2[i] = &hid_attr_lang[i];
   2532 	}
   2533 
   2534 	lang_lst = sdp_seq_alloc(dtds2, values2, sizeof(hid_attr_lang) / 2);
   2535 	lang_lst2 = sdp_data_alloc(SDP_SEQ8, lang_lst);
   2536 	sdp_attr_add(&record, SDP_ATTR_HID_LANG_ID_BASE_LIST, lang_lst2);
   2537 
   2538 	sdp_attr_add_new(&record, SDP_ATTR_HID_SDP_DISABLE,
   2539 						SDP_BOOL, &sdp_disable);
   2540 
   2541 	sdp_attr_add_new(&record, SDP_ATTR_HID_BATTERY_POWER,
   2542 						SDP_BOOL, &battery);
   2543 
   2544 	sdp_attr_add_new(&record, SDP_ATTR_HID_REMOTE_WAKEUP,
   2545 						SDP_BOOL, &remote_wakeup);
   2546 
   2547 	sdp_attr_add_new(&record, SDP_ATTR_HID_PROFILE_VERSION,
   2548 						SDP_UINT16, &profile_version);
   2549 
   2550 	sdp_attr_add_new(&record, SDP_ATTR_HID_SUPERVISION_TIMEOUT,
   2551 						SDP_UINT16, &superv_timeout);
   2552 
   2553 	sdp_attr_add_new(&record, SDP_ATTR_HID_NORMALLY_CONNECTABLE,
   2554 						SDP_BOOL, &norm_connect);
   2555 
   2556 	sdp_attr_add_new(&record, SDP_ATTR_HID_BOOT_DEVICE,
   2557 						SDP_BOOL, &boot_device);
   2558 
   2559 	if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) {
   2560 		printf("Service Record registration failed\n");
   2561 		return -1;
   2562 	}
   2563 
   2564 	printf("Wii-Mote service registered\n");
   2565 
   2566 	return 0;
   2567 }
   2568 
   2569 static int add_cip(sdp_session_t *session, svc_info_t *si)
   2570 {
   2571 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
   2572 	uuid_t root_uuid, l2cap, cmtp, cip;
   2573 	sdp_profile_desc_t profile[1];
   2574 	sdp_list_t *aproto, *proto[2];
   2575 	sdp_record_t record;
   2576 	uint16_t psm = si->psm ? si->psm : 0x1001;
   2577 	uint8_t netid = si->network ? si->network : 0x02; // 0x02 = ISDN, 0x03 = GSM
   2578 	sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid);
   2579 	int ret = 0;
   2580 
   2581 	memset(&record, 0, sizeof(sdp_record_t));
   2582 	record.handle = si->handle;
   2583 
   2584 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   2585 	root = sdp_list_append(0, &root_uuid);
   2586 	sdp_set_browse_groups(&record, root);
   2587 
   2588 	sdp_uuid16_create(&cip, CIP_SVCLASS_ID);
   2589 	svclass_id = sdp_list_append(0, &cip);
   2590 	sdp_set_service_classes(&record, svclass_id);
   2591 
   2592 	sdp_uuid16_create(&profile[0].uuid, CIP_PROFILE_ID);
   2593 	profile[0].version = 0x0100;
   2594 	pfseq = sdp_list_append(0, &profile[0]);
   2595 	sdp_set_profile_descs(&record, pfseq);
   2596 
   2597 	sdp_uuid16_create(&l2cap, L2CAP_UUID);
   2598 	proto[0] = sdp_list_append(0, &l2cap);
   2599 	apseq = sdp_list_append(0, proto[0]);
   2600 	proto[0] = sdp_list_append(proto[0], sdp_data_alloc(SDP_UINT16, &psm));
   2601 	apseq = sdp_list_append(0, proto[0]);
   2602 
   2603 	sdp_uuid16_create(&cmtp, CMTP_UUID);
   2604 	proto[1] = sdp_list_append(0, &cmtp);
   2605 	apseq = sdp_list_append(apseq, proto[1]);
   2606 
   2607 	aproto = sdp_list_append(0, apseq);
   2608 	sdp_set_access_protos(&record, aproto);
   2609 
   2610 	sdp_attr_add(&record, SDP_ATTR_EXTERNAL_NETWORK, network);
   2611 
   2612 	sdp_set_info_attr(&record, "Common ISDN Access", 0, 0);
   2613 
   2614 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   2615 		printf("Service Record registration failed\n");
   2616 		ret = -1;
   2617 		goto end;
   2618 	}
   2619 
   2620 	printf("CIP service registered\n");
   2621 
   2622 end:
   2623 	sdp_list_free(proto[0], 0);
   2624 	sdp_list_free(proto[1], 0);
   2625 	sdp_list_free(apseq, 0);
   2626 	sdp_list_free(aproto, 0);
   2627 	sdp_data_free(network);
   2628 
   2629 	return ret;
   2630 }
   2631 
   2632 static int add_ctp(sdp_session_t *session, svc_info_t *si)
   2633 {
   2634 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
   2635 	uuid_t root_uuid, l2cap, tcsbin, ctp;
   2636 	sdp_profile_desc_t profile[1];
   2637 	sdp_list_t *aproto, *proto[2];
   2638 	sdp_record_t record;
   2639 	uint8_t netid = si->network ? si->network : 0x02; // 0x01-0x07 cf. p120 profile document
   2640 	sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid);
   2641 	int ret = 0;
   2642 
   2643 	memset(&record, 0, sizeof(sdp_record_t));
   2644 	record.handle = si->handle;
   2645 
   2646 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   2647 	root = sdp_list_append(0, &root_uuid);
   2648 	sdp_set_browse_groups(&record, root);
   2649 
   2650 	sdp_uuid16_create(&ctp, CORDLESS_TELEPHONY_SVCLASS_ID);
   2651 	svclass_id = sdp_list_append(0, &ctp);
   2652 	sdp_set_service_classes(&record, svclass_id);
   2653 
   2654 	sdp_uuid16_create(&profile[0].uuid, CORDLESS_TELEPHONY_PROFILE_ID);
   2655 	profile[0].version = 0x0100;
   2656 	pfseq = sdp_list_append(0, &profile[0]);
   2657 	sdp_set_profile_descs(&record, pfseq);
   2658 
   2659 	sdp_uuid16_create(&l2cap, L2CAP_UUID);
   2660 	proto[0] = sdp_list_append(0, &l2cap);
   2661 	apseq = sdp_list_append(0, proto[0]);
   2662 
   2663 	sdp_uuid16_create(&tcsbin, TCS_BIN_UUID);
   2664 	proto[1] = sdp_list_append(0, &tcsbin);
   2665 	apseq = sdp_list_append(apseq, proto[1]);
   2666 
   2667 	aproto = sdp_list_append(0, apseq);
   2668 	sdp_set_access_protos(&record, aproto);
   2669 
   2670 	sdp_attr_add(&record, SDP_ATTR_EXTERNAL_NETWORK, network);
   2671 
   2672 	sdp_set_info_attr(&record, "Cordless Telephony", 0, 0);
   2673 
   2674 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   2675 		printf("Service Record registration failed\n");
   2676 		ret = -1;
   2677 		goto end;
   2678 	}
   2679 
   2680 	printf("CTP service registered\n");
   2681 
   2682 end:
   2683 	sdp_list_free(proto[0], 0);
   2684 	sdp_list_free(proto[1], 0);
   2685 	sdp_list_free(apseq, 0);
   2686 	sdp_list_free(aproto, 0);
   2687 	sdp_data_free(network);
   2688 
   2689 	return ret;
   2690 }
   2691 
   2692 static int add_a2source(sdp_session_t *session, svc_info_t *si)
   2693 {
   2694 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
   2695 	uuid_t root_uuid, l2cap, avdtp, a2src;
   2696 	sdp_profile_desc_t profile[1];
   2697 	sdp_list_t *aproto, *proto[2];
   2698 	sdp_record_t record;
   2699 	sdp_data_t *psm, *version;
   2700 	uint16_t lp = 0x0019, ver = 0x0100;
   2701 	int ret = 0;
   2702 
   2703 	memset(&record, 0, sizeof(sdp_record_t));
   2704 	record.handle = si->handle;
   2705 
   2706 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   2707 	root = sdp_list_append(0, &root_uuid);
   2708 	sdp_set_browse_groups(&record, root);
   2709 
   2710 	sdp_uuid16_create(&a2src, AUDIO_SOURCE_SVCLASS_ID);
   2711 	svclass_id = sdp_list_append(0, &a2src);
   2712 	sdp_set_service_classes(&record, svclass_id);
   2713 
   2714 	sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID);
   2715 	profile[0].version = 0x0100;
   2716 	pfseq = sdp_list_append(0, &profile[0]);
   2717 	sdp_set_profile_descs(&record, pfseq);
   2718 
   2719 	sdp_uuid16_create(&l2cap, L2CAP_UUID);
   2720 	proto[0] = sdp_list_append(0, &l2cap);
   2721 	psm = sdp_data_alloc(SDP_UINT16, &lp);
   2722 	proto[0] = sdp_list_append(proto[0], psm);
   2723 	apseq = sdp_list_append(0, proto[0]);
   2724 
   2725 	sdp_uuid16_create(&avdtp, AVDTP_UUID);
   2726 	proto[1] = sdp_list_append(0, &avdtp);
   2727 	version = sdp_data_alloc(SDP_UINT16, &ver);
   2728 	proto[1] = sdp_list_append(proto[1], version);
   2729 	apseq = sdp_list_append(apseq, proto[1]);
   2730 
   2731 	aproto = sdp_list_append(0, apseq);
   2732 	sdp_set_access_protos(&record, aproto);
   2733 
   2734 	sdp_set_info_attr(&record, "Audio Source", 0, 0);
   2735 
   2736 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   2737 		printf("Service Record registration failed\n");
   2738 		ret = -1;
   2739 		goto done;
   2740 	}
   2741 
   2742 	printf("Audio source service registered\n");
   2743 
   2744 done:
   2745 	sdp_list_free(proto[0], 0);
   2746 	sdp_list_free(proto[1], 0);
   2747 	sdp_list_free(apseq, 0);
   2748 	sdp_list_free(aproto, 0);
   2749 
   2750 	return ret;
   2751 }
   2752 
   2753 static int add_a2sink(sdp_session_t *session, svc_info_t *si)
   2754 {
   2755 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
   2756 	uuid_t root_uuid, l2cap, avdtp, a2snk;
   2757 	sdp_profile_desc_t profile[1];
   2758 	sdp_list_t *aproto, *proto[2];
   2759 	sdp_record_t record;
   2760 	sdp_data_t *psm, *version;
   2761 	uint16_t lp = 0x0019, ver = 0x0100;
   2762 	int ret = 0;
   2763 
   2764 	memset(&record, 0, sizeof(sdp_record_t));
   2765 	record.handle = si->handle;
   2766 
   2767 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   2768 	root = sdp_list_append(0, &root_uuid);
   2769 	sdp_set_browse_groups(&record, root);
   2770 
   2771 	sdp_uuid16_create(&a2snk, AUDIO_SINK_SVCLASS_ID);
   2772 	svclass_id = sdp_list_append(0, &a2snk);
   2773 	sdp_set_service_classes(&record, svclass_id);
   2774 
   2775 	sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID);
   2776 	profile[0].version = 0x0100;
   2777 	pfseq = sdp_list_append(0, &profile[0]);
   2778 	sdp_set_profile_descs(&record, pfseq);
   2779 
   2780 	sdp_uuid16_create(&l2cap, L2CAP_UUID);
   2781 	proto[0] = sdp_list_append(0, &l2cap);
   2782 	psm = sdp_data_alloc(SDP_UINT16, &lp);
   2783 	proto[0] = sdp_list_append(proto[0], psm);
   2784 	apseq = sdp_list_append(0, proto[0]);
   2785 
   2786 	sdp_uuid16_create(&avdtp, AVDTP_UUID);
   2787 	proto[1] = sdp_list_append(0, &avdtp);
   2788 	version = sdp_data_alloc(SDP_UINT16, &ver);
   2789 	proto[1] = sdp_list_append(proto[1], version);
   2790 	apseq = sdp_list_append(apseq, proto[1]);
   2791 
   2792 	aproto = sdp_list_append(0, apseq);
   2793 	sdp_set_access_protos(&record, aproto);
   2794 
   2795 	sdp_set_info_attr(&record, "Audio Sink", 0, 0);
   2796 
   2797 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   2798 		printf("Service Record registration failed\n");
   2799 		ret = -1;
   2800 		goto done;
   2801 	}
   2802 
   2803 	printf("Audio sink service registered\n");
   2804 
   2805 done:
   2806 	sdp_list_free(proto[0], 0);
   2807 	sdp_list_free(proto[1], 0);
   2808 	sdp_list_free(apseq, 0);
   2809 	sdp_list_free(aproto, 0);
   2810 
   2811 	return ret;
   2812 }
   2813 
   2814 static int add_avrct(sdp_session_t *session, svc_info_t *si)
   2815 {
   2816 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
   2817 	uuid_t root_uuid, l2cap, avctp, avrct;
   2818 	sdp_profile_desc_t profile[1];
   2819 	sdp_list_t *aproto, *proto[2];
   2820 	sdp_record_t record;
   2821 	sdp_data_t *psm, *version, *features;
   2822 	uint16_t lp = 0x0017, ver = 0x0100, feat = 0x000f;
   2823 	int ret = 0;
   2824 
   2825 	memset(&record, 0, sizeof(sdp_record_t));
   2826 	record.handle = si->handle;
   2827 
   2828 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   2829 	root = sdp_list_append(0, &root_uuid);
   2830 	sdp_set_browse_groups(&record, root);
   2831 
   2832 	sdp_uuid16_create(&avrct, AV_REMOTE_SVCLASS_ID);
   2833 	svclass_id = sdp_list_append(0, &avrct);
   2834 	sdp_set_service_classes(&record, svclass_id);
   2835 
   2836 	sdp_uuid16_create(&profile[0].uuid, AV_REMOTE_PROFILE_ID);
   2837 	profile[0].version = 0x0100;
   2838 	pfseq = sdp_list_append(0, &profile[0]);
   2839 	sdp_set_profile_descs(&record, pfseq);
   2840 
   2841 	sdp_uuid16_create(&l2cap, L2CAP_UUID);
   2842 	proto[0] = sdp_list_append(0, &l2cap);
   2843 	psm = sdp_data_alloc(SDP_UINT16, &lp);
   2844 	proto[0] = sdp_list_append(proto[0], psm);
   2845 	apseq = sdp_list_append(0, proto[0]);
   2846 
   2847 	sdp_uuid16_create(&avctp, AVCTP_UUID);
   2848 	proto[1] = sdp_list_append(0, &avctp);
   2849 	version = sdp_data_alloc(SDP_UINT16, &ver);
   2850 	proto[1] = sdp_list_append(proto[1], version);
   2851 	apseq = sdp_list_append(apseq, proto[1]);
   2852 
   2853 	aproto = sdp_list_append(0, apseq);
   2854 	sdp_set_access_protos(&record, aproto);
   2855 
   2856 	features = sdp_data_alloc(SDP_UINT16, &feat);
   2857 	sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features);
   2858 
   2859 	sdp_set_info_attr(&record, "AVRCP CT", 0, 0);
   2860 
   2861 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   2862 		printf("Service Record registration failed\n");
   2863 		ret = -1;
   2864 		goto done;
   2865 	}
   2866 
   2867 	printf("Remote control service registered\n");
   2868 
   2869 done:
   2870 	sdp_list_free(proto[0], 0);
   2871 	sdp_list_free(proto[1], 0);
   2872 	sdp_list_free(apseq, 0);
   2873 	sdp_list_free(aproto, 0);
   2874 
   2875 	return ret;
   2876 }
   2877 
   2878 static int add_avrtg(sdp_session_t *session, svc_info_t *si)
   2879 {
   2880 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
   2881 	uuid_t root_uuid, l2cap, avctp, avrtg;
   2882 	sdp_profile_desc_t profile[1];
   2883 	sdp_list_t *aproto, *proto[2];
   2884 	sdp_record_t record;
   2885 	sdp_data_t *psm, *version, *features;
   2886 	uint16_t lp = 0x0017, ver = 0x0100, feat = 0x000f;
   2887 	int ret = 0;
   2888 
   2889 	memset(&record, 0, sizeof(sdp_record_t));
   2890 	record.handle = si->handle;
   2891 
   2892 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   2893 	root = sdp_list_append(0, &root_uuid);
   2894 	sdp_set_browse_groups(&record, root);
   2895 
   2896 	sdp_uuid16_create(&avrtg, AV_REMOTE_TARGET_SVCLASS_ID);
   2897 	svclass_id = sdp_list_append(0, &avrtg);
   2898 	sdp_set_service_classes(&record, svclass_id);
   2899 
   2900 	sdp_uuid16_create(&profile[0].uuid, AV_REMOTE_PROFILE_ID);
   2901 	profile[0].version = 0x0100;
   2902 	pfseq = sdp_list_append(0, &profile[0]);
   2903 	sdp_set_profile_descs(&record, pfseq);
   2904 
   2905 	sdp_uuid16_create(&l2cap, L2CAP_UUID);
   2906 	proto[0] = sdp_list_append(0, &l2cap);
   2907 	psm = sdp_data_alloc(SDP_UINT16, &lp);
   2908 	proto[0] = sdp_list_append(proto[0], psm);
   2909 	apseq = sdp_list_append(0, proto[0]);
   2910 
   2911 	sdp_uuid16_create(&avctp, AVCTP_UUID);
   2912 	proto[1] = sdp_list_append(0, &avctp);
   2913 	version = sdp_data_alloc(SDP_UINT16, &ver);
   2914 	proto[1] = sdp_list_append(proto[1], version);
   2915 	apseq = sdp_list_append(apseq, proto[1]);
   2916 
   2917 	aproto = sdp_list_append(0, apseq);
   2918 	sdp_set_access_protos(&record, aproto);
   2919 
   2920 	features = sdp_data_alloc(SDP_UINT16, &feat);
   2921 	sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features);
   2922 
   2923 	sdp_set_info_attr(&record, "AVRCP TG", 0, 0);
   2924 
   2925 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   2926 		printf("Service Record registration failed\n");
   2927 		ret = -1;
   2928 		goto done;
   2929 	}
   2930 
   2931 	printf("Remote target service registered\n");
   2932 
   2933 done:
   2934 	sdp_list_free(proto[0], 0);
   2935 	sdp_list_free(proto[1], 0);
   2936 	sdp_list_free(apseq, 0);
   2937 	sdp_list_free(aproto, 0);
   2938 
   2939 	return ret;
   2940 }
   2941 
   2942 static int add_udi_ue(sdp_session_t *session, svc_info_t *si)
   2943 {
   2944 	sdp_record_t record;
   2945 	sdp_list_t *root, *svclass, *proto;
   2946 	uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid;
   2947 	uint8_t channel = si->channel ? si->channel: 18;
   2948 
   2949 	memset(&record, 0, sizeof(record));
   2950 	record.handle = si->handle;
   2951 
   2952 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   2953 	root = sdp_list_append(NULL, &root_uuid);
   2954 	sdp_set_browse_groups(&record, root);
   2955 	sdp_list_free(root, NULL);
   2956 
   2957 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
   2958 	proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid));
   2959 
   2960 	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
   2961 	proto = sdp_list_append(proto, sdp_list_append(
   2962 		sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel)));
   2963 
   2964 	sdp_set_access_protos(&record, sdp_list_append(NULL, proto));
   2965 
   2966 	sdp_uuid16_create(&svclass_uuid, UDI_MT_SVCLASS_ID);
   2967 	svclass = sdp_list_append(NULL, &svclass_uuid);
   2968 	sdp_set_service_classes(&record, svclass);
   2969 	sdp_list_free(svclass, NULL);
   2970 
   2971 	sdp_set_info_attr(&record, "UDI UE", NULL, NULL);
   2972 
   2973 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   2974 		printf("Service Record registration failed\n");
   2975 		return -1;
   2976 	}
   2977 
   2978 	printf("UDI UE service registered\n");
   2979 
   2980 	return 0;
   2981 }
   2982 
   2983 static int add_udi_te(sdp_session_t *session, svc_info_t *si)
   2984 {
   2985 	sdp_record_t record;
   2986 	sdp_list_t *root, *svclass, *proto;
   2987 	uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid;
   2988 	uint8_t channel = si->channel ? si->channel: 19;
   2989 
   2990 	memset(&record, 0, sizeof(record));
   2991 	record.handle = si->handle;
   2992 
   2993 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   2994 	root = sdp_list_append(NULL, &root_uuid);
   2995 	sdp_set_browse_groups(&record, root);
   2996 	sdp_list_free(root, NULL);
   2997 
   2998 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
   2999 	proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid));
   3000 
   3001 	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
   3002 	proto = sdp_list_append(proto, sdp_list_append(
   3003 		sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel)));
   3004 
   3005 	sdp_set_access_protos(&record, sdp_list_append(NULL, proto));
   3006 
   3007 	sdp_uuid16_create(&svclass_uuid, UDI_TA_SVCLASS_ID);
   3008 	svclass = sdp_list_append(NULL, &svclass_uuid);
   3009 	sdp_set_service_classes(&record, svclass);
   3010 	sdp_list_free(svclass, NULL);
   3011 
   3012 	sdp_set_info_attr(&record, "UDI TE", NULL, NULL);
   3013 
   3014 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   3015 		printf("Service Record registration failed\n");
   3016 		return -1;
   3017 	}
   3018 
   3019 	printf("UDI TE service registered\n");
   3020 
   3021 	return 0;
   3022 }
   3023 
   3024 static unsigned char sr1_uuid[] = {	0xbc, 0x19, 0x9c, 0x24, 0x95, 0x8b, 0x4c, 0xc0,
   3025 					0xa2, 0xcb, 0xfd, 0x8a, 0x30, 0xbf, 0x32, 0x06 };
   3026 
   3027 static int add_sr1(sdp_session_t *session, svc_info_t *si)
   3028 {
   3029 	sdp_record_t record;
   3030 	sdp_list_t *root, *svclass;
   3031 	uuid_t root_uuid, svclass_uuid;
   3032 
   3033 	memset(&record, 0, sizeof(record));
   3034 	record.handle = si->handle;
   3035 
   3036 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   3037 	root = sdp_list_append(NULL, &root_uuid);
   3038 	sdp_set_browse_groups(&record, root);
   3039 
   3040 	sdp_uuid128_create(&svclass_uuid, (void *) sr1_uuid);
   3041 	svclass = sdp_list_append(NULL, &svclass_uuid);
   3042 	sdp_set_service_classes(&record, svclass);
   3043 
   3044 	sdp_set_info_attr(&record, "TOSHIBA SR-1", NULL, NULL);
   3045 
   3046 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   3047 		printf("Service Record registration failed\n");
   3048 		return -1;
   3049 	}
   3050 
   3051 	printf("Toshiba Speech Recognition SR-1 service record registered\n");
   3052 
   3053 	return 0;
   3054 }
   3055 
   3056 static unsigned char syncmls_uuid[] = {	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00,
   3057 					0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x02 };
   3058 
   3059 static unsigned char syncmlc_uuid[] = {	0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x10, 0x00,
   3060 					0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x02 };
   3061 
   3062 static int add_syncml(sdp_session_t *session, svc_info_t *si)
   3063 {
   3064 	sdp_record_t record;
   3065 	sdp_list_t *root, *svclass, *proto;
   3066 	uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid;
   3067 	uint8_t channel = si->channel ? si->channel: 15;
   3068 
   3069 	memset(&record, 0, sizeof(record));
   3070 	record.handle = si->handle;
   3071 
   3072 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   3073 	root = sdp_list_append(NULL, &root_uuid);
   3074 	sdp_set_browse_groups(&record, root);
   3075 
   3076 	sdp_uuid128_create(&svclass_uuid, (void *) syncmlc_uuid);
   3077 	svclass = sdp_list_append(NULL, &svclass_uuid);
   3078 	sdp_set_service_classes(&record, svclass);
   3079 
   3080 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
   3081 	proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid));
   3082 
   3083 	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
   3084 	proto = sdp_list_append(proto, sdp_list_append(
   3085 		sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel)));
   3086 
   3087 	sdp_uuid16_create(&obex_uuid, OBEX_UUID);
   3088 	proto = sdp_list_append(proto, sdp_list_append(NULL, &obex_uuid));
   3089 
   3090 	sdp_set_access_protos(&record, sdp_list_append(NULL, proto));
   3091 
   3092 	sdp_set_info_attr(&record, "SyncML Client", NULL, NULL);
   3093 
   3094 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   3095 		printf("Service Record registration failed\n");
   3096 		return -1;
   3097 	}
   3098 
   3099 	printf("SyncML Client service record registered\n");
   3100 
   3101 	return 0;
   3102 }
   3103 
   3104 static unsigned char async_uuid[] = {	0x03, 0x50, 0x27, 0x8F, 0x3D, 0xCA, 0x4E, 0x62,
   3105 					0x83, 0x1D, 0xA4, 0x11, 0x65, 0xFF, 0x90, 0x6C };
   3106 
   3107 static int add_activesync(sdp_session_t *session, svc_info_t *si)
   3108 {
   3109 	sdp_record_t record;
   3110 	sdp_list_t *root, *svclass, *proto;
   3111 	uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid;
   3112 	uint8_t channel = si->channel ? si->channel: 21;
   3113 
   3114 	memset(&record, 0, sizeof(record));
   3115 	record.handle = si->handle;
   3116 
   3117 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   3118 	root = sdp_list_append(NULL, &root_uuid);
   3119 	sdp_set_browse_groups(&record, root);
   3120 
   3121 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
   3122 	proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid));
   3123 
   3124 	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
   3125 	proto = sdp_list_append(proto, sdp_list_append(
   3126 	sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel)));
   3127 
   3128 	sdp_set_access_protos(&record, sdp_list_append(NULL, proto));
   3129 
   3130 	sdp_uuid128_create(&svclass_uuid, (void *) async_uuid);
   3131 	svclass = sdp_list_append(NULL, &svclass_uuid);
   3132 	sdp_set_service_classes(&record, svclass);
   3133 
   3134 	sdp_set_info_attr(&record, "Microsoft ActiveSync", NULL, NULL);
   3135 
   3136 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   3137 		printf("Service Record registration failed\n");
   3138 		return -1;
   3139 	}
   3140 
   3141 	printf("ActiveSync service record registered\n");
   3142 
   3143 	return 0;
   3144 }
   3145 
   3146 static unsigned char hotsync_uuid[] = {	0xD8, 0x0C, 0xF9, 0xEA, 0x13, 0x4C, 0x11, 0xD5,
   3147 					0x83, 0xCE, 0x00, 0x30, 0x65, 0x7C, 0x54, 0x3C };
   3148 
   3149 static int add_hotsync(sdp_session_t *session, svc_info_t *si)
   3150 {
   3151 	sdp_record_t record;
   3152 	sdp_list_t *root, *svclass, *proto;
   3153 	uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid;
   3154 	uint8_t channel = si->channel ? si->channel: 22;
   3155 
   3156 	memset(&record, 0, sizeof(record));
   3157 	record.handle = si->handle;
   3158 
   3159 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   3160 	root = sdp_list_append(NULL, &root_uuid);
   3161 	sdp_set_browse_groups(&record, root);
   3162 
   3163 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
   3164 	proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid));
   3165 
   3166 	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
   3167 	proto = sdp_list_append(proto, sdp_list_append(
   3168 	sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel)));
   3169 
   3170 	sdp_set_access_protos(&record, sdp_list_append(NULL, proto));
   3171 
   3172 	sdp_uuid128_create(&svclass_uuid, (void *) hotsync_uuid);
   3173 	svclass = sdp_list_append(NULL, &svclass_uuid);
   3174 	sdp_set_service_classes(&record, svclass);
   3175 
   3176 	sdp_set_info_attr(&record, "PalmOS HotSync", NULL, NULL);
   3177 
   3178 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   3179 		printf("Service Record registration failed\n");
   3180 		return -1;
   3181 	}
   3182 
   3183 	printf("HotSync service record registered\n");
   3184 
   3185 	return 0;
   3186 }
   3187 
   3188 static unsigned char palmos_uuid[] = {	0xF5, 0xBE, 0xB6, 0x51, 0x41, 0x71, 0x40, 0x51,
   3189 					0xAC, 0xF5, 0x6C, 0xA7, 0x20, 0x22, 0x42, 0xF0 };
   3190 
   3191 static int add_palmos(sdp_session_t *session, svc_info_t *si)
   3192 {
   3193 	sdp_record_t record;
   3194 	sdp_list_t *root, *svclass;
   3195 	uuid_t root_uuid, svclass_uuid;
   3196 
   3197 	memset(&record, 0, sizeof(record));
   3198 	record.handle = si->handle;
   3199 
   3200 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   3201 	root = sdp_list_append(NULL, &root_uuid);
   3202 	sdp_set_browse_groups(&record, root);
   3203 
   3204 	sdp_uuid128_create(&svclass_uuid, (void *) palmos_uuid);
   3205 	svclass = sdp_list_append(NULL, &svclass_uuid);
   3206 	sdp_set_service_classes(&record, svclass);
   3207 
   3208 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   3209 		printf("Service Record registration failed\n");
   3210 		return -1;
   3211 	}
   3212 
   3213 	printf("PalmOS service record registered\n");
   3214 
   3215 	return 0;
   3216 }
   3217 
   3218 static unsigned char nokid_uuid[] = {	0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x10, 0x00,
   3219 					0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 };
   3220 
   3221 static int add_nokiaid(sdp_session_t *session, svc_info_t *si)
   3222 {
   3223 	sdp_record_t record;
   3224 	sdp_list_t *root, *svclass;
   3225 	uuid_t root_uuid, svclass_uuid;
   3226 	uint16_t verid = 0x005f;
   3227 	sdp_data_t *version = sdp_data_alloc(SDP_UINT16, &verid);
   3228 
   3229 	memset(&record, 0, sizeof(record));
   3230 	record.handle = si->handle;
   3231 
   3232 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   3233 	root = sdp_list_append(NULL, &root_uuid);
   3234 	sdp_set_browse_groups(&record, root);
   3235 
   3236 	sdp_uuid128_create(&svclass_uuid, (void *) nokid_uuid);
   3237 	svclass = sdp_list_append(NULL, &svclass_uuid);
   3238 	sdp_set_service_classes(&record, svclass);
   3239 
   3240 	sdp_attr_add(&record, SDP_ATTR_SERVICE_VERSION, version);
   3241 
   3242 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   3243 		printf("Service Record registration failed\n");
   3244 		sdp_data_free(version);
   3245 		return -1;
   3246 	}
   3247 
   3248 	printf("Nokia ID service record registered\n");
   3249 
   3250 	return 0;
   3251 }
   3252 
   3253 static unsigned char pcsuite_uuid[] = {	0x00, 0x00, 0x50, 0x02, 0x00, 0x00, 0x10, 0x00,
   3254 					0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 };
   3255 
   3256 static int add_pcsuite(sdp_session_t *session, svc_info_t *si)
   3257 {
   3258 	sdp_record_t record;
   3259 	sdp_list_t *root, *svclass, *proto;
   3260 	uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid;
   3261 	uint8_t channel = si->channel ? si->channel: 14;
   3262 
   3263 	memset(&record, 0, sizeof(record));
   3264 	record.handle = si->handle;
   3265 
   3266 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   3267 	root = sdp_list_append(NULL, &root_uuid);
   3268 	sdp_set_browse_groups(&record, root);
   3269 
   3270 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
   3271 	proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid));
   3272 
   3273 	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
   3274 	proto = sdp_list_append(proto, sdp_list_append(
   3275 		sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel)));
   3276 
   3277 	sdp_set_access_protos(&record, sdp_list_append(NULL, proto));
   3278 
   3279 	sdp_uuid128_create(&svclass_uuid, (void *) pcsuite_uuid);
   3280 	svclass = sdp_list_append(NULL, &svclass_uuid);
   3281 	sdp_set_service_classes(&record, svclass);
   3282 
   3283 	sdp_set_info_attr(&record, "Nokia PC Suite", NULL, NULL);
   3284 
   3285 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   3286 		printf("Service Record registration failed\n");
   3287 		return -1;
   3288 	}
   3289 
   3290 	printf("Nokia PC Suite service registered\n");
   3291 
   3292 	return 0;
   3293 }
   3294 
   3295 static unsigned char nftp_uuid[] = {	0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x10, 0x00,
   3296 					0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 };
   3297 
   3298 static unsigned char nsyncml_uuid[] = {	0x00, 0x00, 0x56, 0x01, 0x00, 0x00, 0x10, 0x00,
   3299 					0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 };
   3300 
   3301 static unsigned char ngage_uuid[] = {	0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x10, 0x00,
   3302 					0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 };
   3303 
   3304 static unsigned char apple_uuid[] = {	0xf0, 0x72, 0x2e, 0x20, 0x0f, 0x8b, 0x4e, 0x90,
   3305 					0x8c, 0xc2, 0x1b, 0x46, 0xf5, 0xf2, 0xef, 0xe2 };
   3306 
   3307 static int add_apple(sdp_session_t *session, svc_info_t *si)
   3308 {
   3309 	sdp_record_t record;
   3310 	sdp_list_t *root;
   3311 	uuid_t root_uuid;
   3312 	uint32_t attr783 = 0x00000000;
   3313 	uint32_t attr785 = 0x00000002;
   3314 	uint16_t attr786 = 0x1234;
   3315 
   3316 	memset(&record, 0, sizeof(record));
   3317 	record.handle = si->handle;
   3318 
   3319 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   3320 	root = sdp_list_append(NULL, &root_uuid);
   3321 	sdp_set_browse_groups(&record, root);
   3322 
   3323 	sdp_attr_add_new(&record, 0x0780, SDP_UUID128, (void *) apple_uuid);
   3324 	sdp_attr_add_new(&record, 0x0781, SDP_TEXT_STR8, (void *) "Macmini");
   3325 	sdp_attr_add_new(&record, 0x0782, SDP_TEXT_STR8, (void *) "PowerMac10,1");
   3326 	sdp_attr_add_new(&record, 0x0783, SDP_UINT32, (void *) &attr783);
   3327 	sdp_attr_add_new(&record, 0x0784, SDP_TEXT_STR8, (void *) "1.6.6f22");
   3328 	sdp_attr_add_new(&record, 0x0785, SDP_UINT32, (void *) &attr785);
   3329 	sdp_attr_add_new(&record, 0x0786, SDP_UUID16, (void *) &attr786);
   3330 
   3331 	sdp_set_info_attr(&record, "Apple Macintosh Attributes", NULL, NULL);
   3332 
   3333 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   3334 		printf("Service Record registration failed\n");
   3335 		return -1;
   3336 	}
   3337 
   3338 	printf("Apple attribute service registered\n");
   3339 
   3340 	return 0;
   3341 }
   3342 
   3343 static int add_isync(sdp_session_t *session, svc_info_t *si)
   3344 {
   3345 	sdp_record_t record;
   3346 	sdp_list_t *root, *svclass, *proto;
   3347 	uuid_t root_uuid, svclass_uuid, serial_uuid, l2cap_uuid, rfcomm_uuid;
   3348 	uint8_t channel = si->channel ? si->channel : 16;
   3349 
   3350 	memset(&record, 0, sizeof(record));
   3351 	record.handle = si->handle;
   3352 
   3353 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   3354 	root = sdp_list_append(NULL, &root_uuid);
   3355 	sdp_set_browse_groups(&record, root);
   3356 
   3357 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
   3358 	proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid));
   3359 
   3360 	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
   3361 	proto = sdp_list_append(proto, sdp_list_append(
   3362 		sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel)));
   3363 
   3364 	sdp_set_access_protos(&record, sdp_list_append(NULL, proto));
   3365 
   3366 	sdp_uuid16_create(&serial_uuid, SERIAL_PORT_SVCLASS_ID);
   3367 	svclass = sdp_list_append(NULL, &serial_uuid);
   3368 
   3369 	sdp_uuid16_create(&svclass_uuid, APPLE_AGENT_SVCLASS_ID);
   3370 	svclass = sdp_list_append(svclass, &svclass_uuid);
   3371 
   3372 	sdp_set_service_classes(&record, svclass);
   3373 
   3374 	sdp_set_info_attr(&record, "AppleAgent", "Bluetooth acceptor", "Apple Computer Ltd.");
   3375 
   3376 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   3377 		printf("Service Record registration failed\n");
   3378 		return -1;
   3379 	}
   3380 
   3381 	printf("Apple iSync service registered\n");
   3382 
   3383 	return 0;
   3384 }
   3385 
   3386 static int add_semchla(sdp_session_t *session, svc_info_t *si)
   3387 {
   3388 	sdp_record_t record;
   3389 	sdp_profile_desc_t profile;
   3390 	sdp_list_t *root, *svclass, *proto, *profiles;
   3391 	uuid_t root_uuid, service_uuid, l2cap_uuid, semchla_uuid;
   3392 	uint16_t psm = 0xf0f9;
   3393 
   3394 	memset(&record, 0, sizeof(record));
   3395 	record.handle = si->handle;
   3396 
   3397 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
   3398 	root = sdp_list_append(NULL, &root_uuid);
   3399 	sdp_set_browse_groups(&record, root);
   3400 
   3401 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
   3402 	proto = sdp_list_append(NULL, sdp_list_append(
   3403 		sdp_list_append(NULL, &l2cap_uuid), sdp_data_alloc(SDP_UINT16, &psm)));
   3404 
   3405 	sdp_uuid32_create(&semchla_uuid, 0x8e770300);
   3406 	proto = sdp_list_append(proto, sdp_list_append(NULL, &semchla_uuid));
   3407 
   3408 	sdp_set_access_protos(&record, sdp_list_append(NULL, proto));
   3409 
   3410 	sdp_uuid32_create(&service_uuid, 0x8e771301);
   3411 	svclass = sdp_list_append(NULL, &service_uuid);
   3412 
   3413 	sdp_set_service_classes(&record, svclass);
   3414 
   3415 	sdp_uuid32_create(&profile.uuid, 0x8e771302);	// Headset
   3416 	//sdp_uuid32_create(&profile.uuid, 0x8e771303);	// Phone
   3417 	profile.version = 0x0100;
   3418 	profiles = sdp_list_append(NULL, &profile);
   3419 	sdp_set_profile_descs(&record, profiles);
   3420 
   3421 	sdp_set_info_attr(&record, "SEMC HLA", NULL, NULL);
   3422 
   3423 	if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) {
   3424 		printf("Service Record registration failed\n");
   3425 		return -1;
   3426 	}
   3427 
   3428 	/* SEMC High Level Authentication */
   3429 	printf("SEMC HLA service registered\n");
   3430 
   3431 	return 0;
   3432 }
   3433 
   3434 struct {
   3435 	char		*name;
   3436 	uint32_t	class;
   3437 	int		(*add)(sdp_session_t *sess, svc_info_t *si);
   3438 	unsigned char *uuid;
   3439 } service[] = {
   3440 	{ "DID",	PNP_INFO_SVCLASS_ID,		NULL,		},
   3441 
   3442 	{ "SP",		SERIAL_PORT_SVCLASS_ID,		add_sp		},
   3443 	{ "DUN",	DIALUP_NET_SVCLASS_ID,		add_dun		},
   3444 	{ "LAN",	LAN_ACCESS_SVCLASS_ID,		add_lan		},
   3445 	{ "FAX",	FAX_SVCLASS_ID,			add_fax		},
   3446 	{ "OPUSH",	OBEX_OBJPUSH_SVCLASS_ID,	add_opush	},
   3447 	{ "FTP",	OBEX_FILETRANS_SVCLASS_ID,	add_ftp		},
   3448 	{ "PRINT",	DIRECT_PRINTING_SVCLASS_ID,	add_directprint	},
   3449 
   3450 	{ "HS",		HEADSET_SVCLASS_ID,		add_headset	},
   3451 	{ "HSAG",	HEADSET_AGW_SVCLASS_ID,		add_headset_ag	},
   3452 	{ "HF",		HANDSFREE_SVCLASS_ID,		add_handsfree	},
   3453 	{ "HFAG",	HANDSFREE_AGW_SVCLASS_ID,	add_handsfree_ag},
   3454 	{ "SAP",	SAP_SVCLASS_ID,			add_simaccess	},
   3455 	{ "PBAP",	PBAP_SVCLASS_ID,		add_pbap,	},
   3456 
   3457 	{ "NAP",	NAP_SVCLASS_ID,			add_nap		},
   3458 	{ "GN",		GN_SVCLASS_ID,			add_gn		},
   3459 	{ "PANU",	PANU_SVCLASS_ID,		add_panu	},
   3460 
   3461 	{ "HCRP",	HCR_SVCLASS_ID,			NULL		},
   3462 	{ "HID",	HID_SVCLASS_ID,			NULL		},
   3463 	{ "KEYB",	HID_SVCLASS_ID,			add_hid_keyb	},
   3464 	{ "WIIMOTE",	HID_SVCLASS_ID,			add_hid_wiimote	},
   3465 	{ "CIP",	CIP_SVCLASS_ID,			add_cip		},
   3466 	{ "CTP",	CORDLESS_TELEPHONY_SVCLASS_ID,	add_ctp		},
   3467 
   3468 	{ "A2SRC",	AUDIO_SOURCE_SVCLASS_ID,	add_a2source	},
   3469 	{ "A2SNK",	AUDIO_SINK_SVCLASS_ID,		add_a2sink	},
   3470 	{ "AVRCT",	AV_REMOTE_SVCLASS_ID,		add_avrct	},
   3471 	{ "AVRTG",	AV_REMOTE_TARGET_SVCLASS_ID,	add_avrtg	},
   3472 
   3473 	{ "UDIUE",	UDI_MT_SVCLASS_ID,		add_udi_ue	},
   3474 	{ "UDITE",	UDI_TA_SVCLASS_ID,		add_udi_te	},
   3475 
   3476 	{ "SEMCHLA",	0x8e771301,			add_semchla	},
   3477 
   3478 	{ "SR1",	0,				add_sr1,	sr1_uuid	},
   3479 	{ "SYNCML",	0,				add_syncml,	syncmlc_uuid	},
   3480 	{ "SYNCMLSERV",	0,				NULL,		syncmls_uuid	},
   3481 	{ "ACTIVESYNC",	0,				add_activesync,	async_uuid	},
   3482 	{ "HOTSYNC",	0,				add_hotsync,	hotsync_uuid	},
   3483 	{ "PALMOS",	0,				add_palmos,	palmos_uuid	},
   3484 	{ "NOKID",	0,				add_nokiaid,	nokid_uuid	},
   3485 	{ "PCSUITE",	0,				add_pcsuite,	pcsuite_uuid	},
   3486 	{ "NFTP",	0,				NULL,		nftp_uuid	},
   3487 	{ "NSYNCML",	0,				NULL,		nsyncml_uuid	},
   3488 	{ "NGAGE",	0,				NULL,		ngage_uuid	},
   3489 	{ "APPLE",	0,				add_apple,	apple_uuid	},
   3490 
   3491 	{ "ISYNC",	APPLE_AGENT_SVCLASS_ID,		add_isync,	},
   3492 
   3493 	{ 0 }
   3494 };
   3495 
   3496 /* Add local service */
   3497 static int add_service(bdaddr_t *bdaddr, svc_info_t *si)
   3498 {
   3499 	sdp_session_t *sess;
   3500 	int i, ret = -1;
   3501 
   3502 	if (!si->name)
   3503 		return -1;
   3504 
   3505 	sess = sdp_connect(&interface, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
   3506 	if (!sess)
   3507 		return -1;
   3508 
   3509 	for (i = 0; service[i].name; i++)
   3510 		if (!strcasecmp(service[i].name, si->name)) {
   3511 			if (service[i].add)
   3512 				ret = service[i].add(sess, si);
   3513 			goto done;
   3514 		}
   3515 
   3516 	printf("Unknown service name: %s\n", si->name);
   3517 
   3518 done:
   3519 	free(si->name);
   3520 	sdp_close(sess);
   3521 
   3522 	return ret;
   3523 }
   3524 
   3525 static struct option add_options[] = {
   3526 	{ "help",	0, 0, 'h' },
   3527 	{ "handle",	1, 0, 'r' },
   3528 	{ "psm",	1, 0, 'p' },
   3529 	{ "channel",	1, 0, 'c' },
   3530 	{ "network",	1, 0, 'n' },
   3531 	{ 0, 0, 0, 0 }
   3532 };
   3533 
   3534 static const char *add_help =
   3535 	"Usage:\n"
   3536 	"\tadd [--handle=RECORD_HANDLE --channel=CHANNEL] service\n";
   3537 
   3538 static int cmd_add(int argc, char **argv)
   3539 {
   3540 	svc_info_t si;
   3541 	int opt;
   3542 
   3543 	memset(&si, 0, sizeof(si));
   3544 	si.handle = 0xffffffff;
   3545 
   3546 	for_each_opt(opt, add_options, 0) {
   3547 		switch (opt) {
   3548 		case 'r':
   3549 			if (strncasecmp(optarg, "0x", 2))
   3550 				si.handle = atoi(optarg);
   3551 			else
   3552 				si.handle = strtol(optarg + 2, NULL, 16);
   3553 			break;
   3554 		case 'p':
   3555 			if (strncasecmp(optarg, "0x", 2))
   3556 				si.psm = atoi(optarg);
   3557 			else
   3558 				si.psm = strtol(optarg + 2, NULL, 16);
   3559 			break;
   3560 		case 'c':
   3561 			if (strncasecmp(optarg, "0x", 2))
   3562 				si.channel = atoi(optarg);
   3563 			else
   3564 				si.channel = strtol(optarg + 2, NULL, 16);
   3565 			break;
   3566 		case 'n':
   3567 			if (strncasecmp(optarg, "0x", 2))
   3568 				si.network = atoi(optarg);
   3569 			else
   3570 				si.network = strtol(optarg + 2, NULL, 16);
   3571 			break;
   3572 		default:
   3573 			printf("%s", add_help);
   3574 			return -1;
   3575 		}
   3576 	}
   3577 
   3578 	argc -= optind;
   3579 	argv += optind;
   3580 
   3581 	if (argc < 1) {
   3582 		printf("%s", add_help);
   3583 		return -1;
   3584 	}
   3585 
   3586 	si.name = strdup(argv[0]);
   3587 
   3588 	return add_service(0, &si);
   3589 }
   3590 
   3591 /* Delete local service */
   3592 static int del_service(bdaddr_t *bdaddr, void *arg)
   3593 {
   3594 	uint32_t handle, range = 0x0000ffff;
   3595 	sdp_list_t *attr;
   3596 	sdp_session_t *sess;
   3597 	sdp_record_t *rec;
   3598 
   3599 	if (!arg) {
   3600 		printf("Record handle was not specified.\n");
   3601 		return -1;
   3602 	}
   3603 
   3604 	sess = sdp_connect(&interface, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
   3605 	if (!sess) {
   3606 		printf("No local SDP server!\n");
   3607 		return -1;
   3608 	}
   3609 
   3610 	handle = strtoul((char *)arg, 0, 16);
   3611 	attr = sdp_list_append(0, &range);
   3612 	rec = sdp_service_attr_req(sess, handle, SDP_ATTR_REQ_RANGE, attr);
   3613 	sdp_list_free(attr, 0);
   3614 
   3615 	if (!rec) {
   3616 		printf("Service Record not found.\n");
   3617 		sdp_close(sess);
   3618 		return -1;
   3619 	}
   3620 
   3621 	if (sdp_device_record_unregister(sess, &interface, rec)) {
   3622 		printf("Failed to unregister service record: %s\n", strerror(errno));
   3623 		sdp_close(sess);
   3624 		return -1;
   3625 	}
   3626 
   3627 	printf("Service Record deleted.\n");
   3628 	sdp_close(sess);
   3629 
   3630 	return 0;
   3631 }
   3632 
   3633 static struct option del_options[] = {
   3634 	{ "help",	0, 0, 'h' },
   3635 	{ 0, 0, 0, 0 }
   3636 };
   3637 
   3638 static const char *del_help =
   3639 	"Usage:\n"
   3640 	"\tdel record_handle\n";
   3641 
   3642 static int cmd_del(int argc, char **argv)
   3643 {
   3644 	int opt;
   3645 
   3646 	for_each_opt(opt, del_options, 0) {
   3647 		switch (opt) {
   3648 		default:
   3649 			printf("%s", del_help);
   3650 			return -1;
   3651 		}
   3652 	}
   3653 
   3654 	argc -= optind;
   3655 	argv += optind;
   3656 
   3657 	if (argc < 1) {
   3658 		printf("%s", del_help);
   3659 		return -1;
   3660 	}
   3661 
   3662 	return del_service(NULL, argv[0]);
   3663 }
   3664 
   3665 /*
   3666  * Perform an inquiry and search/browse all peer found.
   3667  */
   3668 static void inquiry(handler_t handler, void *arg)
   3669 {
   3670 	inquiry_info ii[20];
   3671 	uint8_t count = 0;
   3672 	int i;
   3673 
   3674 	printf("Inquiring ...\n");
   3675 	if (sdp_general_inquiry(ii, 20, 8, &count) < 0) {
   3676 		printf("Inquiry failed\n");
   3677 		return;
   3678 	}
   3679 
   3680 	for (i = 0; i < count; i++)
   3681 		handler(&ii[i].bdaddr, arg);
   3682 }
   3683 
   3684 static void doprintf(void *data, const char *str)
   3685 {
   3686 	printf("%s", str);
   3687 }
   3688 
   3689 /*
   3690  * Search for a specific SDP service
   3691  */
   3692 static int do_search(bdaddr_t *bdaddr, struct search_context *context)
   3693 {
   3694 	sdp_list_t *attrid, *search, *seq, *next;
   3695 	uint32_t range = 0x0000ffff;
   3696 	char str[20];
   3697 	sdp_session_t *sess;
   3698 
   3699 	if (!bdaddr) {
   3700 		inquiry(do_search, context);
   3701 		return 0;
   3702 	}
   3703 
   3704 	sess = sdp_connect(&interface, bdaddr, SDP_RETRY_IF_BUSY);
   3705 	ba2str(bdaddr, str);
   3706 	if (!sess) {
   3707 		printf("Failed to connect to SDP server on %s: %s\n", str, strerror(errno));
   3708 		return -1;
   3709 	}
   3710 
   3711 	if (context->view != RAW_VIEW) {
   3712 		if (context->svc)
   3713 			printf("Searching for %s on %s ...\n", context->svc, str);
   3714 		else
   3715 			printf("Browsing %s ...\n", str);
   3716 	}
   3717 
   3718 	attrid = sdp_list_append(0, &range);
   3719 	search = sdp_list_append(0, &context->group);
   3720 	if (sdp_service_search_attr_req(sess, search, SDP_ATTR_REQ_RANGE, attrid, &seq)) {
   3721 		printf("Service Search failed: %s\n", strerror(errno));
   3722 		sdp_close(sess);
   3723 		return -1;
   3724 	}
   3725 	sdp_list_free(attrid, 0);
   3726 	sdp_list_free(search, 0);
   3727 
   3728 	for (; seq; seq = next) {
   3729 		sdp_record_t *rec = (sdp_record_t *) seq->data;
   3730 		struct search_context sub_context;
   3731 
   3732 		switch (context->view) {
   3733 		case DEFAULT_VIEW:
   3734 			/* Display user friendly form */
   3735 			print_service_attr(rec);
   3736 			printf("\n");
   3737 			break;
   3738 		case TREE_VIEW:
   3739 			/* Display full tree */
   3740 			print_tree_attr(rec);
   3741 			printf("\n");
   3742 			break;
   3743 		case XML_VIEW:
   3744 			/* Display raw XML tree */
   3745 			convert_sdp_record_to_xml(rec, 0, doprintf);
   3746 			break;
   3747 		default:
   3748 			/* Display raw tree */
   3749 			print_raw_attr(rec);
   3750 			break;
   3751 		}
   3752 
   3753 		if (sdp_get_group_id(rec, &sub_context.group) != -1) {
   3754 			/* Set the subcontext for browsing the sub tree */
   3755 			memcpy(&sub_context, context, sizeof(struct search_context));
   3756 			/* Browse the next level down if not done */
   3757 			if (sub_context.group.value.uuid16 != context->group.value.uuid16)
   3758 				do_search(bdaddr, &sub_context);
   3759 		}
   3760 		next = seq->next;
   3761 		free(seq);
   3762 		sdp_record_free(rec);
   3763 	}
   3764 
   3765 	sdp_close(sess);
   3766 	return 0;
   3767 }
   3768 
   3769 static struct option browse_options[] = {
   3770 	{ "help",	0, 0, 'h' },
   3771 	{ "tree",	0, 0, 't' },
   3772 	{ "raw",	0, 0, 'r' },
   3773 	{ "xml",	0, 0, 'x' },
   3774 	{ "uuid",	1, 0, 'u' },
   3775 	{ "l2cap",	0, 0, 'l' },
   3776 	{ 0, 0, 0, 0 }
   3777 };
   3778 
   3779 static const char *browse_help =
   3780 	"Usage:\n"
   3781 	"\tbrowse [--tree] [--raw] [--xml] [--uuid uuid] [--l2cap] [bdaddr]\n";
   3782 
   3783 /*
   3784  * Browse the full SDP database (i.e. list all services starting from the
   3785  * root/top-level).
   3786  */
   3787 static int cmd_browse(int argc, char **argv)
   3788 {
   3789 	struct search_context context;
   3790 	int opt, num;
   3791 
   3792 	/* Initialise context */
   3793 	memset(&context, '\0', sizeof(struct search_context));
   3794 	/* We want to browse the top-level/root */
   3795 	sdp_uuid16_create(&context.group, PUBLIC_BROWSE_GROUP);
   3796 
   3797 	for_each_opt(opt, browse_options, 0) {
   3798 		switch (opt) {
   3799 		case 't':
   3800 			context.view = TREE_VIEW;
   3801 			break;
   3802 		case 'r':
   3803 			context.view = RAW_VIEW;
   3804 			break;
   3805 		case 'x':
   3806 			context.view = XML_VIEW;
   3807 			break;
   3808 		case 'u':
   3809 			if (sscanf(optarg, "%i", &num) != 1 || num < 0 || num > 0xffff) {
   3810 				printf("Invalid uuid %s\n", optarg);
   3811 				return -1;
   3812 			}
   3813 			sdp_uuid16_create(&context.group, num);
   3814 			break;
   3815 		case 'l':
   3816 			sdp_uuid16_create(&context.group, L2CAP_UUID);
   3817 			break;
   3818 		default:
   3819 			printf("%s", browse_help);
   3820 			return -1;
   3821 		}
   3822 	}
   3823 
   3824 	argc -= optind;
   3825 	argv += optind;
   3826 
   3827 	if (argc >= 1) {
   3828 		bdaddr_t bdaddr;
   3829 		estr2ba(argv[0], &bdaddr);
   3830 		return do_search(&bdaddr, &context);
   3831 	}
   3832 
   3833 	return do_search(NULL, &context);
   3834 }
   3835 
   3836 static struct option search_options[] = {
   3837 	{ "help",	0, 0, 'h' },
   3838 	{ "bdaddr",	1, 0, 'b' },
   3839 	{ "tree",	0, 0, 't' },
   3840 	{ "raw",	0, 0, 'r' },
   3841 	{ "xml",	0, 0, 'x' },
   3842 	{ 0, 0, 0, 0}
   3843 };
   3844 
   3845 static const char *search_help =
   3846 	"Usage:\n"
   3847 	"\tsearch [--bdaddr bdaddr] [--tree] [--raw] [--xml] SERVICE\n"
   3848 	"SERVICE is a name (string) or UUID (0x1002)\n";
   3849 
   3850 /*
   3851  * Search for a specific SDP service
   3852  *
   3853  * Note : we should support multiple services on the command line :
   3854  *          sdptool search 0x0100 0x000f 0x1002
   3855  * (this would search a service supporting both L2CAP and BNEP directly in
   3856  * the top level browse group)
   3857  */
   3858 static int cmd_search(int argc, char **argv)
   3859 {
   3860 	struct search_context context;
   3861 	unsigned char *uuid = NULL;
   3862 	uint32_t class = 0;
   3863 	bdaddr_t bdaddr;
   3864 	int has_addr = 0;
   3865 	int i;
   3866 	int opt;
   3867 
   3868 	/* Initialise context */
   3869 	memset(&context, '\0', sizeof(struct search_context));
   3870 
   3871 	for_each_opt(opt, search_options, 0) {
   3872 		switch (opt) {
   3873 		case 'b':
   3874 			estr2ba(optarg, &bdaddr);
   3875 			has_addr = 1;
   3876 			break;
   3877 		case 't':
   3878 			context.view = TREE_VIEW;
   3879 			break;
   3880 		case 'r':
   3881 			context.view = RAW_VIEW;
   3882 			break;
   3883 		case 'x':
   3884 			context.view = XML_VIEW;
   3885 			break;
   3886 		default:
   3887 			printf("%s", search_help);
   3888 			return -1;
   3889 		}
   3890 	}
   3891 
   3892 	argc -= optind;
   3893 	argv += optind;
   3894 
   3895 	if (argc < 1) {
   3896 		printf("%s", search_help);
   3897 		return -1;
   3898 	}
   3899 
   3900 	/* Note : we need to find a way to support search combining
   3901 	 * multiple services */
   3902 	context.svc = strdup(argv[0]);
   3903 	if (!strncasecmp(context.svc, "0x", 2)) {
   3904 		int num;
   3905 		/* This is a UUID16, just convert to int */
   3906 		sscanf(context.svc + 2, "%X", &num);
   3907 		class = num;
   3908 		printf("Class 0x%X\n", class);
   3909 	} else {
   3910 		/* Convert class name to an UUID */
   3911 
   3912 		for (i = 0; service[i].name; i++)
   3913 			if (strcasecmp(context.svc, service[i].name) == 0) {
   3914 				class = service[i].class;
   3915 				uuid = service[i].uuid;
   3916 				break;
   3917 			}
   3918 		if (!class && !uuid) {
   3919 			printf("Unknown service %s\n", context.svc);
   3920 			return -1;
   3921 		}
   3922 	}
   3923 
   3924 	if (class) {
   3925 		if (class & 0xffff0000)
   3926 			sdp_uuid32_create(&context.group, class);
   3927 		else {
   3928 			uint16_t class16 = class & 0xffff;
   3929 			sdp_uuid16_create(&context.group, class16);
   3930 		}
   3931 	} else
   3932 		sdp_uuid128_create(&context.group, uuid);
   3933 
   3934 	if (has_addr)
   3935 		return do_search(&bdaddr, &context);
   3936 
   3937 	return do_search(NULL, &context);
   3938 }
   3939 
   3940 /*
   3941  * Show how to get a specific SDP record by its handle.
   3942  * Not really useful to the user, just show how it can be done...
   3943  */
   3944 static int get_service(bdaddr_t *bdaddr, struct search_context *context, int quite)
   3945 {
   3946 	sdp_list_t *attrid;
   3947 	uint32_t range = 0x0000ffff;
   3948 	sdp_record_t *rec;
   3949 	sdp_session_t *session = sdp_connect(&interface, bdaddr, SDP_RETRY_IF_BUSY);
   3950 
   3951 	if (!session) {
   3952 		char str[20];
   3953 		ba2str(bdaddr, str);
   3954 		printf("Failed to connect to SDP server on %s: %s\n", str, strerror(errno));
   3955 		return -1;
   3956 	}
   3957 
   3958 	attrid = sdp_list_append(0, &range);
   3959 	rec = sdp_service_attr_req(session, context->handle, SDP_ATTR_REQ_RANGE, attrid);
   3960 	sdp_list_free(attrid, 0);
   3961 	sdp_close(session);
   3962 
   3963 	if (!rec) {
   3964 		if (!quite) {
   3965 			printf("Service get request failed.\n");
   3966 			return -1;
   3967 		} else
   3968 			return 0;
   3969 	}
   3970 
   3971 	switch (context->view) {
   3972 	case DEFAULT_VIEW:
   3973 		/* Display user friendly form */
   3974 		print_service_attr(rec);
   3975 		printf("\n");
   3976 		break;
   3977 	case TREE_VIEW:
   3978 		/* Display full tree */
   3979 		print_tree_attr(rec);
   3980 		printf("\n");
   3981 		break;
   3982 	case XML_VIEW:
   3983 		/* Display raw XML tree */
   3984 		convert_sdp_record_to_xml(rec, 0, doprintf);
   3985 		break;
   3986 	default:
   3987 		/* Display raw tree */
   3988 		print_raw_attr(rec);
   3989 		break;
   3990 	}
   3991 
   3992 	sdp_record_free(rec);
   3993 	return 0;
   3994 }
   3995 
   3996 static struct option records_options[] = {
   3997 	{ "help",	0, 0, 'h' },
   3998 	{ "tree",	0, 0, 't' },
   3999 	{ "raw",	0, 0, 'r' },
   4000 	{ "xml",	0, 0, 'x' },
   4001 	{ 0, 0, 0, 0 }
   4002 };
   4003 
   4004 static const char *records_help =
   4005 	"Usage:\n"
   4006 	"\trecords [--tree] [--raw] [--xml] bdaddr\n";
   4007 
   4008 /*
   4009  * Request possible SDP service records
   4010  */
   4011 static int cmd_records(int argc, char **argv)
   4012 {
   4013 	struct search_context context;
   4014 	uint32_t base[] = { 0x10000, 0x10300, 0x10500,
   4015 				0x1002e, 0x110b, 0x90000, 0x2008000,
   4016 					0x4000000, 0x100000, 0x1000000,
   4017 						0x4f491100, 0x4f491200 };
   4018 	bdaddr_t bdaddr;
   4019 	unsigned int i, n, num = 32;
   4020 	int opt, err = 0;
   4021 
   4022 	/* Initialise context */
   4023 	memset(&context, '\0', sizeof(struct search_context));
   4024 
   4025 	for_each_opt(opt, records_options, 0) {
   4026 		switch (opt) {
   4027 		case 't':
   4028 			context.view = TREE_VIEW;
   4029 			break;
   4030 		case 'r':
   4031 			context.view = RAW_VIEW;
   4032 			break;
   4033 		case 'x':
   4034 			context.view = XML_VIEW;
   4035 			break;
   4036 		default:
   4037 			printf("%s", records_help);
   4038 			return -1;
   4039 		}
   4040 	}
   4041 
   4042 	argc -= optind;
   4043 	argv += optind;
   4044 
   4045 	if (argc < 1) {
   4046 		printf("%s", records_help);
   4047 		return -1;
   4048 	}
   4049 
   4050 	/* Convert command line parameters */
   4051 	estr2ba(argv[0], &bdaddr);
   4052 
   4053 	for (i = 0; i < sizeof(base) / sizeof(uint32_t); i++)
   4054 		for (n = 0; n < num; n++) {
   4055 			context.handle = base[i] + n;
   4056 			err = get_service(&bdaddr, &context, 1);
   4057 			if (err < 0)
   4058 				goto done;
   4059 		}
   4060 
   4061 done:
   4062 	return 0;
   4063 }
   4064 
   4065 static struct option get_options[] = {
   4066 	{ "help",	0, 0, 'h' },
   4067 	{ "bdaddr",	1, 0, 'b' },
   4068 	{ "tree",	0, 0, 't' },
   4069 	{ "raw",	0, 0, 'r' },
   4070 	{ "xml",	0, 0, 'x' },
   4071 	{ 0, 0, 0, 0 }
   4072 };
   4073 
   4074 static const char *get_help =
   4075 	"Usage:\n"
   4076 	"\tget [--tree] [--raw] [--xml] [--bdaddr bdaddr] record_handle\n";
   4077 
   4078 /*
   4079  * Get a specific SDP record on the local SDP server
   4080  */
   4081 static int cmd_get(int argc, char **argv)
   4082 {
   4083 	struct search_context context;
   4084 	bdaddr_t bdaddr;
   4085 	int has_addr = 0;
   4086 	int opt;
   4087 
   4088 	/* Initialise context */
   4089 	memset(&context, '\0', sizeof(struct search_context));
   4090 
   4091 	for_each_opt(opt, get_options, 0) {
   4092 		switch (opt) {
   4093 		case 'b':
   4094 			estr2ba(optarg, &bdaddr);
   4095 			has_addr = 1;
   4096 			break;
   4097 		case 't':
   4098 			context.view = TREE_VIEW;
   4099 			break;
   4100 		case 'r':
   4101 			context.view = RAW_VIEW;
   4102 			break;
   4103 		case 'x':
   4104 			context.view = XML_VIEW;
   4105 			break;
   4106 		default:
   4107 			printf("%s", get_help);
   4108 			return -1;
   4109 		}
   4110 	}
   4111 
   4112 	argc -= optind;
   4113 	argv += optind;
   4114 
   4115 	if (argc < 1) {
   4116 		printf("%s", get_help);
   4117 		return -1;
   4118 	}
   4119 
   4120 	/* Convert command line parameters */
   4121 	context.handle = strtoul(argv[0], 0, 16);
   4122 
   4123 	return get_service(has_addr ? &bdaddr : BDADDR_LOCAL, &context, 0);
   4124 }
   4125 
   4126 static struct {
   4127 	char *cmd;
   4128 	int (*func)(int argc, char **argv);
   4129 	char *doc;
   4130 } command[] = {
   4131 	{ "search",  cmd_search,      "Search for a service"          },
   4132 	{ "browse",  cmd_browse,      "Browse all available services" },
   4133 	{ "records", cmd_records,     "Request all records"           },
   4134 	{ "add",     cmd_add,         "Add local service"             },
   4135 	{ "del",     cmd_del,         "Delete local service"          },
   4136 	{ "get",     cmd_get,         "Get local service"             },
   4137 	{ "setattr", cmd_setattr,     "Set/Add attribute to a SDP record"          },
   4138 	{ "setseq",  cmd_setseq,      "Set/Add attribute sequence to a SDP record" },
   4139 	{ 0, 0, 0 }
   4140 };
   4141 
   4142 static void usage(void)
   4143 {
   4144 	int i, pos = 0;
   4145 
   4146 	printf("sdptool - SDP tool v%s\n", VERSION);
   4147 	printf("Usage:\n"
   4148 		"\tsdptool [options] <command> [command parameters]\n");
   4149 	printf("Options:\n"
   4150 		"\t-h\t\tDisplay help\n"
   4151 		"\t-i\t\tSpecify source interface\n");
   4152 
   4153 	printf("Commands:\n");
   4154 	for (i = 0; command[i].cmd; i++)
   4155 		printf("\t%-4s\t\t%s\n", command[i].cmd, command[i].doc);
   4156 
   4157 	printf("\nServices:\n\t");
   4158 	for (i = 0; service[i].name; i++) {
   4159 		printf("%s ", service[i].name);
   4160 		pos += strlen(service[i].name) + 1;
   4161 		if (pos > 60) {
   4162 			printf("\n\t");
   4163 			pos = 0;
   4164 		}
   4165 	}
   4166 	printf("\n");
   4167 }
   4168 
   4169 static struct option main_options[] = {
   4170 	{ "help",	0, 0, 'h' },
   4171 	{ "device",	1, 0, 'i' },
   4172 	{ 0, 0, 0, 0 }
   4173 };
   4174 
   4175 int main(int argc, char *argv[])
   4176 {
   4177 	int i, opt;
   4178 
   4179 	bacpy(&interface, BDADDR_ANY);
   4180 
   4181 	while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) {
   4182 		switch(opt) {
   4183 		case 'i':
   4184 			if (!strncmp(optarg, "hci", 3))
   4185 				hci_devba(atoi(optarg + 3), &interface);
   4186 			else
   4187 				str2ba(optarg, &interface);
   4188 			break;
   4189 
   4190 		case 'h':
   4191 			usage();
   4192 			exit(0);
   4193 
   4194 		default:
   4195 			exit(1);
   4196 		}
   4197 	}
   4198 
   4199 	argc -= optind;
   4200 	argv += optind;
   4201 	optind = 0;
   4202 
   4203 	if (argc < 1) {
   4204 		usage();
   4205 		exit(1);
   4206 	}
   4207 
   4208 	for (i = 0; command[i].cmd; i++)
   4209 		if (strncmp(command[i].cmd, argv[0], 4) == 0)
   4210 			return command[i].func(argc, argv);
   4211 
   4212 	return 1;
   4213 }
   4214