11558Srgrimes/* $NetBSD: sdp_compat.c,v 1.1 2009/05/12 10:05:06 plunky Exp $ */ 21558Srgrimes 31558Srgrimes/*- 41558Srgrimes * Copyright (c) 2006 Itronix Inc. 51558Srgrimes * All rights reserved. 61558Srgrimes * 71558Srgrimes * Written by Iain Hibbert for Itronix Inc. 81558Srgrimes * 91558Srgrimes * Redistribution and use in source and binary forms, with or without 101558Srgrimes * modification, are permitted provided that the following conditions 111558Srgrimes * are met: 121558Srgrimes * 1. Redistributions of source code must retain the above copyright 131558Srgrimes * notice, this list of conditions and the following disclaimer. 141558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 151558Srgrimes * notice, this list of conditions and the following disclaimer in the 161558Srgrimes * documentation and/or other materials provided with the distribution. 171558Srgrimes * 3. The name of Itronix Inc. may not be used to endorse 181558Srgrimes * or promote products derived from this software without specific 191558Srgrimes * prior written permission. 201558Srgrimes * 211558Srgrimes * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND 221558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 231558Srgrimes * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 241558Srgrimes * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY 251558Srgrimes * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 261558Srgrimes * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 271558Srgrimes * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 281558Srgrimes * ON ANY THEORY OF LIABILITY, WHETHER IN 291558Srgrimes * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 301558Srgrimes * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 311558Srgrimes * POSSIBILITY OF SUCH DAMAGE. 321558Srgrimes */ 331558Srgrimes/*- 3473986Sobrien * Copyright (c) 2001-2003 Maksim Yevmenkin <m_evmenkin@yahoo.com> 351558Srgrimes * All rights reserved. 361558Srgrimes * 371558Srgrimes * Redistribution and use in source and binary forms, with or without 381558Srgrimes * modification, are permitted provided that the following conditions 3973986Sobrien * are met: 401558Srgrimes * 1. Redistributions of source code must retain the above copyright 411558Srgrimes * notice, this list of conditions and the following disclaimer. 421558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 4321021Sobrien * 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.1 2009/05/12 10:05:06 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 90struct sdp_compat { 91 sdp_session_t ss; 92 int error; 93 uint8_t buf[256]; 94}; 95 96void * 97sdp_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 120void * 121sdp_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 139int32_t 140sdp_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 155int32_t 156sdp_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 166int32_t 167sdp_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 249int32_t 250sdp_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 299int32_t 300sdp_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 340int32_t 341sdp_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 376struct sdp_attr_desc { 377 uint32_t attr; 378 char const *desc; 379}; 380typedef struct sdp_attr_desc sdp_attr_desc_t; 381typedef struct sdp_attr_desc * sdp_attr_desc_p; 382 383static 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 468static 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 582char const * 583sdp_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 594char const * 595sdp_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 606void 607sdp_print(uint32_t level, uint8_t *start, uint8_t const *end) 608{ 609 610 (void)_sdp_data_print(start, end, level); 611} 612