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