1 /* $NetBSD: sdp_compat.c,v 1.2 2009/05/14 19:12:45 plunky Exp $ */ 2 3 /*- 4 * Copyright (c) 2006 Itronix Inc. 5 * All rights reserved. 6 * 7 * Written by Iain Hibbert for Itronix Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. The name of Itronix Inc. may not be used to endorse 18 * or promote products derived from this software without specific 19 * prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY 25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 28 * ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 /*- 34 * Copyright (c) 2001-2003 Maksim Yevmenkin <m_evmenkin@yahoo.com> 35 * All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 46 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 49 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 56 * SUCH DAMAGE. 57 */ 58 59 /* 60 * This file provides compatibility with the original library API, 61 * use -DSDP_COMPAT to access it. 62 * 63 * These functions are deprecated and will be removed eventually. 64 * 65 * sdp_open(laddr, raddr) 66 * sdp_open_local(control) 67 * sdp_close(session) 68 * sdp_error(session) 69 * sdp_search(session, plen, protos, alen, attrs, vlen, values) 70 * sdp_register_service(session, uuid, bdaddr, data, datalen, handle) 71 * sdp_change_service(session, handle, data, datalen) 72 * sdp_unregister_service(session, handle) 73 * sdp_attr2desc(attribute) 74 * sdp_uuid2desc(uuid16) 75 * sdp_print(level, start, end) 76 */ 77 #define SDP_COMPAT 78 79 #include <sys/cdefs.h> 80 __RCSID("$NetBSD: sdp_compat.c,v 1.2 2009/05/14 19:12:45 plunky Exp $"); 81 82 #include <errno.h> 83 #include <sdp.h> 84 #include <stdlib.h> 85 #include <string.h> 86 #include <unistd.h> 87 88 #include "sdp-int.h" 89 90 struct sdp_compat { 91 sdp_session_t ss; 92 int error; 93 uint8_t buf[256]; 94 }; 95 96 void * 97 sdp_open(bdaddr_t const *l, bdaddr_t const *r) 98 { 99 struct sdp_compat *sc; 100 101 sc = malloc(sizeof(struct sdp_compat)); 102 if (sc == NULL) 103 return NULL; 104 105 if (l == NULL || r == NULL) { 106 sc->error = EINVAL; 107 return sc; 108 } 109 110 sc->ss = _sdp_open(l, r); 111 if (sc->ss == NULL) { 112 sc->error = errno; 113 return sc; 114 } 115 116 sc->error = 0; 117 return sc; 118 } 119 120 void * 121 sdp_open_local(char const *control) 122 { 123 struct sdp_compat *sc; 124 125 sc = malloc(sizeof(struct sdp_compat)); 126 if (sc == NULL) 127 return NULL; 128 129 sc->ss = _sdp_open_local(control); 130 if (sc->ss == NULL) { 131 sc->error = errno; 132 return sc; 133 } 134 135 sc->error = 0; 136 return sc; 137 } 138 139 int32_t 140 sdp_close(void *xss) 141 { 142 struct sdp_compat *sc = xss; 143 144 if (sc == NULL) 145 return 0; 146 147 if (sc->ss != NULL) 148 _sdp_close(sc->ss); 149 150 free(sc); 151 152 return 0; 153 } 154 155 int32_t 156 sdp_error(void *xss) 157 { 158 struct sdp_compat *sc = xss; 159 160 if (sc == NULL) 161 return EINVAL; 162 163 return sc->error; 164 } 165 166 int32_t 167 sdp_search(void *xss, uint32_t plen, uint16_t const *pp, uint32_t alen, 168 uint32_t const *ap, uint32_t vlen, sdp_attr_t *vp) 169 { 170 struct sdp_compat *sc = xss; 171 sdp_data_t seq, ssp, ail, rsp, value; 172 uint16_t attr; 173 size_t i; 174 bool rv; 175 176 if (sc == NULL) 177 return -1; 178 179 if (plen == 0 || pp == NULL || alen == 0 || ap == NULL) { 180 sc->error = EINVAL; 181 return -1; 182 } 183 184 /* 185 * encode ServiceSearchPattern 186 */ 187 ssp.next = sc->buf; 188 ssp.end = sc->buf + sizeof(sc->buf); 189 for (i = 0; i < plen; i++) 190 sdp_put_uuid16(&ssp, pp[i]); 191 192 ssp.end = ssp.next; 193 ssp.next = sc->buf; 194 195 /* 196 * encode AttributeIDList 197 */ 198 ail.next = ssp.end; 199 ail.end = sc->buf + sizeof(sc->buf); 200 for (i = 0; i < alen; i++) 201 sdp_put_uint32(&ail, ap[i]); 202 203 ail.end = ail.next; 204 ail.next = ssp.end; 205 206 /* 207 * perform ServiceSearchAttribute transaction 208 */ 209 rv = sdp_service_search_attribute(sc->ss, &ssp, &ail, &rsp); 210 if (rv == false) { 211 sc->error = errno; 212 return -1; 213 } 214 215 if (vp == NULL) 216 return 0; 217 218 /* 219 * The response buffer is a list of data element sequences, 220 * each containing a list of attribute/value pairs. We want to 221 * parse those to the attribute array that the user passed in. 222 */ 223 while (vlen > 0 && sdp_get_seq(&rsp, &seq)) { 224 while (vlen > 0 && sdp_get_attr(&seq, &attr, &value)) { 225 vp->attr = attr; 226 if (vp->value != NULL) { 227 if (value.end - value.next > (ssize_t)vp->vlen) { 228 vp->flags = SDP_ATTR_TRUNCATED; 229 } else { 230 vp->flags = SDP_ATTR_OK; 231 vp->vlen = value.end - value.next; 232 } 233 memcpy(vp->value, value.next, vp->vlen); 234 } else { 235 vp->flags = SDP_ATTR_INVALID; 236 } 237 238 vp++; 239 vlen--; 240 } 241 } 242 243 while (vlen-- > 0) 244 vp++->flags = SDP_ATTR_INVALID; 245 246 return 0; 247 } 248 249 int32_t 250 sdp_register_service(void *xss, uint16_t uuid, bdaddr_t *bdaddr, 251 uint8_t *data, uint32_t datalen, uint32_t *handle) 252 { 253 struct sdp_compat *sc = xss; 254 struct iovec req[4]; 255 ssize_t len; 256 257 if (sc == NULL) 258 return -1; 259 260 if (bdaddr == NULL || data == NULL || datalen == 0) { 261 sc->error = EINVAL; 262 return -1; 263 } 264 265 uuid = htobe16(uuid); 266 req[1].iov_base = &uuid; 267 req[1].iov_len = sizeof(uint16_t); 268 269 req[2].iov_base = bdaddr; 270 req[2].iov_len = sizeof(bdaddr_t); 271 272 req[3].iov_base = data; 273 req[3].iov_len = datalen; 274 275 if (!_sdp_send_pdu(sc->ss, SDP_PDU_SERVICE_REGISTER_REQUEST, 276 req, __arraycount(req))) { 277 sc->error = errno; 278 return -1; 279 } 280 281 len = _sdp_recv_pdu(sc->ss, SDP_PDU_ERROR_RESPONSE); 282 if (len == -1) { 283 sc->error = errno; 284 return -1; 285 } 286 287 if (len != sizeof(uint16_t) + sizeof(uint32_t) 288 || be16dec(sc->ss->ibuf) != 0) { 289 sc->error = EIO; 290 return -1; 291 } 292 293 if (handle != NULL) 294 *handle = be32dec(sc->ss->ibuf + sizeof(uint16_t)); 295 296 return 0; 297 } 298 299 int32_t 300 sdp_change_service(void *xss, uint32_t handle, 301 uint8_t *data, uint32_t datalen) 302 { 303 struct sdp_compat *sc = xss; 304 struct iovec req[3]; 305 ssize_t len; 306 307 if (data == NULL || datalen == 0) { 308 sc->error = EINVAL; 309 return -1; 310 } 311 312 handle = htobe32(handle); 313 req[1].iov_base = &handle; 314 req[1].iov_len = sizeof(uint32_t); 315 316 req[2].iov_base = data; 317 req[2].iov_len = datalen; 318 319 if (!_sdp_send_pdu(sc->ss, SDP_PDU_SERVICE_CHANGE_REQUEST, 320 req, __arraycount(req))) { 321 sc->error = errno; 322 return -1; 323 } 324 325 len = _sdp_recv_pdu(sc->ss, SDP_PDU_ERROR_RESPONSE); 326 if (len == -1) { 327 sc->error = errno; 328 return -1; 329 } 330 331 if (len != sizeof(uint16_t) 332 || be16dec(sc->ss->ibuf) != 0) { 333 sc->error = EIO; 334 return -1; 335 } 336 337 return 0; 338 } 339 340 int32_t 341 sdp_unregister_service(void *xss, uint32_t handle) 342 { 343 struct sdp_compat *sc = xss; 344 struct iovec req[2]; 345 ssize_t len; 346 347 handle = htobe32(handle); 348 req[1].iov_base = &handle; 349 req[1].iov_len = sizeof(uint32_t); 350 351 if (!_sdp_send_pdu(sc->ss, SDP_PDU_SERVICE_UNREGISTER_REQUEST, 352 req, __arraycount(req))) { 353 sc->error = errno; 354 return -1; 355 } 356 357 len = _sdp_recv_pdu(sc->ss, SDP_PDU_ERROR_RESPONSE); 358 if (len == -1) { 359 sc->error = errno; 360 return -1; 361 } 362 363 if (len != sizeof(uint16_t) 364 || be16dec(sc->ss->ibuf) != 0) { 365 sc->error = EIO; 366 return -1; 367 } 368 369 return 0; 370 } 371 372 /* 373 * SDP attribute description 374 */ 375 376 struct sdp_attr_desc { 377 uint32_t attr; 378 char const *desc; 379 }; 380 typedef struct sdp_attr_desc sdp_attr_desc_t; 381 typedef struct sdp_attr_desc * sdp_attr_desc_p; 382 383 static sdp_attr_desc_t sdp_uuids_desc[] = { 384 { SDP_UUID_PROTOCOL_SDP, "SDP", }, 385 { SDP_UUID_PROTOCOL_UDP, "UDP", }, 386 { SDP_UUID_PROTOCOL_RFCOMM, "RFCOMM", }, 387 { SDP_UUID_PROTOCOL_TCP, "TCP", }, 388 { SDP_UUID_PROTOCOL_TCS_BIN, "TCS BIN", }, 389 { SDP_UUID_PROTOCOL_TCS_AT, "TCS AT", }, 390 { SDP_UUID_PROTOCOL_OBEX, "OBEX", }, 391 { SDP_UUID_PROTOCOL_IP, "IP", }, 392 { SDP_UUID_PROTOCOL_FTP, "FTP", }, 393 { SDP_UUID_PROTOCOL_HTTP, "HTTP", }, 394 { SDP_UUID_PROTOCOL_WSP, "WSP", }, 395 { SDP_UUID_PROTOCOL_BNEP, "BNEP", }, 396 { SDP_UUID_PROTOCOL_UPNP, "UPNP", }, 397 { SDP_UUID_PROTOCOL_HIDP, "HIDP", }, 398 { SDP_UUID_PROTOCOL_HARDCOPY_CONTROL_CHANNEL, "Hardcopy Control Channel", }, 399 { SDP_UUID_PROTOCOL_HARDCOPY_DATA_CHANNEL, "Hardcopy Data Channel", }, 400 { SDP_UUID_PROTOCOL_HARDCOPY_NOTIFICATION, "Hardcopy Notification", }, 401 { SDP_UUID_PROTOCOL_AVCTP, "AVCTP", }, 402 { SDP_UUID_PROTOCOL_AVDTP, "AVDTP", }, 403 { SDP_UUID_PROTOCOL_CMPT, "CMPT", }, 404 { SDP_UUID_PROTOCOL_UDI_C_PLANE, "UDI C-Plane", }, 405 { SDP_UUID_PROTOCOL_L2CAP, "L2CAP", }, 406 /* Service Class IDs/Bluetooth Profile IDs */ 407 { SDP_SERVICE_CLASS_SERVICE_DISCOVERY_SERVER, "Service Discovery Server", }, 408 { SDP_SERVICE_CLASS_BROWSE_GROUP_DESCRIPTOR, "Browse Group Descriptor", }, 409 { SDP_SERVICE_CLASS_PUBLIC_BROWSE_GROUP, "Public Browse Group", }, 410 { SDP_SERVICE_CLASS_SERIAL_PORT, "Serial Port", }, 411 { SDP_SERVICE_CLASS_LAN_ACCESS_USING_PPP, "LAN Access Using PPP", }, 412 { SDP_SERVICE_CLASS_DIALUP_NETWORKING, "Dial-Up Networking", }, 413 { SDP_SERVICE_CLASS_IR_MC_SYNC, "IrMC Sync", }, 414 { SDP_SERVICE_CLASS_OBEX_OBJECT_PUSH, "OBEX Object Push", }, 415 { SDP_SERVICE_CLASS_OBEX_FILE_TRANSFER, "OBEX File Transfer", }, 416 { SDP_SERVICE_CLASS_IR_MC_SYNC_COMMAND, "IrMC Sync Command", }, 417 { SDP_SERVICE_CLASS_HEADSET, "Headset", }, 418 { SDP_SERVICE_CLASS_CORDLESS_TELEPHONY, "Cordless Telephony", }, 419 { SDP_SERVICE_CLASS_AUDIO_SOURCE, "Audio Source", }, 420 { SDP_SERVICE_CLASS_AUDIO_SINK, "Audio Sink", }, 421 { SDP_SERVICE_CLASS_AV_REMOTE_CONTROL_TARGET, "A/V Remote Control Target", }, 422 { SDP_SERVICE_CLASS_ADVANCED_AUDIO_DISTRIBUTION, "Advanced Audio Distribution", }, 423 { SDP_SERVICE_CLASS_AV_REMOTE_CONTROL, "A/V Remote Control", }, 424 { SDP_SERVICE_CLASS_VIDEO_CONFERENCING, "Video Conferencing", }, 425 { SDP_SERVICE_CLASS_INTERCOM, "Intercom", }, 426 { SDP_SERVICE_CLASS_FAX, "Fax", }, 427 { SDP_SERVICE_CLASS_HEADSET_AUDIO_GATEWAY, "Headset Audio Gateway", }, 428 { SDP_SERVICE_CLASS_WAP, "WAP", }, 429 { SDP_SERVICE_CLASS_WAP_CLIENT, "WAP Client", }, 430 { SDP_SERVICE_CLASS_PANU, "PANU", }, 431 { SDP_SERVICE_CLASS_NAP, "Network Access Point", }, 432 { SDP_SERVICE_CLASS_GN, "GN", }, 433 { SDP_SERVICE_CLASS_DIRECT_PRINTING, "Direct Printing", }, 434 { SDP_SERVICE_CLASS_REFERENCE_PRINTING, "Reference Printing", }, 435 { SDP_SERVICE_CLASS_IMAGING, "Imaging", }, 436 { SDP_SERVICE_CLASS_IMAGING_RESPONDER, "Imaging Responder", }, 437 { SDP_SERVICE_CLASS_IMAGING_AUTOMATIC_ARCHIVE, "Imaging Automatic Archive", }, 438 { SDP_SERVICE_CLASS_IMAGING_REFERENCED_OBJECTS, "Imaging Referenced Objects", }, 439 { SDP_SERVICE_CLASS_HANDSFREE, "Handsfree", }, 440 { SDP_SERVICE_CLASS_HANDSFREE_AUDIO_GATEWAY, "Handsfree Audio Gateway", }, 441 { SDP_SERVICE_CLASS_DIRECT_PRINTING_REFERENCE_OBJECTS, "Direct Printing Reference Objects", }, 442 { SDP_SERVICE_CLASS_REFLECTED_UI, "Reflected UI", }, 443 { SDP_SERVICE_CLASS_BASIC_PRINTING, "Basic Printing", }, 444 { SDP_SERVICE_CLASS_PRINTING_STATUS, "Printing Status", }, 445 { SDP_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE, "Human Interface Device", }, 446 { SDP_SERVICE_CLASS_HARDCOPY_CABLE_REPLACEMENT, "Hardcopy Cable Replacement", }, 447 { SDP_SERVICE_CLASS_HCR_PRINT, "HCR Print", }, 448 { SDP_SERVICE_CLASS_HCR_SCAN, "HCR Scan", }, 449 { SDP_SERVICE_CLASS_COMMON_ISDN_ACCESS, "Common ISDN Access", }, 450 { SDP_SERVICE_CLASS_VIDEO_CONFERENCING_GW, "Video Conferencing Gateway", }, 451 { SDP_SERVICE_CLASS_UDI_MT, "UDI MT", }, 452 { SDP_SERVICE_CLASS_UDI_TA, "UDI TA", }, 453 { SDP_SERVICE_CLASS_AUDIO_VIDEO, "Audio/Video", }, 454 { SDP_SERVICE_CLASS_SIM_ACCESS, "SIM Access", }, 455 { SDP_SERVICE_CLASS_PNP_INFORMATION, "PNP Information", }, 456 { SDP_SERVICE_CLASS_GENERIC_NETWORKING, "Generic Networking", }, 457 { SDP_SERVICE_CLASS_GENERIC_FILE_TRANSFER, "Generic File Transfer", }, 458 { SDP_SERVICE_CLASS_GENERIC_AUDIO, "Generic Audio", }, 459 { SDP_SERVICE_CLASS_GENERIC_TELEPHONY, "Generic Telephony", }, 460 { SDP_SERVICE_CLASS_UPNP, "UPNP", }, 461 { SDP_SERVICE_CLASS_UPNP_IP, "UPNP IP", }, 462 { SDP_SERVICE_CLASS_ESDP_UPNP_IP_PAN, "ESDP UPNP IP PAN", }, 463 { SDP_SERVICE_CLASS_ESDP_UPNP_IP_LAP, "ESDP UPNP IP LAP", }, 464 { SDP_SERVICE_CLASS_ESDP_UPNP_L2CAP, "ESDP UPNP L2CAP", }, 465 { 0xffff, NULL, } 466 }; 467 468 static sdp_attr_desc_t sdp_attrs_desc[] = { 469 { SDP_ATTR_SERVICE_RECORD_HANDLE, 470 "Record handle", 471 }, 472 { SDP_ATTR_SERVICE_CLASS_ID_LIST, 473 "Service Class ID list", 474 }, 475 { SDP_ATTR_SERVICE_RECORD_STATE, 476 "Service Record State", 477 }, 478 { SDP_ATTR_SERVICE_ID, 479 "Service ID", 480 }, 481 { SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST, 482 "Protocol Descriptor List", 483 }, 484 { SDP_ATTR_BROWSE_GROUP_LIST, 485 "Browse Group List", 486 }, 487 { SDP_ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST, 488 "Language Base Attribute ID List", 489 }, 490 { SDP_ATTR_SERVICE_INFO_TIME_TO_LIVE, 491 "Service Info Time-To-Live", 492 }, 493 { SDP_ATTR_SERVICE_AVAILABILITY, 494 "Service Availability", 495 }, 496 { SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST, 497 "Bluetooh Profile Descriptor List", 498 }, 499 { SDP_ATTR_DOCUMENTATION_URL, 500 "Documentation URL", 501 }, 502 { SDP_ATTR_CLIENT_EXECUTABLE_URL, 503 "Client Executable URL", 504 }, 505 { SDP_ATTR_ICON_URL, 506 "Icon URL", 507 }, 508 { SDP_ATTR_ADDITIONAL_PROTOCOL_DESCRIPTOR_LISTS, 509 "Additional Protocol Descriptor Lists" }, 510 { SDP_ATTR_GROUP_ID, 511 /*SDP_ATTR_IP_SUBNET, 512 SDP_ATTR_VERSION_NUMBER_LIST*/ 513 "Group ID/IP Subnet/Version Number List", 514 }, 515 { SDP_ATTR_SERVICE_DATABASE_STATE, 516 "Service Database State", 517 }, 518 { SDP_ATTR_SERVICE_VERSION, 519 "Service Version", 520 }, 521 { SDP_ATTR_EXTERNAL_NETWORK, 522 /*SDP_ATTR_NETWORK, 523 SDP_ATTR_SUPPORTED_DATA_STORES_LIST*/ 524 "External Network/Network/Supported Data Stores List", 525 }, 526 { SDP_ATTR_FAX_CLASS1_SUPPORT, 527 /*SDP_ATTR_REMOTE_AUDIO_VOLUME_CONTROL*/ 528 "Fax Class1 Support/Remote Audio Volume Control", 529 }, 530 { SDP_ATTR_FAX_CLASS20_SUPPORT, 531 /*SDP_ATTR_SUPPORTED_FORMATS_LIST*/ 532 "Fax Class20 Support/Supported Formats List", 533 }, 534 { SDP_ATTR_FAX_CLASS2_SUPPORT, 535 "Fax Class2 Support", 536 }, 537 { SDP_ATTR_AUDIO_FEEDBACK_SUPPORT, 538 "Audio Feedback Support", 539 }, 540 { SDP_ATTR_NETWORK_ADDRESS, 541 "Network Address", 542 }, 543 { SDP_ATTR_WAP_GATEWAY, 544 "WAP Gateway", 545 }, 546 { SDP_ATTR_HOME_PAGE_URL, 547 "Home Page URL", 548 }, 549 { SDP_ATTR_WAP_STACK_TYPE, 550 "WAP Stack Type", 551 }, 552 { SDP_ATTR_SECURITY_DESCRIPTION, 553 "Security Description", 554 }, 555 { SDP_ATTR_NET_ACCESS_TYPE, 556 "Net Access Type", 557 }, 558 { SDP_ATTR_MAX_NET_ACCESS_RATE, 559 "Max Net Access Rate", 560 }, 561 { SDP_ATTR_IPV4_SUBNET, 562 "IPv4 Subnet", 563 }, 564 { SDP_ATTR_IPV6_SUBNET, 565 "IPv6 Subnet", 566 }, 567 { SDP_ATTR_SUPPORTED_CAPABALITIES, 568 "Supported Capabalities", 569 }, 570 { SDP_ATTR_SUPPORTED_FEATURES, 571 "Supported Features", 572 }, 573 { SDP_ATTR_SUPPORTED_FUNCTIONS, 574 "Supported Functions", 575 }, 576 { SDP_ATTR_TOTAL_IMAGING_DATA_CAPACITY, 577 "Total Imaging Data Capacity", 578 }, 579 { 0xffff, NULL, } 580 }; 581 582 char const * 583 sdp_attr2desc(uint16_t attr) 584 { 585 register sdp_attr_desc_p a = sdp_attrs_desc; 586 587 for (; a->desc != NULL; a++) 588 if (attr == a->attr) 589 break; 590 591 return ((a->desc != NULL)? a->desc : "Unknown"); 592 } 593 594 char const * 595 sdp_uuid2desc(uint16_t uuid) 596 { 597 register sdp_attr_desc_p a = sdp_uuids_desc; 598 599 for (; a->desc != NULL; a++) 600 if (uuid == a->attr) 601 break; 602 603 return ((a->desc != NULL)? a->desc : "Unknown"); 604 } 605 606 void 607 sdp_print(uint32_t level, uint8_t *start, uint8_t const *end) 608 { 609 610 (void)_sdp_data_print(start, end, level); 611 } 612