1 /* 2 * 3 * BlueZ - Bluetooth protocol stack for Linux 4 * 5 * Copyright (C) 2001-2002 Nokia Corporation 6 * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk (at) qualcomm.com> 7 * Copyright (C) 2002-2009 Marcel Holtmann <marcel (at) holtmann.org> 8 * Copyright (C) 2002-2003 Stephen Crane <steve.crane (at) rococosoft.com> 9 * 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24 * 25 */ 26 27 #ifdef HAVE_CONFIG_H 28 #include <config.h> 29 #endif 30 31 #include <stdio.h> 32 #include <errno.h> 33 #include <fcntl.h> 34 #include <unistd.h> 35 #include <stdlib.h> 36 #include <limits.h> 37 #include <string.h> 38 #include <syslog.h> 39 #include <sys/time.h> 40 #include <sys/types.h> 41 #include <sys/socket.h> 42 #include <sys/un.h> 43 44 #include <bluetooth/bluetooth.h> 45 #include <bluetooth/hci.h> 46 #include <bluetooth/hci_lib.h> 47 #include <bluetooth/l2cap.h> 48 #include <bluetooth/sdp.h> 49 #include <bluetooth/sdp_lib.h> 50 51 #include <netinet/in.h> 52 53 #define SDPINF(fmt, arg...) syslog(LOG_INFO, fmt "\n", ## arg) 54 #define SDPERR(fmt, arg...) syslog(LOG_ERR, "%s: " fmt "\n", __func__ , ## arg) 55 56 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) 57 58 #ifdef SDP_DEBUG 59 #define SDPDBG(fmt, arg...) syslog(LOG_DEBUG, "%s: " fmt "\n", __func__ , ## arg) 60 #else 61 #define SDPDBG(fmt...) 62 #endif 63 64 #if __BYTE_ORDER == __BIG_ENDIAN 65 #define ntoh64(x) (x) 66 static inline void ntoh128(uint128_t *src, uint128_t *dst) 67 { 68 int i; 69 for (i = 0; i < 16; i++) 70 dst->data[i] = src->data[i]; 71 } 72 #else 73 static inline uint64_t ntoh64(uint64_t n) 74 { 75 uint64_t h; 76 uint64_t tmp = ntohl(n & 0x00000000ffffffff); 77 h = ntohl(n >> 32); 78 h |= tmp << 32; 79 return h; 80 } 81 static inline void ntoh128(uint128_t *src, uint128_t *dst) 82 { 83 int i; 84 for (i = 0; i < 16; i++) 85 dst->data[15 - i] = src->data[i]; 86 } 87 #endif 88 89 #define hton64(x) ntoh64(x) 90 #define hton128(x, y) ntoh128(x, y) 91 92 #define BASE_UUID "00000000-0000-1000-8000-00805F9B34FB" 93 94 static uint128_t bluetooth_base_uuid = { 95 .data = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 96 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB } 97 }; 98 99 #define SDP_MAX_ATTR_LEN 65535 100 101 static sdp_data_t *sdp_copy_seq(sdp_data_t *data); 102 static int sdp_attr_add_new_with_length(sdp_record_t *rec, 103 uint16_t attr, uint8_t dtd, const void *value, uint32_t len); 104 static int sdp_gen_buffer(sdp_buf_t *buf, sdp_data_t *d); 105 106 /* Message structure. */ 107 struct tupla { 108 int index; 109 char *str; 110 }; 111 112 static struct tupla Protocol[] = { 113 { SDP_UUID, "SDP" }, 114 { UDP_UUID, "UDP" }, 115 { RFCOMM_UUID, "RFCOMM" }, 116 { TCP_UUID, "TCP" }, 117 { TCS_BIN_UUID, "TCS-BIN" }, 118 { TCS_AT_UUID, "TCS-AT" }, 119 { OBEX_UUID, "OBEX" }, 120 { IP_UUID, "IP" }, 121 { FTP_UUID, "FTP" }, 122 { HTTP_UUID, "HTTP" }, 123 { WSP_UUID, "WSP" }, 124 { BNEP_UUID, "BNEP" }, 125 { UPNP_UUID, "UPNP" }, 126 { HIDP_UUID, "HIDP" }, 127 { HCRP_CTRL_UUID, "HCRP-Ctrl" }, 128 { HCRP_DATA_UUID, "HCRP-Data" }, 129 { HCRP_NOTE_UUID, "HCRP-Notify" }, 130 { AVCTP_UUID, "AVCTP" }, 131 { AVDTP_UUID, "AVDTP" }, 132 { CMTP_UUID, "CMTP" }, 133 { UDI_UUID, "UDI" }, 134 { MCAP_CTRL_UUID, "MCAP-Ctrl" }, 135 { MCAP_DATA_UUID, "MCAP-Data" }, 136 { L2CAP_UUID, "L2CAP" }, 137 { 0 } 138 }; 139 140 static struct tupla ServiceClass[] = { 141 { SDP_SERVER_SVCLASS_ID, "SDP Server" }, 142 { BROWSE_GRP_DESC_SVCLASS_ID, "Browse Group Descriptor" }, 143 { PUBLIC_BROWSE_GROUP, "Public Browse Group" }, 144 { SERIAL_PORT_SVCLASS_ID, "Serial Port" }, 145 { LAN_ACCESS_SVCLASS_ID, "LAN Access Using PPP" }, 146 { DIALUP_NET_SVCLASS_ID, "Dialup Networking" }, 147 { IRMC_SYNC_SVCLASS_ID, "IrMC Sync" }, 148 { OBEX_OBJPUSH_SVCLASS_ID, "OBEX Object Push" }, 149 { OBEX_FILETRANS_SVCLASS_ID, "OBEX File Transfer" }, 150 { IRMC_SYNC_CMD_SVCLASS_ID, "IrMC Sync Command" }, 151 { HEADSET_SVCLASS_ID, "Headset" }, 152 { CORDLESS_TELEPHONY_SVCLASS_ID, "Cordless Telephony" }, 153 { AUDIO_SOURCE_SVCLASS_ID, "Audio Source" }, 154 { AUDIO_SINK_SVCLASS_ID, "Audio Sink" }, 155 { AV_REMOTE_TARGET_SVCLASS_ID, "AV Remote Target" }, 156 { ADVANCED_AUDIO_SVCLASS_ID, "Advanced Audio" }, 157 { AV_REMOTE_SVCLASS_ID, "AV Remote" }, 158 { VIDEO_CONF_SVCLASS_ID, "Video Conferencing" }, 159 { INTERCOM_SVCLASS_ID, "Intercom" }, 160 { FAX_SVCLASS_ID, "Fax" }, 161 { HEADSET_AGW_SVCLASS_ID, "Headset Audio Gateway" }, 162 { WAP_SVCLASS_ID, "WAP" }, 163 { WAP_CLIENT_SVCLASS_ID, "WAP Client" }, 164 { PANU_SVCLASS_ID, "PAN User" }, 165 { NAP_SVCLASS_ID, "Network Access Point" }, 166 { GN_SVCLASS_ID, "PAN Group Network" }, 167 { DIRECT_PRINTING_SVCLASS_ID, "Direct Printing" }, 168 { REFERENCE_PRINTING_SVCLASS_ID, "Reference Printing" }, 169 { IMAGING_SVCLASS_ID, "Imaging" }, 170 { IMAGING_RESPONDER_SVCLASS_ID, "Imaging Responder" }, 171 { IMAGING_ARCHIVE_SVCLASS_ID, "Imaging Automatic Archive" }, 172 { IMAGING_REFOBJS_SVCLASS_ID, "Imaging Referenced Objects" }, 173 { HANDSFREE_SVCLASS_ID, "Handsfree" }, 174 { HANDSFREE_AGW_SVCLASS_ID, "Handsfree Audio Gateway" }, 175 { DIRECT_PRT_REFOBJS_SVCLASS_ID, "Direct Printing Ref. Objects" }, 176 { REFLECTED_UI_SVCLASS_ID, "Reflected UI" }, 177 { BASIC_PRINTING_SVCLASS_ID, "Basic Printing" }, 178 { PRINTING_STATUS_SVCLASS_ID, "Printing Status" }, 179 { HID_SVCLASS_ID, "Human Interface Device" }, 180 { HCR_SVCLASS_ID, "Hardcopy Cable Replacement" }, 181 { HCR_PRINT_SVCLASS_ID, "HCR Print" }, 182 { HCR_SCAN_SVCLASS_ID, "HCR Scan" }, 183 { CIP_SVCLASS_ID, "Common ISDN Access" }, 184 { VIDEO_CONF_GW_SVCLASS_ID, "Video Conferencing Gateway" }, 185 { UDI_MT_SVCLASS_ID, "UDI MT" }, 186 { UDI_TA_SVCLASS_ID, "UDI TA" }, 187 { AV_SVCLASS_ID, "Audio/Video" }, 188 { SAP_SVCLASS_ID, "SIM Access" }, 189 { PBAP_PCE_SVCLASS_ID, "Phonebook Access - PCE" }, 190 { PBAP_PSE_SVCLASS_ID, "Phonebook Access - PSE" }, 191 { PBAP_SVCLASS_ID, "Phonebook Access" }, 192 { PNP_INFO_SVCLASS_ID, "PnP Information" }, 193 { GENERIC_NETWORKING_SVCLASS_ID, "Generic Networking" }, 194 { GENERIC_FILETRANS_SVCLASS_ID, "Generic File Transfer" }, 195 { GENERIC_AUDIO_SVCLASS_ID, "Generic Audio" }, 196 { GENERIC_TELEPHONY_SVCLASS_ID, "Generic Telephony" }, 197 { UPNP_SVCLASS_ID, "UPnP" }, 198 { UPNP_IP_SVCLASS_ID, "UPnP IP" }, 199 { UPNP_PAN_SVCLASS_ID, "UPnP PAN" }, 200 { UPNP_LAP_SVCLASS_ID, "UPnP LAP" }, 201 { UPNP_L2CAP_SVCLASS_ID, "UPnP L2CAP" }, 202 { VIDEO_SOURCE_SVCLASS_ID, "Video Source" }, 203 { VIDEO_SINK_SVCLASS_ID, "Video Sink" }, 204 { VIDEO_DISTRIBUTION_SVCLASS_ID, "Video Distribution" }, 205 { MDP_SVCLASS_ID, "MDP" }, 206 { MDP_SOURCE_SVCLASS_ID, "MDP Source" }, 207 { MDP_SINK_SVCLASS_ID, "MDP Sink" }, 208 { APPLE_AGENT_SVCLASS_ID, "Apple Agent" }, 209 { 0 } 210 }; 211 212 #define Profile ServiceClass 213 214 static char *string_lookup(struct tupla *pt0, int index) 215 { 216 struct tupla *pt; 217 218 for (pt = pt0; pt->index; pt++) 219 if (pt->index == index) 220 return pt->str; 221 222 return ""; 223 } 224 225 static char *string_lookup_uuid(struct tupla *pt0, const uuid_t* uuid) 226 { 227 uuid_t tmp_uuid; 228 229 memcpy(&tmp_uuid, uuid, sizeof(tmp_uuid)); 230 231 if (sdp_uuid128_to_uuid(&tmp_uuid)) { 232 switch (tmp_uuid.type) { 233 case SDP_UUID16: 234 return string_lookup(pt0, tmp_uuid.value.uuid16); 235 case SDP_UUID32: 236 return string_lookup(pt0, tmp_uuid.value.uuid32); 237 } 238 } 239 240 return ""; 241 } 242 243 /* 244 * Prints into a string the Protocol UUID 245 * coping a maximum of n characters. 246 */ 247 static int uuid2str(struct tupla *message, const uuid_t *uuid, char *str, size_t n) 248 { 249 char *str2; 250 251 if (!uuid) { 252 snprintf(str, n, "NULL"); 253 return -2; 254 } 255 256 switch (uuid->type) { 257 case SDP_UUID16: 258 str2 = string_lookup(message, uuid->value.uuid16); 259 snprintf(str, n, "%s", str2); 260 break; 261 case SDP_UUID32: 262 str2 = string_lookup(message, uuid->value.uuid32); 263 snprintf(str, n, "%s", str2); 264 break; 265 case SDP_UUID128: 266 str2 = string_lookup_uuid(message, uuid); 267 snprintf(str, n, "%s", str2); 268 break; 269 default: 270 snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type); 271 return -1; 272 } 273 274 return 0; 275 } 276 277 int sdp_proto_uuid2strn(const uuid_t *uuid, char *str, size_t n) 278 { 279 return uuid2str(Protocol, uuid, str, n); 280 } 281 282 int sdp_svclass_uuid2strn(const uuid_t *uuid, char *str, size_t n) 283 { 284 return uuid2str(ServiceClass, uuid, str, n); 285 } 286 287 int sdp_profile_uuid2strn(const uuid_t *uuid, char *str, size_t n) 288 { 289 return uuid2str(Profile, uuid, str, n); 290 } 291 292 /* 293 * convert the UUID to string, copying a maximum of n characters. 294 */ 295 int sdp_uuid2strn(const uuid_t *uuid, char *str, size_t n) 296 { 297 if (!uuid) { 298 snprintf(str, n, "NULL"); 299 return -2; 300 } 301 switch (uuid->type) { 302 case SDP_UUID16: 303 snprintf(str, n, "%.4x", uuid->value.uuid16); 304 break; 305 case SDP_UUID32: 306 snprintf(str, n, "%.8x", uuid->value.uuid32); 307 break; 308 case SDP_UUID128:{ 309 unsigned int data0; 310 unsigned short data1; 311 unsigned short data2; 312 unsigned short data3; 313 unsigned int data4; 314 unsigned short data5; 315 316 memcpy(&data0, &uuid->value.uuid128.data[0], 4); 317 memcpy(&data1, &uuid->value.uuid128.data[4], 2); 318 memcpy(&data2, &uuid->value.uuid128.data[6], 2); 319 memcpy(&data3, &uuid->value.uuid128.data[8], 2); 320 memcpy(&data4, &uuid->value.uuid128.data[10], 4); 321 memcpy(&data5, &uuid->value.uuid128.data[14], 2); 322 323 snprintf(str, n, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x", 324 ntohl(data0), ntohs(data1), 325 ntohs(data2), ntohs(data3), 326 ntohl(data4), ntohs(data5)); 327 } 328 break; 329 default: 330 snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type); 331 return -1; /* Enum type of UUID not set */ 332 } 333 return 0; 334 } 335 336 #ifdef SDP_DEBUG 337 /* 338 * Function prints the UUID in hex as per defined syntax - 339 * 340 * 4bytes-2bytes-2bytes-2bytes-6bytes 341 * 342 * There is some ugly code, including hardcoding, but 343 * that is just the way it is converting 16 and 32 bit 344 * UUIDs to 128 bit as defined in the SDP doc 345 */ 346 void sdp_uuid_print(const uuid_t *uuid) 347 { 348 if (uuid == NULL) { 349 SDPERR("Null passed to print UUID\n"); 350 return; 351 } 352 if (uuid->type == SDP_UUID16) { 353 SDPDBG(" uint16_t : 0x%.4x\n", uuid->value.uuid16); 354 } else if (uuid->type == SDP_UUID32) { 355 SDPDBG(" uint32_t : 0x%.8x\n", uuid->value.uuid32); 356 } else if (uuid->type == SDP_UUID128) { 357 unsigned int data0; 358 unsigned short data1; 359 unsigned short data2; 360 unsigned short data3; 361 unsigned int data4; 362 unsigned short data5; 363 364 memcpy(&data0, &uuid->value.uuid128.data[0], 4); 365 memcpy(&data1, &uuid->value.uuid128.data[4], 2); 366 memcpy(&data2, &uuid->value.uuid128.data[6], 2); 367 memcpy(&data3, &uuid->value.uuid128.data[8], 2); 368 memcpy(&data4, &uuid->value.uuid128.data[10], 4); 369 memcpy(&data5, &uuid->value.uuid128.data[14], 2); 370 371 SDPDBG(" uint128_t : 0x%.8x-", ntohl(data0)); 372 SDPDBG("%.4x-", ntohs(data1)); 373 SDPDBG("%.4x-", ntohs(data2)); 374 SDPDBG("%.4x-", ntohs(data3)); 375 SDPDBG("%.8x", ntohl(data4)); 376 SDPDBG("%.4x\n", ntohs(data5)); 377 } else 378 SDPERR("Enum type of UUID not set\n"); 379 } 380 #endif 381 382 sdp_data_t *sdp_data_alloc_with_length(uint8_t dtd, const void *value, 383 uint32_t length) 384 { 385 sdp_data_t *seq; 386 sdp_data_t *d = malloc(sizeof(sdp_data_t)); 387 388 if (!d) 389 return NULL; 390 391 memset(d, 0, sizeof(sdp_data_t)); 392 d->dtd = dtd; 393 d->unitSize = sizeof(uint8_t); 394 395 switch (dtd) { 396 case SDP_DATA_NIL: 397 break; 398 case SDP_UINT8: 399 d->val.uint8 = *(uint8_t *) value; 400 d->unitSize += sizeof(uint8_t); 401 break; 402 case SDP_INT8: 403 case SDP_BOOL: 404 d->val.int8 = *(int8_t *) value; 405 d->unitSize += sizeof(int8_t); 406 break; 407 case SDP_UINT16: 408 d->val.uint16 = bt_get_unaligned((uint16_t *) value); 409 d->unitSize += sizeof(uint16_t); 410 break; 411 case SDP_INT16: 412 d->val.int16 = bt_get_unaligned((int16_t *) value); 413 d->unitSize += sizeof(int16_t); 414 break; 415 case SDP_UINT32: 416 d->val.uint32 = bt_get_unaligned((uint32_t *) value); 417 d->unitSize += sizeof(uint32_t); 418 break; 419 case SDP_INT32: 420 d->val.int32 = bt_get_unaligned((int32_t *) value); 421 d->unitSize += sizeof(int32_t); 422 break; 423 case SDP_INT64: 424 d->val.int64 = bt_get_unaligned((int64_t *) value); 425 d->unitSize += sizeof(int64_t); 426 break; 427 case SDP_UINT64: 428 d->val.uint64 = bt_get_unaligned((uint64_t *) value); 429 d->unitSize += sizeof(uint64_t); 430 break; 431 case SDP_UINT128: 432 memcpy(&d->val.uint128.data, value, sizeof(uint128_t)); 433 d->unitSize += sizeof(uint128_t); 434 break; 435 case SDP_INT128: 436 memcpy(&d->val.int128.data, value, sizeof(uint128_t)); 437 d->unitSize += sizeof(uint128_t); 438 break; 439 case SDP_UUID16: 440 sdp_uuid16_create(&d->val.uuid, bt_get_unaligned((uint16_t *) value)); 441 d->unitSize += sizeof(uint16_t); 442 break; 443 case SDP_UUID32: 444 sdp_uuid32_create(&d->val.uuid, bt_get_unaligned((uint32_t *) value)); 445 d->unitSize += sizeof(uint32_t); 446 break; 447 case SDP_UUID128: 448 sdp_uuid128_create(&d->val.uuid, value); 449 d->unitSize += sizeof(uint128_t); 450 break; 451 case SDP_URL_STR8: 452 case SDP_URL_STR16: 453 case SDP_TEXT_STR8: 454 case SDP_TEXT_STR16: 455 if (!value) { 456 free(d); 457 return NULL; 458 } 459 460 d->unitSize += length; 461 if (length <= USHRT_MAX) { 462 d->val.str = malloc(length); 463 if (!d->val.str) { 464 free(d); 465 return NULL; 466 } 467 468 memcpy(d->val.str, value, length); 469 } else { 470 SDPERR("Strings of size > USHRT_MAX not supported\n"); 471 free(d); 472 d = NULL; 473 } 474 break; 475 case SDP_URL_STR32: 476 case SDP_TEXT_STR32: 477 SDPERR("Strings of size > USHRT_MAX not supported\n"); 478 break; 479 case SDP_ALT8: 480 case SDP_ALT16: 481 case SDP_ALT32: 482 case SDP_SEQ8: 483 case SDP_SEQ16: 484 case SDP_SEQ32: 485 if (dtd == SDP_ALT8 || dtd == SDP_SEQ8) 486 d->unitSize += sizeof(uint8_t); 487 else if (dtd == SDP_ALT16 || dtd == SDP_SEQ16) 488 d->unitSize += sizeof(uint16_t); 489 else if (dtd == SDP_ALT32 || dtd == SDP_SEQ32) 490 d->unitSize += sizeof(uint32_t); 491 seq = (sdp_data_t *)value; 492 d->val.dataseq = seq; 493 for (; seq; seq = seq->next) 494 d->unitSize += seq->unitSize; 495 break; 496 default: 497 free(d); 498 d = NULL; 499 } 500 501 return d; 502 } 503 504 sdp_data_t *sdp_data_alloc(uint8_t dtd, const void *value) 505 { 506 uint32_t length; 507 508 switch (dtd) { 509 case SDP_URL_STR8: 510 case SDP_URL_STR16: 511 case SDP_TEXT_STR8: 512 case SDP_TEXT_STR16: 513 if (!value) 514 return NULL; 515 516 length = strlen((char *) value); 517 break; 518 default: 519 length = 0; 520 break; 521 } 522 523 return sdp_data_alloc_with_length(dtd, value, length); 524 } 525 526 sdp_data_t *sdp_seq_append(sdp_data_t *seq, sdp_data_t *d) 527 { 528 if (seq) { 529 sdp_data_t *p; 530 for (p = seq; p->next; p = p->next); 531 p->next = d; 532 } else 533 seq = d; 534 d->next = NULL; 535 return seq; 536 } 537 538 sdp_data_t *sdp_seq_alloc_with_length(void **dtds, void **values, int *length, 539 int len) 540 { 541 sdp_data_t *curr = NULL, *seq = NULL; 542 int i; 543 544 for (i = 0; i < len; i++) { 545 sdp_data_t *data; 546 int8_t dtd = *(uint8_t *) dtds[i]; 547 548 if (dtd >= SDP_SEQ8 && dtd <= SDP_ALT32) 549 data = (sdp_data_t *) values[i]; 550 else 551 data = sdp_data_alloc_with_length(dtd, values[i], length[i]); 552 553 if (!data) 554 return NULL; 555 556 if (curr) 557 curr->next = data; 558 else 559 seq = data; 560 561 curr = data; 562 } 563 564 return sdp_data_alloc_with_length(SDP_SEQ8, seq, length[i]); 565 } 566 567 sdp_data_t *sdp_seq_alloc(void **dtds, void **values, int len) 568 { 569 sdp_data_t *curr = NULL, *seq = NULL; 570 int i; 571 572 for (i = 0; i < len; i++) { 573 sdp_data_t *data; 574 uint8_t dtd = *(uint8_t *) dtds[i]; 575 576 if (dtd >= SDP_SEQ8 && dtd <= SDP_ALT32) 577 data = (sdp_data_t *) values[i]; 578 else 579 data = sdp_data_alloc(dtd, values[i]); 580 581 if (!data) 582 return NULL; 583 584 if (curr) 585 curr->next = data; 586 else 587 seq = data; 588 589 curr = data; 590 } 591 592 return sdp_data_alloc(SDP_SEQ8, seq); 593 } 594 595 static void extract_svclass_uuid(sdp_data_t *data, uuid_t *uuid) 596 { 597 sdp_data_t *d; 598 599 if (!data || data->dtd < SDP_SEQ8 || data->dtd > SDP_SEQ32) 600 return; 601 602 d = data->val.dataseq; 603 if (!d) 604 return; 605 606 if (d->dtd < SDP_UUID16 || d->dtd > SDP_UUID128) 607 return; 608 609 *uuid = d->val.uuid; 610 } 611 612 int sdp_attr_add(sdp_record_t *rec, uint16_t attr, sdp_data_t *d) 613 { 614 sdp_data_t *p = sdp_data_get(rec, attr); 615 616 if (p) 617 return -1; 618 619 d->attrId = attr; 620 rec->attrlist = sdp_list_insert_sorted(rec->attrlist, d, sdp_attrid_comp_func); 621 622 if (attr == SDP_ATTR_SVCLASS_ID_LIST) 623 extract_svclass_uuid(d, &rec->svclass); 624 625 return 0; 626 } 627 628 void sdp_attr_remove(sdp_record_t *rec, uint16_t attr) 629 { 630 sdp_data_t *d = sdp_data_get(rec, attr); 631 632 if (d) 633 rec->attrlist = sdp_list_remove(rec->attrlist, d); 634 635 if (attr == SDP_ATTR_SVCLASS_ID_LIST) 636 memset(&rec->svclass, 0, sizeof(rec->svclass)); 637 } 638 639 void sdp_set_seq_len(uint8_t *ptr, uint32_t length) 640 { 641 uint8_t dtd = *(uint8_t *) ptr++; 642 643 switch (dtd) { 644 case SDP_SEQ8: 645 case SDP_ALT8: 646 case SDP_TEXT_STR8: 647 case SDP_URL_STR8: 648 *(uint8_t *)ptr = (uint8_t) length; 649 break; 650 case SDP_SEQ16: 651 case SDP_ALT16: 652 case SDP_TEXT_STR16: 653 case SDP_URL_STR16: 654 bt_put_unaligned(htons(length), (uint16_t *) ptr); 655 break; 656 case SDP_SEQ32: 657 case SDP_ALT32: 658 case SDP_TEXT_STR32: 659 case SDP_URL_STR32: 660 bt_put_unaligned(htonl(length), (uint32_t *) ptr); 661 break; 662 } 663 } 664 665 static int sdp_get_data_type(sdp_buf_t *buf, uint8_t dtd) 666 { 667 int data_type = 0; 668 669 data_type += sizeof(uint8_t); 670 671 switch (dtd) { 672 case SDP_SEQ8: 673 case SDP_TEXT_STR8: 674 case SDP_URL_STR8: 675 case SDP_ALT8: 676 data_type += sizeof(uint8_t); 677 break; 678 case SDP_SEQ16: 679 case SDP_TEXT_STR16: 680 case SDP_URL_STR16: 681 case SDP_ALT16: 682 data_type += sizeof(uint16_t); 683 break; 684 case SDP_SEQ32: 685 case SDP_TEXT_STR32: 686 case SDP_URL_STR32: 687 case SDP_ALT32: 688 data_type += sizeof(uint32_t); 689 break; 690 } 691 692 if (!buf->data) 693 buf->buf_size += data_type; 694 695 return data_type; 696 } 697 698 static int sdp_set_data_type(sdp_buf_t *buf, uint8_t dtd) 699 { 700 int data_type = 0; 701 uint8_t *p = buf->data + buf->data_size; 702 703 *p++ = dtd; 704 data_type = sdp_get_data_type(buf, dtd); 705 buf->data_size += data_type; 706 707 return data_type; 708 } 709 710 void sdp_set_attrid(sdp_buf_t *buf, uint16_t attr) 711 { 712 uint8_t *p = buf->data; 713 714 /* data type for attr */ 715 *p++ = SDP_UINT16; 716 buf->data_size = sizeof(uint8_t); 717 bt_put_unaligned(htons(attr), (uint16_t *) p); 718 p += sizeof(uint16_t); 719 buf->data_size += sizeof(uint16_t); 720 } 721 722 static int get_data_size(sdp_buf_t *buf, sdp_data_t *sdpdata) 723 { 724 sdp_data_t *d; 725 int n = 0; 726 727 for (d = sdpdata->val.dataseq; d; d = d->next) { 728 if (buf->data) 729 n += sdp_gen_pdu(buf, d); 730 else 731 n += sdp_gen_buffer(buf, d); 732 } 733 734 return n; 735 } 736 737 static int sdp_get_data_size(sdp_buf_t *buf, sdp_data_t *d) 738 { 739 uint32_t data_size = 0; 740 uint8_t dtd = d->dtd; 741 742 switch (dtd) { 743 case SDP_DATA_NIL: 744 break; 745 case SDP_UINT8: 746 data_size = sizeof(uint8_t); 747 break; 748 case SDP_UINT16: 749 data_size = sizeof(uint16_t); 750 break; 751 case SDP_UINT32: 752 data_size = sizeof(uint32_t); 753 break; 754 case SDP_UINT64: 755 data_size = sizeof(uint64_t); 756 break; 757 case SDP_UINT128: 758 data_size = sizeof(uint128_t); 759 break; 760 case SDP_INT8: 761 case SDP_BOOL: 762 data_size = sizeof(int8_t); 763 break; 764 case SDP_INT16: 765 data_size = sizeof(int16_t); 766 break; 767 case SDP_INT32: 768 data_size = sizeof(int32_t); 769 break; 770 case SDP_INT64: 771 data_size = sizeof(int64_t); 772 break; 773 case SDP_INT128: 774 data_size = sizeof(uint128_t); 775 break; 776 case SDP_TEXT_STR8: 777 case SDP_TEXT_STR16: 778 case SDP_TEXT_STR32: 779 case SDP_URL_STR8: 780 case SDP_URL_STR16: 781 case SDP_URL_STR32: 782 data_size = d->unitSize - sizeof(uint8_t); 783 break; 784 case SDP_SEQ8: 785 case SDP_SEQ16: 786 case SDP_SEQ32: 787 data_size = get_data_size(buf, d); 788 break; 789 case SDP_ALT8: 790 case SDP_ALT16: 791 case SDP_ALT32: 792 data_size = get_data_size(buf, d); 793 break; 794 case SDP_UUID16: 795 data_size = sizeof(uint16_t); 796 break; 797 case SDP_UUID32: 798 data_size = sizeof(uint32_t); 799 break; 800 case SDP_UUID128: 801 data_size = sizeof(uint128_t); 802 break; 803 default: 804 break; 805 } 806 807 if (!buf->data) 808 buf->buf_size += data_size; 809 810 return data_size; 811 } 812 813 static int sdp_gen_buffer(sdp_buf_t *buf, sdp_data_t *d) 814 { 815 int orig = buf->buf_size; 816 817 if (buf->buf_size == 0 && d->dtd == 0) { 818 /* create initial sequence */ 819 buf->buf_size += sizeof(uint8_t); 820 821 /* reserve space for sequence size */ 822 buf->buf_size += sizeof(uint8_t); 823 } 824 825 /* attribute length */ 826 buf->buf_size += sizeof(uint8_t) + sizeof(uint16_t); 827 828 sdp_get_data_type(buf, d->dtd); 829 sdp_get_data_size(buf, d); 830 831 if (buf->buf_size > UCHAR_MAX && d->dtd == SDP_SEQ8) 832 buf->buf_size += sizeof(uint8_t); 833 834 return buf->buf_size - orig; 835 } 836 837 int sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d) 838 { 839 uint32_t pdu_size = 0, data_size = 0; 840 unsigned char *src = NULL, is_seq = 0, is_alt = 0; 841 uint8_t dtd = d->dtd; 842 uint16_t u16; 843 uint32_t u32; 844 uint64_t u64; 845 uint128_t u128; 846 uint8_t *seqp = buf->data + buf->data_size; 847 848 pdu_size = sdp_set_data_type(buf, dtd); 849 data_size = sdp_get_data_size(buf, d); 850 851 switch (dtd) { 852 case SDP_DATA_NIL: 853 break; 854 case SDP_UINT8: 855 src = &d->val.uint8; 856 break; 857 case SDP_UINT16: 858 u16 = htons(d->val.uint16); 859 src = (unsigned char *) &u16; 860 break; 861 case SDP_UINT32: 862 u32 = htonl(d->val.uint32); 863 src = (unsigned char *) &u32; 864 break; 865 case SDP_UINT64: 866 u64 = hton64(d->val.uint64); 867 src = (unsigned char *) &u64; 868 break; 869 case SDP_UINT128: 870 hton128(&d->val.uint128, &u128); 871 src = (unsigned char *) &u128; 872 break; 873 case SDP_INT8: 874 case SDP_BOOL: 875 src = (unsigned char *) &d->val.int8; 876 break; 877 case SDP_INT16: 878 u16 = htons(d->val.int16); 879 src = (unsigned char *) &u16; 880 break; 881 case SDP_INT32: 882 u32 = htonl(d->val.int32); 883 src = (unsigned char *) &u32; 884 break; 885 case SDP_INT64: 886 u64 = hton64(d->val.int64); 887 src = (unsigned char *) &u64; 888 break; 889 case SDP_INT128: 890 hton128(&d->val.int128, &u128); 891 src = (unsigned char *) &u128; 892 break; 893 case SDP_TEXT_STR8: 894 case SDP_TEXT_STR16: 895 case SDP_TEXT_STR32: 896 case SDP_URL_STR8: 897 case SDP_URL_STR16: 898 case SDP_URL_STR32: 899 src = (unsigned char *) d->val.str; 900 sdp_set_seq_len(seqp, data_size); 901 break; 902 case SDP_SEQ8: 903 case SDP_SEQ16: 904 case SDP_SEQ32: 905 is_seq = 1; 906 sdp_set_seq_len(seqp, data_size); 907 break; 908 case SDP_ALT8: 909 case SDP_ALT16: 910 case SDP_ALT32: 911 is_alt = 1; 912 sdp_set_seq_len(seqp, data_size); 913 break; 914 case SDP_UUID16: 915 u16 = htons(d->val.uuid.value.uuid16); 916 src = (unsigned char *) &u16; 917 break; 918 case SDP_UUID32: 919 u32 = htonl(d->val.uuid.value.uuid32); 920 src = (unsigned char *) &u32; 921 break; 922 case SDP_UUID128: 923 src = (unsigned char *) &d->val.uuid.value.uuid128; 924 break; 925 default: 926 break; 927 } 928 929 if (!is_seq && !is_alt) { 930 if (src && buf && buf->buf_size >= buf->data_size + data_size) { 931 memcpy(buf->data + buf->data_size, src, data_size); 932 buf->data_size += data_size; 933 } else if (dtd != SDP_DATA_NIL) { 934 SDPDBG("Gen PDU : Can't copy from invalid source or dest\n"); 935 } 936 } 937 938 pdu_size += data_size; 939 940 return pdu_size; 941 } 942 943 static void sdp_attr_pdu(void *value, void *udata) 944 { 945 sdp_append_to_pdu((sdp_buf_t *)udata, (sdp_data_t *)value); 946 } 947 948 static void sdp_attr_size(void *value, void *udata) 949 { 950 sdp_gen_buffer((sdp_buf_t *)udata, (sdp_data_t *)value); 951 } 952 953 int sdp_gen_record_pdu(const sdp_record_t *rec, sdp_buf_t *buf) 954 { 955 memset(buf, 0, sizeof(sdp_buf_t)); 956 sdp_list_foreach(rec->attrlist, sdp_attr_size, buf); 957 958 buf->data = malloc(buf->buf_size); 959 if (!buf->data) 960 return -ENOMEM; 961 buf->data_size = 0; 962 memset(buf->data, 0, buf->buf_size); 963 964 sdp_list_foreach(rec->attrlist, sdp_attr_pdu, buf); 965 966 return 0; 967 } 968 969 void sdp_attr_replace(sdp_record_t *rec, uint16_t attr, sdp_data_t *d) 970 { 971 sdp_data_t *p = sdp_data_get(rec, attr); 972 973 if (p) { 974 rec->attrlist = sdp_list_remove(rec->attrlist, p); 975 sdp_data_free(p); 976 } 977 978 d->attrId = attr; 979 rec->attrlist = sdp_list_insert_sorted(rec->attrlist, d, sdp_attrid_comp_func); 980 981 if (attr == SDP_ATTR_SVCLASS_ID_LIST) 982 extract_svclass_uuid(d, &rec->svclass); 983 } 984 985 int sdp_attrid_comp_func(const void *key1, const void *key2) 986 { 987 const sdp_data_t *d1 = (const sdp_data_t *)key1; 988 const sdp_data_t *d2 = (const sdp_data_t *)key2; 989 990 if (d1 && d2) 991 return d1->attrId - d2->attrId; 992 return 0; 993 } 994 995 static void data_seq_free(sdp_data_t *seq) 996 { 997 sdp_data_t *d = seq->val.dataseq; 998 999 while (d) { 1000 sdp_data_t *next = d->next; 1001 sdp_data_free(d); 1002 d = next; 1003 } 1004 } 1005 1006 void sdp_data_free(sdp_data_t *d) 1007 { 1008 switch (d->dtd) { 1009 case SDP_SEQ8: 1010 case SDP_SEQ16: 1011 case SDP_SEQ32: 1012 data_seq_free(d); 1013 break; 1014 case SDP_URL_STR8: 1015 case SDP_URL_STR16: 1016 case SDP_URL_STR32: 1017 case SDP_TEXT_STR8: 1018 case SDP_TEXT_STR16: 1019 case SDP_TEXT_STR32: 1020 free(d->val.str); 1021 break; 1022 } 1023 free(d); 1024 } 1025 1026 int sdp_uuid_extract(const uint8_t *p, int bufsize, uuid_t *uuid, int *scanned) 1027 { 1028 uint8_t type; 1029 1030 if (bufsize < (int) sizeof(uint8_t)) { 1031 SDPERR("Unexpected end of packet"); 1032 return -1; 1033 } 1034 1035 type = *(const uint8_t *) p; 1036 1037 if (!SDP_IS_UUID(type)) { 1038 SDPERR("Unknown data type : %d expecting a svc UUID\n", type); 1039 return -1; 1040 } 1041 p += sizeof(uint8_t); 1042 *scanned += sizeof(uint8_t); 1043 bufsize -= sizeof(uint8_t); 1044 if (type == SDP_UUID16) { 1045 if (bufsize < (int) sizeof(uint16_t)) { 1046 SDPERR("Not enough room for 16-bit UUID"); 1047 return -1; 1048 } 1049 sdp_uuid16_create(uuid, ntohs(bt_get_unaligned((uint16_t *) p))); 1050 *scanned += sizeof(uint16_t); 1051 p += sizeof(uint16_t); 1052 } else if (type == SDP_UUID32) { 1053 if (bufsize < (int) sizeof(uint32_t)) { 1054 SDPERR("Not enough room for 32-bit UUID"); 1055 return -1; 1056 } 1057 sdp_uuid32_create(uuid, ntohl(bt_get_unaligned((uint32_t *) p))); 1058 *scanned += sizeof(uint32_t); 1059 p += sizeof(uint32_t); 1060 } else { 1061 if (bufsize < (int) sizeof(uint128_t)) { 1062 SDPERR("Not enough room for 128-bit UUID"); 1063 return -1; 1064 } 1065 sdp_uuid128_create(uuid, p); 1066 *scanned += sizeof(uint128_t); 1067 p += sizeof(uint128_t); 1068 } 1069 return 0; 1070 } 1071 1072 static sdp_data_t *extract_int(const void *p, int bufsize, int *len) 1073 { 1074 sdp_data_t *d; 1075 1076 if (bufsize < (int) sizeof(uint8_t)) { 1077 SDPERR("Unexpected end of packet"); 1078 return NULL; 1079 } 1080 1081 d = malloc(sizeof(sdp_data_t)); 1082 1083 SDPDBG("Extracting integer\n"); 1084 memset(d, 0, sizeof(sdp_data_t)); 1085 d->dtd = *(uint8_t *) p; 1086 p += sizeof(uint8_t); 1087 *len += sizeof(uint8_t); 1088 bufsize -= sizeof(uint8_t); 1089 1090 switch (d->dtd) { 1091 case SDP_DATA_NIL: 1092 break; 1093 case SDP_BOOL: 1094 case SDP_INT8: 1095 case SDP_UINT8: 1096 if (bufsize < (int) sizeof(uint8_t)) { 1097 SDPERR("Unexpected end of packet"); 1098 free(d); 1099 return NULL; 1100 } 1101 *len += sizeof(uint8_t); 1102 d->val.uint8 = *(uint8_t *) p; 1103 break; 1104 case SDP_INT16: 1105 case SDP_UINT16: 1106 if (bufsize < (int) sizeof(uint16_t)) { 1107 SDPERR("Unexpected end of packet"); 1108 free(d); 1109 return NULL; 1110 } 1111 *len += sizeof(uint16_t); 1112 d->val.uint16 = ntohs(bt_get_unaligned((uint16_t *) p)); 1113 break; 1114 case SDP_INT32: 1115 case SDP_UINT32: 1116 if (bufsize < (int) sizeof(uint32_t)) { 1117 SDPERR("Unexpected end of packet"); 1118 free(d); 1119 return NULL; 1120 } 1121 *len += sizeof(uint32_t); 1122 d->val.uint32 = ntohl(bt_get_unaligned((uint32_t *) p)); 1123 break; 1124 case SDP_INT64: 1125 case SDP_UINT64: 1126 if (bufsize < (int) sizeof(uint64_t)) { 1127 SDPERR("Unexpected end of packet"); 1128 free(d); 1129 return NULL; 1130 } 1131 *len += sizeof(uint64_t); 1132 d->val.uint64 = ntoh64(bt_get_unaligned((uint64_t *) p)); 1133 break; 1134 case SDP_INT128: 1135 case SDP_UINT128: 1136 if (bufsize < (int) sizeof(uint128_t)) { 1137 SDPERR("Unexpected end of packet"); 1138 free(d); 1139 return NULL; 1140 } 1141 *len += sizeof(uint128_t); 1142 ntoh128((uint128_t *) p, &d->val.uint128); 1143 break; 1144 default: 1145 free(d); 1146 d = NULL; 1147 } 1148 return d; 1149 } 1150 1151 static sdp_data_t *extract_uuid(const uint8_t *p, int bufsize, int *len, 1152 sdp_record_t *rec) 1153 { 1154 sdp_data_t *d = malloc(sizeof(sdp_data_t)); 1155 1156 SDPDBG("Extracting UUID"); 1157 memset(d, 0, sizeof(sdp_data_t)); 1158 if (sdp_uuid_extract(p, bufsize, &d->val.uuid, len) < 0) { 1159 free(d); 1160 return NULL; 1161 } 1162 d->dtd = *(uint8_t *) p; 1163 if (rec) 1164 sdp_pattern_add_uuid(rec, &d->val.uuid); 1165 return d; 1166 } 1167 1168 /* 1169 * Extract strings from the PDU (could be service description and similar info) 1170 */ 1171 static sdp_data_t *extract_str(const void *p, int bufsize, int *len) 1172 { 1173 char *s; 1174 int n; 1175 sdp_data_t *d; 1176 1177 if (bufsize < (int) sizeof(uint8_t)) { 1178 SDPERR("Unexpected end of packet"); 1179 return NULL; 1180 } 1181 1182 d = malloc(sizeof(sdp_data_t)); 1183 1184 memset(d, 0, sizeof(sdp_data_t)); 1185 d->dtd = *(uint8_t *) p; 1186 p += sizeof(uint8_t); 1187 *len += sizeof(uint8_t); 1188 bufsize -= sizeof(uint8_t); 1189 1190 switch (d->dtd) { 1191 case SDP_TEXT_STR8: 1192 case SDP_URL_STR8: 1193 if (bufsize < (int) sizeof(uint8_t)) { 1194 SDPERR("Unexpected end of packet"); 1195 free(d); 1196 return NULL; 1197 } 1198 n = *(uint8_t *) p; 1199 p += sizeof(uint8_t); 1200 *len += sizeof(uint8_t); 1201 bufsize -= sizeof(uint8_t); 1202 break; 1203 case SDP_TEXT_STR16: 1204 case SDP_URL_STR16: 1205 if (bufsize < (int) sizeof(uint16_t)) { 1206 SDPERR("Unexpected end of packet"); 1207 free(d); 1208 return NULL; 1209 } 1210 n = ntohs(bt_get_unaligned((uint16_t *) p)); 1211 p += sizeof(uint16_t); 1212 *len += sizeof(uint16_t) + n; 1213 bufsize -= sizeof(uint16_t); 1214 break; 1215 default: 1216 SDPERR("Sizeof text string > UINT16_MAX\n"); 1217 free(d); 1218 return 0; 1219 } 1220 1221 if (bufsize < n) { 1222 SDPERR("String too long to fit in packet"); 1223 free(d); 1224 return NULL; 1225 } 1226 1227 s = malloc(n + 1); 1228 if (!s) { 1229 SDPERR("Not enough memory for incoming string"); 1230 free(d); 1231 return NULL; 1232 } 1233 memset(s, 0, n + 1); 1234 memcpy(s, p, n); 1235 1236 *len += n; 1237 1238 SDPDBG("Len : %d\n", n); 1239 SDPDBG("Str : %s\n", s); 1240 1241 d->val.str = s; 1242 d->unitSize = n + sizeof(uint8_t); 1243 return d; 1244 } 1245 1246 /* 1247 * Extract the sequence type and its length, and return offset into buf 1248 * or 0 on failure. 1249 */ 1250 int sdp_extract_seqtype(const uint8_t *buf, int bufsize, uint8_t *dtdp, int *size) 1251 { 1252 uint8_t dtd; 1253 int scanned = sizeof(uint8_t); 1254 1255 if (bufsize < (int) sizeof(uint8_t)) { 1256 SDPERR("Unexpected end of packet"); 1257 return 0; 1258 } 1259 1260 dtd = *(uint8_t *) buf; 1261 buf += sizeof(uint8_t); 1262 bufsize -= sizeof(uint8_t); 1263 *dtdp = dtd; 1264 switch (dtd) { 1265 case SDP_SEQ8: 1266 case SDP_ALT8: 1267 if (bufsize < (int) sizeof(uint8_t)) { 1268 SDPERR("Unexpected end of packet"); 1269 return 0; 1270 } 1271 *size = *(uint8_t *) buf; 1272 scanned += sizeof(uint8_t); 1273 break; 1274 case SDP_SEQ16: 1275 case SDP_ALT16: 1276 if (bufsize < (int) sizeof(uint16_t)) { 1277 SDPERR("Unexpected end of packet"); 1278 return 0; 1279 } 1280 *size = ntohs(bt_get_unaligned((uint16_t *) buf)); 1281 scanned += sizeof(uint16_t); 1282 break; 1283 case SDP_SEQ32: 1284 case SDP_ALT32: 1285 if (bufsize < (int) sizeof(uint32_t)) { 1286 SDPERR("Unexpected end of packet"); 1287 return 0; 1288 } 1289 *size = ntohl(bt_get_unaligned((uint32_t *) buf)); 1290 scanned += sizeof(uint32_t); 1291 break; 1292 default: 1293 SDPERR("Unknown sequence type, aborting\n"); 1294 return 0; 1295 } 1296 return scanned; 1297 } 1298 1299 static sdp_data_t *extract_seq(const void *p, int bufsize, int *len, 1300 sdp_record_t *rec) 1301 { 1302 int seqlen, n = 0; 1303 sdp_data_t *curr, *prev; 1304 sdp_data_t *d = malloc(sizeof(sdp_data_t)); 1305 1306 SDPDBG("Extracting SEQ"); 1307 memset(d, 0, sizeof(sdp_data_t)); 1308 *len = sdp_extract_seqtype(p, bufsize, &d->dtd, &seqlen); 1309 SDPDBG("Sequence Type : 0x%x length : 0x%x\n", d->dtd, seqlen); 1310 1311 if (*len == 0) 1312 return d; 1313 1314 if (*len > bufsize) { 1315 SDPERR("Packet not big enough to hold sequence."); 1316 free(d); 1317 return NULL; 1318 } 1319 1320 p += *len; 1321 bufsize -= *len; 1322 prev = NULL; 1323 while (n < seqlen) { 1324 int attrlen = 0; 1325 curr = sdp_extract_attr(p, bufsize, &attrlen, rec); 1326 if (curr == NULL) 1327 break; 1328 1329 if (prev) 1330 prev->next = curr; 1331 else 1332 d->val.dataseq = curr; 1333 prev = curr; 1334 p += attrlen; 1335 n += attrlen; 1336 bufsize -= attrlen; 1337 1338 SDPDBG("Extracted: %d SequenceLength: %d", n, seqlen); 1339 } 1340 1341 *len += n; 1342 return d; 1343 } 1344 1345 sdp_data_t *sdp_extract_attr(const uint8_t *p, int bufsize, int *size, 1346 sdp_record_t *rec) 1347 { 1348 sdp_data_t *elem; 1349 int n = 0; 1350 uint8_t dtd; 1351 1352 if (bufsize < (int) sizeof(uint8_t)) { 1353 SDPERR("Unexpected end of packet"); 1354 return NULL; 1355 } 1356 1357 dtd = *(const uint8_t *)p; 1358 1359 SDPDBG("extract_attr: dtd=0x%x", dtd); 1360 switch (dtd) { 1361 case SDP_DATA_NIL: 1362 case SDP_BOOL: 1363 case SDP_UINT8: 1364 case SDP_UINT16: 1365 case SDP_UINT32: 1366 case SDP_UINT64: 1367 case SDP_UINT128: 1368 case SDP_INT8: 1369 case SDP_INT16: 1370 case SDP_INT32: 1371 case SDP_INT64: 1372 case SDP_INT128: 1373 elem = extract_int(p, bufsize, &n); 1374 break; 1375 case SDP_UUID16: 1376 case SDP_UUID32: 1377 case SDP_UUID128: 1378 elem = extract_uuid(p, bufsize, &n, rec); 1379 break; 1380 case SDP_TEXT_STR8: 1381 case SDP_TEXT_STR16: 1382 case SDP_TEXT_STR32: 1383 case SDP_URL_STR8: 1384 case SDP_URL_STR16: 1385 case SDP_URL_STR32: 1386 elem = extract_str(p, bufsize, &n); 1387 break; 1388 case SDP_SEQ8: 1389 case SDP_SEQ16: 1390 case SDP_SEQ32: 1391 case SDP_ALT8: 1392 case SDP_ALT16: 1393 case SDP_ALT32: 1394 elem = extract_seq(p, bufsize, &n, rec); 1395 break; 1396 default: 1397 SDPERR("Unknown data descriptor : 0x%x terminating\n", dtd); 1398 return NULL; 1399 } 1400 *size += n; 1401 return elem; 1402 } 1403 1404 #ifdef SDP_DEBUG 1405 static void attr_print_func(void *value, void *userData) 1406 { 1407 sdp_data_t *d = (sdp_data_t *)value; 1408 1409 SDPDBG("=====================================\n"); 1410 SDPDBG("ATTRIBUTE IDENTIFIER : 0x%x\n", d->attrId); 1411 SDPDBG("ATTRIBUTE VALUE PTR : 0x%x\n", (uint32_t)value); 1412 if (d) 1413 sdp_data_print(d); 1414 else 1415 SDPDBG("NULL value\n"); 1416 SDPDBG("=====================================\n"); 1417 } 1418 1419 void sdp_print_service_attr(sdp_list_t *svcAttrList) 1420 { 1421 SDPDBG("Printing service attr list %p\n", svcAttrList); 1422 sdp_list_foreach(svcAttrList, attr_print_func, NULL); 1423 SDPDBG("Printed service attr list %p\n", svcAttrList); 1424 } 1425 #endif 1426 1427 sdp_record_t *sdp_extract_pdu(const uint8_t *buf, int bufsize, int *scanned) 1428 { 1429 int extracted = 0, seqlen = 0; 1430 uint8_t dtd; 1431 uint16_t attr; 1432 sdp_record_t *rec = sdp_record_alloc(); 1433 const uint8_t *p = buf; 1434 1435 *scanned = sdp_extract_seqtype(buf, bufsize, &dtd, &seqlen); 1436 p += *scanned; 1437 bufsize -= *scanned; 1438 rec->attrlist = NULL; 1439 1440 while (extracted < seqlen && bufsize > 0) { 1441 int n = sizeof(uint8_t), attrlen = 0; 1442 sdp_data_t *data = NULL; 1443 1444 SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d", 1445 seqlen, extracted); 1446 1447 if (bufsize < n + (int) sizeof(uint16_t)) { 1448 SDPERR("Unexpected end of packet"); 1449 break; 1450 } 1451 1452 dtd = *(uint8_t *) p; 1453 attr = ntohs(bt_get_unaligned((uint16_t *) (p + n))); 1454 n += sizeof(uint16_t); 1455 1456 SDPDBG("DTD of attrId : %d Attr id : 0x%x \n", dtd, attr); 1457 1458 data = sdp_extract_attr(p + n, bufsize - n, &attrlen, rec); 1459 1460 SDPDBG("Attr id : 0x%x attrValueLength : %d\n", attr, attrlen); 1461 1462 n += attrlen; 1463 if (data == NULL) { 1464 SDPDBG("Terminating extraction of attributes"); 1465 break; 1466 } 1467 1468 if (attr == SDP_ATTR_RECORD_HANDLE) 1469 rec->handle = data->val.uint32; 1470 1471 if (attr == SDP_ATTR_SVCLASS_ID_LIST) 1472 extract_svclass_uuid(data, &rec->svclass); 1473 1474 extracted += n; 1475 p += n; 1476 bufsize -= n; 1477 sdp_attr_replace(rec, attr, data); 1478 1479 SDPDBG("Extract PDU, seqLength: %d localExtractedLength: %d", 1480 seqlen, extracted); 1481 } 1482 #ifdef SDP_DEBUG 1483 SDPDBG("Successful extracting of Svc Rec attributes\n"); 1484 sdp_print_service_attr(rec->attrlist); 1485 #endif 1486 *scanned += seqlen; 1487 return rec; 1488 } 1489 1490 static void sdp_copy_pattern(void *value, void *udata) 1491 { 1492 uuid_t *uuid = value; 1493 sdp_record_t *rec = udata; 1494 1495 sdp_pattern_add_uuid(rec, uuid); 1496 } 1497 1498 static void *sdp_data_value(sdp_data_t *data, uint32_t *len) 1499 { 1500 void *val = NULL; 1501 1502 switch (data->dtd) { 1503 case SDP_DATA_NIL: 1504 break; 1505 case SDP_UINT8: 1506 val = &data->val.uint8; 1507 break; 1508 case SDP_INT8: 1509 case SDP_BOOL: 1510 val = &data->val.int8; 1511 break; 1512 case SDP_UINT16: 1513 val = &data->val.uint16; 1514 break; 1515 case SDP_INT16: 1516 val = &data->val.int16; 1517 break; 1518 case SDP_UINT32: 1519 val = &data->val.uint32; 1520 break; 1521 case SDP_INT32: 1522 val = &data->val.int32; 1523 break; 1524 case SDP_INT64: 1525 val = &data->val.int64; 1526 break; 1527 case SDP_UINT64: 1528 val = &data->val.uint64; 1529 break; 1530 case SDP_UINT128: 1531 val = &data->val.uint128; 1532 break; 1533 case SDP_INT128: 1534 val = &data->val.int128; 1535 break; 1536 case SDP_UUID16: 1537 val = &data->val.uuid.value.uuid16; 1538 break; 1539 case SDP_UUID32: 1540 val = &data->val.uuid.value.uuid32; 1541 break; 1542 case SDP_UUID128: 1543 val = &data->val.uuid.value.uuid128; 1544 break; 1545 case SDP_URL_STR8: 1546 case SDP_URL_STR16: 1547 case SDP_TEXT_STR8: 1548 case SDP_TEXT_STR16: 1549 case SDP_URL_STR32: 1550 case SDP_TEXT_STR32: 1551 val = data->val.str; 1552 if (len) 1553 *len = data->unitSize - 1; 1554 break; 1555 case SDP_ALT8: 1556 case SDP_ALT16: 1557 case SDP_ALT32: 1558 case SDP_SEQ8: 1559 case SDP_SEQ16: 1560 case SDP_SEQ32: 1561 val = sdp_copy_seq(data->val.dataseq); 1562 break; 1563 } 1564 1565 return val; 1566 } 1567 1568 static sdp_data_t *sdp_copy_seq(sdp_data_t *data) 1569 { 1570 sdp_data_t *tmp, *seq = NULL, *cur = NULL; 1571 1572 for (tmp = data; tmp; tmp = tmp->next) { 1573 sdp_data_t *datatmp; 1574 void *value; 1575 1576 value = sdp_data_value(tmp, NULL); 1577 datatmp = sdp_data_alloc_with_length(tmp->dtd, value, 1578 tmp->unitSize); 1579 1580 if (cur) 1581 cur->next = datatmp; 1582 else 1583 seq = datatmp; 1584 1585 cur = datatmp; 1586 } 1587 1588 return seq; 1589 } 1590 1591 static void sdp_copy_attrlist(void *value, void *udata) 1592 { 1593 sdp_data_t *data = value; 1594 sdp_record_t *rec = udata; 1595 void *val; 1596 uint32_t len = 0; 1597 1598 val = sdp_data_value(data, &len); 1599 1600 if (!len) 1601 sdp_attr_add_new(rec, data->attrId, data->dtd, val); 1602 else 1603 sdp_attr_add_new_with_length(rec, data->attrId, 1604 data->dtd, val, len); 1605 } 1606 1607 sdp_record_t *sdp_copy_record(sdp_record_t *rec) 1608 { 1609 sdp_record_t *cpy; 1610 1611 cpy = sdp_record_alloc(); 1612 1613 cpy->handle = rec->handle; 1614 1615 sdp_list_foreach(rec->pattern, sdp_copy_pattern, cpy); 1616 sdp_list_foreach(rec->attrlist, sdp_copy_attrlist, cpy); 1617 1618 cpy->svclass = rec->svclass; 1619 1620 return cpy; 1621 } 1622 1623 #ifdef SDP_DEBUG 1624 static void print_dataseq(sdp_data_t *p) 1625 { 1626 sdp_data_t *d; 1627 1628 for (d = p; d; d = d->next) 1629 sdp_data_print(d); 1630 } 1631 #endif 1632 1633 void sdp_record_print(const sdp_record_t *rec) 1634 { 1635 sdp_data_t *d = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY); 1636 if (d) 1637 printf("Service Name: %.*s\n", d->unitSize, d->val.str); 1638 d = sdp_data_get(rec, SDP_ATTR_SVCDESC_PRIMARY); 1639 if (d) 1640 printf("Service Description: %.*s\n", d->unitSize, d->val.str); 1641 d = sdp_data_get(rec, SDP_ATTR_PROVNAME_PRIMARY); 1642 if (d) 1643 printf("Service Provider: %.*s\n", d->unitSize, d->val.str); 1644 } 1645 1646 #ifdef SDP_DEBUG 1647 void sdp_data_print(sdp_data_t *d) 1648 { 1649 switch (d->dtd) { 1650 case SDP_DATA_NIL: 1651 SDPDBG("NIL\n"); 1652 break; 1653 case SDP_BOOL: 1654 case SDP_UINT8: 1655 case SDP_UINT16: 1656 case SDP_UINT32: 1657 case SDP_UINT64: 1658 case SDP_UINT128: 1659 case SDP_INT8: 1660 case SDP_INT16: 1661 case SDP_INT32: 1662 case SDP_INT64: 1663 case SDP_INT128: 1664 SDPDBG("Integer : 0x%x\n", d->val.uint32); 1665 break; 1666 case SDP_UUID16: 1667 case SDP_UUID32: 1668 case SDP_UUID128: 1669 SDPDBG("UUID\n"); 1670 sdp_uuid_print(&d->val.uuid); 1671 break; 1672 case SDP_TEXT_STR8: 1673 case SDP_TEXT_STR16: 1674 case SDP_TEXT_STR32: 1675 SDPDBG("Text : %s\n", d->val.str); 1676 break; 1677 case SDP_URL_STR8: 1678 case SDP_URL_STR16: 1679 case SDP_URL_STR32: 1680 SDPDBG("URL : %s\n", d->val.str); 1681 break; 1682 case SDP_SEQ8: 1683 case SDP_SEQ16: 1684 case SDP_SEQ32: 1685 print_dataseq(d->val.dataseq); 1686 break; 1687 case SDP_ALT8: 1688 case SDP_ALT16: 1689 case SDP_ALT32: 1690 SDPDBG("Data Sequence Alternates\n"); 1691 print_dataseq(d->val.dataseq); 1692 break; 1693 } 1694 } 1695 #endif 1696 1697 sdp_data_t *sdp_data_get(const sdp_record_t *rec, uint16_t attrId) 1698 { 1699 if (rec->attrlist) { 1700 sdp_data_t sdpTemplate; 1701 sdp_list_t *p; 1702 1703 sdpTemplate.attrId = attrId; 1704 p = sdp_list_find(rec->attrlist, &sdpTemplate, sdp_attrid_comp_func); 1705 if (p) 1706 return (sdp_data_t *)p->data; 1707 } 1708 return NULL; 1709 } 1710 1711 static int sdp_send_req(sdp_session_t *session, uint8_t *buf, uint32_t size) 1712 { 1713 uint32_t sent = 0; 1714 1715 while (sent < size) { 1716 int n = send(session->sock, buf + sent, size - sent, 0); 1717 if (n < 0) 1718 return -1; 1719 sent += n; 1720 } 1721 return 0; 1722 } 1723 1724 static int sdp_read_rsp(sdp_session_t *session, uint8_t *buf, uint32_t size) 1725 { 1726 fd_set readFds; 1727 struct timeval timeout = { SDP_RESPONSE_TIMEOUT, 0 }; 1728 1729 FD_ZERO(&readFds); 1730 FD_SET(session->sock, &readFds); 1731 SDPDBG("Waiting for response\n"); 1732 if (select(session->sock + 1, &readFds, NULL, NULL, &timeout) == 0) { 1733 SDPERR("Client timed out\n"); 1734 errno = ETIMEDOUT; 1735 return -1; 1736 } 1737 return recv(session->sock, buf, size, 0); 1738 } 1739 1740 /* 1741 * generic send request, wait for response method. 1742 */ 1743 int sdp_send_req_w4_rsp(sdp_session_t *session, uint8_t *reqbuf, 1744 uint8_t *rspbuf, uint32_t reqsize, uint32_t *rspsize) 1745 { 1746 int n; 1747 sdp_pdu_hdr_t *reqhdr = (sdp_pdu_hdr_t *)reqbuf; 1748 sdp_pdu_hdr_t *rsphdr = (sdp_pdu_hdr_t *)rspbuf; 1749 1750 SDPDBG(""); 1751 if (0 > sdp_send_req(session, reqbuf, reqsize)) { 1752 SDPERR("Error sending data:%s", strerror(errno)); 1753 return -1; 1754 } 1755 n = sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE); 1756 if (0 > n) 1757 return -1; 1758 SDPDBG("Read : %d\n", n); 1759 if (n == 0 || reqhdr->tid != rsphdr->tid) { 1760 errno = EPROTO; 1761 return -1; 1762 } 1763 *rspsize = n; 1764 return 0; 1765 } 1766 1767 /* 1768 * singly-linked lists (after openobex implementation) 1769 */ 1770 sdp_list_t *sdp_list_append(sdp_list_t *p, void *d) 1771 { 1772 sdp_list_t *q, *n = malloc(sizeof(sdp_list_t)); 1773 1774 if (!n) 1775 return 0; 1776 1777 n->data = d; 1778 n->next = 0; 1779 1780 if (!p) 1781 return n; 1782 1783 for (q = p; q->next; q = q->next); 1784 q->next = n; 1785 1786 return p; 1787 } 1788 1789 sdp_list_t *sdp_list_remove(sdp_list_t *list, void *d) 1790 { 1791 sdp_list_t *p, *q; 1792 1793 for (q = 0, p = list; p; q = p, p = p->next) 1794 if (p->data == d) { 1795 if (q) 1796 q->next = p->next; 1797 else 1798 list = p->next; 1799 free(p); 1800 break; 1801 } 1802 1803 return list; 1804 } 1805 1806 sdp_list_t *sdp_list_insert_sorted(sdp_list_t *list, void *d, 1807 sdp_comp_func_t f) 1808 { 1809 sdp_list_t *q, *p, *n; 1810 1811 n = malloc(sizeof(sdp_list_t)); 1812 if (!n) 1813 return 0; 1814 n->data = d; 1815 for (q = 0, p = list; p; q = p, p = p->next) 1816 if (f(p->data, d) >= 0) 1817 break; 1818 // insert between q and p; if !q insert at head 1819 if (q) 1820 q->next = n; 1821 else 1822 list = n; 1823 n->next = p; 1824 return list; 1825 } 1826 1827 /* 1828 * Every element of the list points to things which need 1829 * to be free()'d. This method frees the list's contents 1830 */ 1831 void sdp_list_free(sdp_list_t *list, sdp_free_func_t f) 1832 { 1833 sdp_list_t *next; 1834 while (list) { 1835 next = list->next; 1836 if (f) 1837 f(list->data); 1838 free(list); 1839 list = next; 1840 } 1841 } 1842 1843 static inline int __find_port(sdp_data_t *seq, int proto) 1844 { 1845 if (!seq || !seq->next) 1846 return 0; 1847 1848 if (SDP_IS_UUID(seq->dtd) && sdp_uuid_to_proto(&seq->val.uuid) == proto) { 1849 seq = seq->next; 1850 switch (seq->dtd) { 1851 case SDP_UINT8: 1852 return seq->val.uint8; 1853 case SDP_UINT16: 1854 return seq->val.uint16; 1855 } 1856 } 1857 return 0; 1858 } 1859 1860 int sdp_get_proto_port(const sdp_list_t *list, int proto) 1861 { 1862 if (proto != L2CAP_UUID && proto != RFCOMM_UUID) { 1863 errno = EINVAL; 1864 return -1; 1865 } 1866 1867 for (; list; list = list->next) { 1868 sdp_list_t *p; 1869 for (p = list->data; p; p = p->next) { 1870 sdp_data_t *seq = (sdp_data_t *) p->data; 1871 int port = __find_port(seq, proto); 1872 if (port) 1873 return port; 1874 } 1875 } 1876 return 0; 1877 } 1878 1879 sdp_data_t *sdp_get_proto_desc(sdp_list_t *list, int proto) 1880 { 1881 for (; list; list = list->next) { 1882 sdp_list_t *p; 1883 for (p = list->data; p; p = p->next) { 1884 sdp_data_t *seq = (sdp_data_t *) p->data; 1885 if (SDP_IS_UUID(seq->dtd) && 1886 sdp_uuid_to_proto(&seq->val.uuid) == proto) 1887 return seq->next; 1888 } 1889 } 1890 return NULL; 1891 } 1892 1893 int sdp_get_access_protos(const sdp_record_t *rec, sdp_list_t **pap) 1894 { 1895 sdp_data_t *pdlist, *curr; 1896 sdp_list_t *ap = 0; 1897 1898 pdlist = sdp_data_get(rec, SDP_ATTR_PROTO_DESC_LIST); 1899 if (pdlist == NULL) { 1900 errno = ENODATA; 1901 return -1; 1902 } 1903 SDPDBG("AP type : 0%x\n", pdlist->dtd); 1904 1905 for (; pdlist; pdlist = pdlist->next) { 1906 sdp_list_t *pds = 0; 1907 for (curr = pdlist->val.dataseq; curr; curr = curr->next) 1908 pds = sdp_list_append(pds, curr->val.dataseq); 1909 ap = sdp_list_append(ap, pds); 1910 } 1911 *pap = ap; 1912 return 0; 1913 } 1914 1915 int sdp_get_add_access_protos(const sdp_record_t *rec, sdp_list_t **pap) 1916 { 1917 sdp_data_t *pdlist, *curr; 1918 sdp_list_t *ap = 0; 1919 1920 pdlist = sdp_data_get(rec, SDP_ATTR_ADD_PROTO_DESC_LIST); 1921 if (pdlist == NULL) { 1922 errno = ENODATA; 1923 return -1; 1924 } 1925 SDPDBG("AP type : 0%x\n", pdlist->dtd); 1926 1927 pdlist = pdlist->val.dataseq; 1928 1929 for (; pdlist; pdlist = pdlist->next) { 1930 sdp_list_t *pds = 0; 1931 for (curr = pdlist->val.dataseq; curr; curr = curr->next) 1932 pds = sdp_list_append(pds, curr->val.dataseq); 1933 ap = sdp_list_append(ap, pds); 1934 } 1935 *pap = ap; 1936 return 0; 1937 } 1938 1939 int sdp_get_uuidseq_attr(const sdp_record_t *rec, uint16_t attr, 1940 sdp_list_t **seqp) 1941 { 1942 sdp_data_t *sdpdata = sdp_data_get(rec, attr); 1943 1944 *seqp = NULL; 1945 if (sdpdata && sdpdata->dtd >= SDP_SEQ8 && sdpdata->dtd <= SDP_SEQ32) { 1946 sdp_data_t *d; 1947 for (d = sdpdata->val.dataseq; d; d = d->next) { 1948 uuid_t *u; 1949 if (d->dtd < SDP_UUID16 || d->dtd > SDP_UUID128) 1950 goto fail; 1951 1952 u = malloc(sizeof(uuid_t)); 1953 memset(u, 0, sizeof(uuid_t)); 1954 *u = d->val.uuid; 1955 *seqp = sdp_list_append(*seqp, u); 1956 } 1957 return 0; 1958 } 1959 fail: 1960 sdp_list_free(*seqp, free); 1961 errno = EINVAL; 1962 return -1; 1963 } 1964 1965 int sdp_set_uuidseq_attr(sdp_record_t *rec, uint16_t aid, sdp_list_t *seq) 1966 { 1967 int status = 0, i, len; 1968 void **dtds, **values; 1969 uint8_t uuid16 = SDP_UUID16; 1970 uint8_t uuid32 = SDP_UUID32; 1971 uint8_t uuid128 = SDP_UUID128; 1972 sdp_list_t *p; 1973 1974 len = sdp_list_len(seq); 1975 if (!seq || len == 0) 1976 return -1; 1977 dtds = (void **)malloc(len * sizeof(void *)); 1978 values = (void **)malloc(len * sizeof(void *)); 1979 for (p = seq, i = 0; i < len; i++, p = p->next) { 1980 uuid_t *uuid = (uuid_t *)p->data; 1981 if (uuid) 1982 switch (uuid->type) { 1983 case SDP_UUID16: 1984 dtds[i] = &uuid16; 1985 values[i] = &uuid->value.uuid16; 1986 break; 1987 case SDP_UUID32: 1988 dtds[i] = &uuid32; 1989 values[i] = &uuid->value.uuid32; 1990 break; 1991 case SDP_UUID128: 1992 dtds[i] = &uuid128; 1993 values[i] = &uuid->value.uuid128; 1994 break; 1995 default: 1996 status = -1; 1997 break; 1998 } 1999 else { 2000 status = -1; 2001 break; 2002 } 2003 } 2004 if (status == 0) { 2005 sdp_data_t *data = sdp_seq_alloc(dtds, values, len); 2006 sdp_attr_replace(rec, aid, data); 2007 sdp_pattern_add_uuidseq(rec, seq); 2008 } 2009 free(dtds); 2010 free(values); 2011 return status; 2012 } 2013 2014 int sdp_get_lang_attr(const sdp_record_t *rec, sdp_list_t **langSeq) 2015 { 2016 sdp_lang_attr_t *lang; 2017 sdp_data_t *sdpdata, *curr_data; 2018 2019 *langSeq = NULL; 2020 sdpdata = sdp_data_get(rec, SDP_ATTR_LANG_BASE_ATTR_ID_LIST); 2021 if (sdpdata == NULL) { 2022 errno = ENODATA; 2023 return -1; 2024 } 2025 curr_data = sdpdata->val.dataseq; 2026 while (curr_data) { 2027 sdp_data_t *pCode = curr_data; 2028 sdp_data_t *pEncoding = pCode->next; 2029 sdp_data_t *pOffset = pEncoding->next; 2030 if (pCode && pEncoding && pOffset) { 2031 lang = malloc(sizeof(sdp_lang_attr_t)); 2032 lang->code_ISO639 = pCode->val.uint16; 2033 lang->encoding = pEncoding->val.uint16; 2034 lang->base_offset = pOffset->val.uint16; 2035 SDPDBG("code_ISO639 : 0x%02x\n", lang->code_ISO639); 2036 SDPDBG("encoding : 0x%02x\n", lang->encoding); 2037 SDPDBG("base_offfset : 0x%02x\n", lang->base_offset); 2038 *langSeq = sdp_list_append(*langSeq, lang); 2039 } 2040 curr_data = pOffset->next; 2041 } 2042 return 0; 2043 } 2044 2045 int sdp_get_profile_descs(const sdp_record_t *rec, sdp_list_t **profDescSeq) 2046 { 2047 sdp_profile_desc_t *profDesc; 2048 sdp_data_t *sdpdata, *seq; 2049 2050 *profDescSeq = NULL; 2051 sdpdata = sdp_data_get(rec, SDP_ATTR_PFILE_DESC_LIST); 2052 if (!sdpdata || !sdpdata->val.dataseq) { 2053 errno = ENODATA; 2054 return -1; 2055 } 2056 for (seq = sdpdata->val.dataseq; seq && seq->val.dataseq; seq = seq->next) { 2057 uuid_t *uuid = NULL; 2058 uint16_t version = 0x100; 2059 2060 if (SDP_IS_UUID(seq->dtd)) { 2061 uuid = &seq->val.uuid; 2062 } else { 2063 sdp_data_t *puuid = seq->val.dataseq; 2064 sdp_data_t *pVnum = seq->val.dataseq->next; 2065 if (puuid && pVnum) { 2066 uuid = &puuid->val.uuid; 2067 version = pVnum->val.uint16; 2068 } 2069 } 2070 2071 if (uuid != NULL) { 2072 profDesc = malloc(sizeof(sdp_profile_desc_t)); 2073 profDesc->uuid = *uuid; 2074 profDesc->version = version; 2075 #ifdef SDP_DEBUG 2076 sdp_uuid_print(&profDesc->uuid); 2077 SDPDBG("Vnum : 0x%04x\n", profDesc->version); 2078 #endif 2079 *profDescSeq = sdp_list_append(*profDescSeq, profDesc); 2080 } 2081 } 2082 return 0; 2083 } 2084 2085 int sdp_get_server_ver(const sdp_record_t *rec, sdp_list_t **u16) 2086 { 2087 sdp_data_t *d, *curr; 2088 2089 *u16 = NULL; 2090 d = sdp_data_get(rec, SDP_ATTR_VERSION_NUM_LIST); 2091 if (d == NULL) { 2092 errno = ENODATA; 2093 return -1; 2094 } 2095 for (curr = d->val.dataseq; curr; curr = curr->next) 2096 *u16 = sdp_list_append(*u16, &curr->val.uint16); 2097 return 0; 2098 } 2099 2100 /* flexible extraction of basic attributes - Jean II */ 2101 /* How do we expect caller to extract predefined data sequences? */ 2102 int sdp_get_int_attr(const sdp_record_t *rec, uint16_t attrid, int *value) 2103 { 2104 sdp_data_t *sdpdata = sdp_data_get(rec, attrid); 2105 2106 if (sdpdata) 2107 /* Verify that it is what the caller expects */ 2108 if (sdpdata->dtd == SDP_BOOL || sdpdata->dtd == SDP_UINT8 || 2109 sdpdata->dtd == SDP_UINT16 || sdpdata->dtd == SDP_UINT32 || 2110 sdpdata->dtd == SDP_INT8 || sdpdata->dtd == SDP_INT16 || 2111 sdpdata->dtd == SDP_INT32) { 2112 *value = sdpdata->val.uint32; 2113 return 0; 2114 } 2115 errno = EINVAL; 2116 return -1; 2117 } 2118 2119 int sdp_get_string_attr(const sdp_record_t *rec, uint16_t attrid, char *value, 2120 int valuelen) 2121 { 2122 sdp_data_t *sdpdata = sdp_data_get(rec, attrid); 2123 if (sdpdata) 2124 /* Verify that it is what the caller expects */ 2125 if (sdpdata->dtd == SDP_TEXT_STR8 || 2126 sdpdata->dtd == SDP_TEXT_STR16 || 2127 sdpdata->dtd == SDP_TEXT_STR32) 2128 if ((int) strlen(sdpdata->val.str) < valuelen) { 2129 strcpy(value, sdpdata->val.str); 2130 return 0; 2131 } 2132 errno = EINVAL; 2133 return -1; 2134 } 2135 2136 #define get_basic_attr(attrID, pAttrValue, fieldName) \ 2137 sdp_data_t *data = sdp_data_get(rec, attrID); \ 2138 if (data) { \ 2139 *pAttrValue = data->val.fieldName; \ 2140 return 0; \ 2141 } \ 2142 errno = EINVAL; \ 2143 return -1; 2144 2145 int sdp_get_service_id(const sdp_record_t *rec, uuid_t *uuid) 2146 { 2147 get_basic_attr(SDP_ATTR_SERVICE_ID, uuid, uuid); 2148 } 2149 2150 int sdp_get_group_id(const sdp_record_t *rec, uuid_t *uuid) 2151 { 2152 get_basic_attr(SDP_ATTR_GROUP_ID, uuid, uuid); 2153 } 2154 2155 int sdp_get_record_state(const sdp_record_t *rec, uint32_t *svcRecState) 2156 { 2157 get_basic_attr(SDP_ATTR_RECORD_STATE, svcRecState, uint32); 2158 } 2159 2160 int sdp_get_service_avail(const sdp_record_t *rec, uint8_t *svcAvail) 2161 { 2162 get_basic_attr(SDP_ATTR_SERVICE_AVAILABILITY, svcAvail, uint8); 2163 } 2164 2165 int sdp_get_service_ttl(const sdp_record_t *rec, uint32_t *svcTTLInfo) 2166 { 2167 get_basic_attr(SDP_ATTR_SVCINFO_TTL, svcTTLInfo, uint32); 2168 } 2169 2170 int sdp_get_database_state(const sdp_record_t *rec, uint32_t *svcDBState) 2171 { 2172 get_basic_attr(SDP_ATTR_SVCDB_STATE, svcDBState, uint32); 2173 } 2174 2175 /* 2176 * NOTE that none of the setXXX() functions below will 2177 * actually update the SDP server, unless the 2178 * {register, update}sdp_record_t() function is invoked. 2179 */ 2180 2181 int sdp_attr_add_new(sdp_record_t *rec, uint16_t attr, uint8_t dtd, 2182 const void *value) 2183 { 2184 sdp_data_t *d = sdp_data_alloc(dtd, value); 2185 if (d) { 2186 sdp_attr_replace(rec, attr, d); 2187 return 0; 2188 } 2189 return -1; 2190 } 2191 2192 static int sdp_attr_add_new_with_length(sdp_record_t *rec, 2193 uint16_t attr, uint8_t dtd, const void *value, uint32_t len) 2194 { 2195 sdp_data_t *d; 2196 2197 d = sdp_data_alloc_with_length(dtd, value, len); 2198 if (!d) 2199 return -1; 2200 2201 sdp_attr_replace(rec, attr, d); 2202 2203 return 0; 2204 } 2205 2206 /* 2207 * Set the information attributes of the service 2208 * pointed to by rec. The attributes are 2209 * service name, description and provider name 2210 */ 2211 void sdp_set_info_attr(sdp_record_t *rec, const char *name, const char *prov, 2212 const char *desc) 2213 { 2214 if (name) 2215 sdp_attr_add_new(rec, SDP_ATTR_SVCNAME_PRIMARY, SDP_TEXT_STR8, 2216 (void *)name); 2217 if (prov) 2218 sdp_attr_add_new(rec, SDP_ATTR_PROVNAME_PRIMARY, SDP_TEXT_STR8, 2219 (void *)prov); 2220 if (desc) 2221 sdp_attr_add_new(rec, SDP_ATTR_SVCDESC_PRIMARY, SDP_TEXT_STR8, 2222 (void *)desc); 2223 } 2224 2225 static sdp_data_t *access_proto_to_dataseq(sdp_record_t *rec, sdp_list_t *proto) 2226 { 2227 sdp_data_t *seq = NULL; 2228 void *dtds[10], *values[10]; 2229 void **seqDTDs, **seqs; 2230 int i, seqlen; 2231 sdp_list_t *p; 2232 2233 seqlen = sdp_list_len(proto); 2234 seqDTDs = (void **)malloc(seqlen * sizeof(void *)); 2235 seqs = (void **)malloc(seqlen * sizeof(void *)); 2236 for (i = 0, p = proto; p; p = p->next, i++) { 2237 sdp_list_t *elt = (sdp_list_t *)p->data; 2238 sdp_data_t *s; 2239 uuid_t *uuid = NULL; 2240 unsigned int pslen = 0; 2241 for (; elt && pslen < ARRAY_SIZE(dtds); elt = elt->next, pslen++) { 2242 sdp_data_t *d = (sdp_data_t *)elt->data; 2243 dtds[pslen] = &d->dtd; 2244 switch (d->dtd) { 2245 case SDP_UUID16: 2246 uuid = (uuid_t *) d; 2247 values[pslen] = &uuid->value.uuid16; 2248 break; 2249 case SDP_UUID32: 2250 uuid = (uuid_t *) d; 2251 values[pslen] = &uuid->value.uuid32; 2252 break; 2253 case SDP_UUID128: 2254 uuid = (uuid_t *) d; 2255 values[pslen] = &uuid->value.uuid128; 2256 break; 2257 case SDP_UINT8: 2258 values[pslen] = &d->val.uint8; 2259 break; 2260 case SDP_UINT16: 2261 values[pslen] = &d->val.uint16; 2262 break; 2263 case SDP_SEQ8: 2264 case SDP_SEQ16: 2265 case SDP_SEQ32: 2266 values[pslen] = d; 2267 break; 2268 /* FIXME: more */ 2269 } 2270 } 2271 s = sdp_seq_alloc(dtds, values, pslen); 2272 if (s) { 2273 seqDTDs[i] = &s->dtd; 2274 seqs[i] = s; 2275 if (uuid) 2276 sdp_pattern_add_uuid(rec, uuid); 2277 } 2278 } 2279 seq = sdp_seq_alloc(seqDTDs, seqs, seqlen); 2280 free(seqDTDs); 2281 free(seqs); 2282 return seq; 2283 } 2284 2285 /* 2286 * sets the access protocols of the service specified 2287 * to the value specified in "access_proto" 2288 * 2289 * Note that if there are alternate mechanisms by 2290 * which the service is accessed, then they should 2291 * be specified as sequences 2292 * 2293 * Using a value of NULL for accessProtocols has 2294 * effect of removing this attribute (if previously set) 2295 * 2296 * This function replaces the existing sdp_access_proto_t 2297 * structure (if any) with the new one specified. 2298 * 2299 * returns 0 if successful or -1 if there is a failure. 2300 */ 2301 int sdp_set_access_protos(sdp_record_t *rec, const sdp_list_t *ap) 2302 { 2303 const sdp_list_t *p; 2304 sdp_data_t *protos = NULL; 2305 2306 for (p = ap; p; p = p->next) { 2307 sdp_data_t *seq = access_proto_to_dataseq(rec, 2308 (sdp_list_t *) p->data); 2309 protos = sdp_seq_append(protos, seq); 2310 } 2311 2312 sdp_attr_add(rec, SDP_ATTR_PROTO_DESC_LIST, protos); 2313 2314 return 0; 2315 } 2316 2317 int sdp_set_add_access_protos(sdp_record_t *rec, const sdp_list_t *ap) 2318 { 2319 const sdp_list_t *p; 2320 sdp_data_t *protos = NULL; 2321 2322 for (p = ap; p; p = p->next) { 2323 sdp_data_t *seq = access_proto_to_dataseq(rec, 2324 (sdp_list_t *) p->data); 2325 protos = sdp_seq_append(protos, seq); 2326 } 2327 2328 sdp_attr_add(rec, SDP_ATTR_ADD_PROTO_DESC_LIST, 2329 protos ? sdp_data_alloc(SDP_SEQ8, protos) : NULL); 2330 2331 return 0; 2332 } 2333 2334 /* 2335 * set the "LanguageBase" attributes of the service record 2336 * record to the value specified in "langAttrList". 2337 * 2338 * "langAttrList" is a linked list of "sdp_lang_attr_t" 2339 * objects, one for each language in which user visible 2340 * attributes are present in the service record. 2341 * 2342 * Using a value of NULL for langAttrList has 2343 * effect of removing this attribute (if previously set) 2344 * 2345 * This function replaces the exisiting sdp_lang_attr_t 2346 * structure (if any) with the new one specified. 2347 * 2348 * returns 0 if successful or -1 if there is a failure. 2349 */ 2350 int sdp_set_lang_attr(sdp_record_t *rec, const sdp_list_t *seq) 2351 { 2352 uint8_t uint16 = SDP_UINT16; 2353 int status = 0, i = 0, seqlen = sdp_list_len(seq); 2354 void **dtds = (void **)malloc(3 * seqlen * sizeof(void *)); 2355 void **values = (void **)malloc(3 * seqlen * sizeof(void *)); 2356 const sdp_list_t *p; 2357 2358 for (p = seq; p; p = p->next) { 2359 sdp_lang_attr_t *lang = (sdp_lang_attr_t *)p->data; 2360 if (!lang) { 2361 status = -1; 2362 break; 2363 } 2364 dtds[i] = &uint16; 2365 values[i] = &lang->code_ISO639; 2366 i++; 2367 dtds[i] = &uint16; 2368 values[i] = &lang->encoding; 2369 i++; 2370 dtds[i] = &uint16; 2371 values[i] = &lang->base_offset; 2372 i++; 2373 } 2374 if (status == 0) { 2375 sdp_data_t *seq = sdp_seq_alloc(dtds, values, 3 * seqlen); 2376 sdp_attr_add(rec, SDP_ATTR_LANG_BASE_ATTR_ID_LIST, seq); 2377 } 2378 free(dtds); 2379 free(values); 2380 return status; 2381 } 2382 2383 /* 2384 * set the "ServiceID" attribute of the service. 2385 * 2386 * This is the UUID of the service. 2387 * 2388 * returns 0 if successful or -1 if there is a failure. 2389 */ 2390 void sdp_set_service_id(sdp_record_t *rec, uuid_t uuid) 2391 { 2392 switch (uuid.type) { 2393 case SDP_UUID16: 2394 sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID16, 2395 &uuid.value.uuid16); 2396 break; 2397 case SDP_UUID32: 2398 sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID32, 2399 &uuid.value.uuid32); 2400 break; 2401 case SDP_UUID128: 2402 sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID128, 2403 &uuid.value.uuid128); 2404 break; 2405 } 2406 sdp_pattern_add_uuid(rec, &uuid); 2407 } 2408 2409 /* 2410 * set the GroupID attribute of the service record defining a group. 2411 * 2412 * This is the UUID of the group. 2413 * 2414 * returns 0 if successful or -1 if there is a failure. 2415 */ 2416 void sdp_set_group_id(sdp_record_t *rec, uuid_t uuid) 2417 { 2418 switch (uuid.type) { 2419 case SDP_UUID16: 2420 sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID16, 2421 &uuid.value.uuid16); 2422 break; 2423 case SDP_UUID32: 2424 sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID32, 2425 &uuid.value.uuid32); 2426 break; 2427 case SDP_UUID128: 2428 sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID128, 2429 &uuid.value.uuid128); 2430 break; 2431 } 2432 sdp_pattern_add_uuid(rec, &uuid); 2433 } 2434 2435 /* 2436 * set the ProfileDescriptorList attribute of the service record 2437 * pointed to by record to the value specified in "profileDesc". 2438 * 2439 * Each element in the list is an object of type 2440 * sdp_profile_desc_t which is a definition of the 2441 * Bluetooth profile that this service conforms to. 2442 * 2443 * Using a value of NULL for profileDesc has 2444 * effect of removing this attribute (if previously set) 2445 * 2446 * This function replaces the exisiting ProfileDescriptorList 2447 * structure (if any) with the new one specified. 2448 * 2449 * returns 0 if successful or -1 if there is a failure. 2450 */ 2451 int sdp_set_profile_descs(sdp_record_t *rec, const sdp_list_t *profiles) 2452 { 2453 int status = 0; 2454 uint8_t uuid16 = SDP_UUID16; 2455 uint8_t uuid32 = SDP_UUID32; 2456 uint8_t uuid128 = SDP_UUID128; 2457 uint8_t uint16 = SDP_UINT16; 2458 int i = 0, seqlen = sdp_list_len(profiles); 2459 void **seqDTDs = (void **)malloc(seqlen * sizeof(void *)); 2460 void **seqs = (void **)malloc(seqlen * sizeof(void *)); 2461 const sdp_list_t *p; 2462 2463 for (p = profiles; p; p = p->next) { 2464 sdp_data_t *seq; 2465 void *dtds[2], *values[2]; 2466 sdp_profile_desc_t *profile = (sdp_profile_desc_t *)p->data; 2467 if (!profile) { 2468 status = -1; 2469 break; 2470 } 2471 switch (profile->uuid.type) { 2472 case SDP_UUID16: 2473 dtds[0] = &uuid16; 2474 values[0] = &profile->uuid.value.uuid16; 2475 break; 2476 case SDP_UUID32: 2477 dtds[0] = &uuid32; 2478 values[0] = &profile->uuid.value.uuid32; 2479 break; 2480 case SDP_UUID128: 2481 dtds[0] = &uuid128; 2482 values[0] = &profile->uuid.value.uuid128; 2483 break; 2484 default: 2485 status = -1; 2486 break; 2487 } 2488 dtds[1] = &uint16; 2489 values[1] = &profile->version; 2490 seq = sdp_seq_alloc(dtds, values, 2); 2491 if (seq) { 2492 seqDTDs[i] = &seq->dtd; 2493 seqs[i] = seq; 2494 sdp_pattern_add_uuid(rec, &profile->uuid); 2495 } 2496 i++; 2497 } 2498 if (status == 0) { 2499 sdp_data_t *pAPSeq = sdp_seq_alloc(seqDTDs, seqs, seqlen); 2500 sdp_attr_add(rec, SDP_ATTR_PFILE_DESC_LIST, pAPSeq); 2501 } 2502 free(seqDTDs); 2503 free(seqs); 2504 return status; 2505 } 2506 2507 /* 2508 * sets various URL attributes of the service 2509 * pointed to by record. The URL include 2510 * 2511 * client: a URL to the client's 2512 * platform specific (WinCE, PalmOS) executable 2513 * code that can be used to access this service. 2514 * 2515 * doc: a URL pointing to service documentation 2516 * 2517 * icon: a URL to an icon that can be used to represent 2518 * this service. 2519 * 2520 * Note that you need to pass NULL for any URLs 2521 * that you don't want to set or remove 2522 */ 2523 void sdp_set_url_attr(sdp_record_t *rec, const char *client, const char *doc, 2524 const char *icon) 2525 { 2526 sdp_attr_add_new(rec, SDP_ATTR_CLNT_EXEC_URL, SDP_URL_STR8, client); 2527 sdp_attr_add_new(rec, SDP_ATTR_DOC_URL, SDP_URL_STR8, doc); 2528 sdp_attr_add_new(rec, SDP_ATTR_ICON_URL, SDP_URL_STR8, icon); 2529 } 2530 2531 uuid_t *sdp_uuid16_create(uuid_t *u, uint16_t val) 2532 { 2533 memset(u, 0, sizeof(uuid_t)); 2534 u->type = SDP_UUID16; 2535 u->value.uuid16 = val; 2536 return u; 2537 } 2538 2539 uuid_t *sdp_uuid32_create(uuid_t *u, uint32_t val) 2540 { 2541 memset(u, 0, sizeof(uuid_t)); 2542 u->type = SDP_UUID32; 2543 u->value.uuid32 = val; 2544 return u; 2545 } 2546 2547 uuid_t *sdp_uuid128_create(uuid_t *u, const void *val) 2548 { 2549 memset(u, 0, sizeof(uuid_t)); 2550 u->type = SDP_UUID128; 2551 memcpy(&u->value.uuid128, val, sizeof(uint128_t)); 2552 return u; 2553 } 2554 2555 /* 2556 * UUID comparison function 2557 * returns 0 if uuidValue1 == uuidValue2 else -1 2558 */ 2559 int sdp_uuid16_cmp(const void *p1, const void *p2) 2560 { 2561 const uuid_t *u1 = (const uuid_t *)p1; 2562 const uuid_t *u2 = (const uuid_t *)p2; 2563 return memcmp(&u1->value.uuid16, &u2->value.uuid16, sizeof(uint16_t)); 2564 } 2565 2566 /* 2567 * UUID comparison function 2568 * returns 0 if uuidValue1 == uuidValue2 else -1 2569 */ 2570 int sdp_uuid128_cmp(const void *p1, const void *p2) 2571 { 2572 const uuid_t *u1 = (const uuid_t *)p1; 2573 const uuid_t *u2 = (const uuid_t *)p2; 2574 return memcmp(&u1->value.uuid128, &u2->value.uuid128, sizeof(uint128_t)); 2575 } 2576 2577 /* 2578 * 128 to 16 bit and 32 to 16 bit UUID conversion functions 2579 * yet to be implemented. Note that the input is in NBO in 2580 * both 32 and 128 bit UUIDs and conversion is needed 2581 */ 2582 void sdp_uuid16_to_uuid128(uuid_t *uuid128, uuid_t *uuid16) 2583 { 2584 /* 2585 * We have a 16 bit value, which needs to be added to 2586 * bytes 3 and 4 (at indices 2 and 3) of the Bluetooth base 2587 */ 2588 unsigned short data1; 2589 2590 /* allocate a 128bit UUID and init to the Bluetooth base UUID */ 2591 uuid128->value.uuid128 = bluetooth_base_uuid; 2592 uuid128->type = SDP_UUID128; 2593 2594 /* extract bytes 2 and 3 of 128bit BT base UUID */ 2595 memcpy(&data1, &bluetooth_base_uuid.data[2], 2); 2596 2597 /* add the given UUID (16 bits) */ 2598 data1 += htons(uuid16->value.uuid16); 2599 2600 /* set bytes 2 and 3 of the 128 bit value */ 2601 memcpy(&uuid128->value.uuid128.data[2], &data1, 2); 2602 } 2603 2604 void sdp_uuid32_to_uuid128(uuid_t *uuid128, uuid_t *uuid32) 2605 { 2606 /* 2607 * We have a 32 bit value, which needs to be added to 2608 * bytes 1->4 (at indices 0 thru 3) of the Bluetooth base 2609 */ 2610 unsigned int data0; 2611 2612 /* allocate a 128bit UUID and init to the Bluetooth base UUID */ 2613 uuid128->value.uuid128 = bluetooth_base_uuid; 2614 uuid128->type = SDP_UUID128; 2615 2616 /* extract first 4 bytes */ 2617 memcpy(&data0, &bluetooth_base_uuid.data[0], 4); 2618 2619 /* add the given UUID (32bits) */ 2620 data0 += htonl(uuid32->value.uuid32); 2621 2622 /* set the 4 bytes of the 128 bit value */ 2623 memcpy(&uuid128->value.uuid128.data[0], &data0, 4); 2624 } 2625 2626 uuid_t *sdp_uuid_to_uuid128(uuid_t *uuid) 2627 { 2628 uuid_t *uuid128 = bt_malloc(sizeof(uuid_t)); 2629 memset(uuid128, 0, sizeof(uuid_t)); 2630 switch (uuid->type) { 2631 case SDP_UUID128: 2632 *uuid128 = *uuid; 2633 break; 2634 case SDP_UUID32: 2635 sdp_uuid32_to_uuid128(uuid128, uuid); 2636 break; 2637 case SDP_UUID16: 2638 sdp_uuid16_to_uuid128(uuid128, uuid); 2639 break; 2640 } 2641 return uuid128; 2642 } 2643 2644 /* 2645 * converts a 128-bit uuid to a 16/32-bit one if possible 2646 * returns true if uuid contains a 16/32-bit UUID at exit 2647 */ 2648 int sdp_uuid128_to_uuid(uuid_t *uuid) 2649 { 2650 uint128_t *b = &bluetooth_base_uuid; 2651 uint128_t *u = &uuid->value.uuid128; 2652 uint32_t data; 2653 unsigned int i; 2654 2655 if (uuid->type != SDP_UUID128) 2656 return 1; 2657 2658 for (i = 4; i < sizeof(b->data); i++) 2659 if (b->data[i] != u->data[i]) 2660 return 0; 2661 2662 memcpy(&data, u->data, 4); 2663 data = htonl(data); 2664 if (data <= 0xffff) { 2665 uuid->type = SDP_UUID16; 2666 uuid->value.uuid16 = (uint16_t) data; 2667 } else { 2668 uuid->type = SDP_UUID32; 2669 uuid->value.uuid32 = data; 2670 } 2671 return 1; 2672 } 2673 2674 /* 2675 * convert a UUID to the 16-bit short-form 2676 */ 2677 int sdp_uuid_to_proto(uuid_t *uuid) 2678 { 2679 uuid_t u = *uuid; 2680 if (sdp_uuid128_to_uuid(&u)) { 2681 switch (u.type) { 2682 case SDP_UUID16: 2683 return u.value.uuid16; 2684 case SDP_UUID32: 2685 return u.value.uuid32; 2686 } 2687 } 2688 return 0; 2689 } 2690 2691 /* 2692 * This function appends data to the PDU buffer "dst" from source "src". 2693 * The data length is also computed and set. 2694 * Should the PDU length exceed 2^8, then sequence type is 2695 * set accordingly and the data is memmove()'d. 2696 */ 2697 void sdp_append_to_buf(sdp_buf_t *dst, uint8_t *data, uint32_t len) 2698 { 2699 uint8_t *p = dst->data; 2700 uint8_t dtd = *(uint8_t *) p; 2701 2702 SDPDBG("Append src size: %d\n", len); 2703 SDPDBG("Append dst size: %d\n", dst->data_size); 2704 SDPDBG("Dst buffer size: %d\n", dst->buf_size); 2705 if (dst->data_size == 0 && dtd == 0) { 2706 /* create initial sequence */ 2707 *(uint8_t *)p = SDP_SEQ8; 2708 p += sizeof(uint8_t); 2709 dst->data_size += sizeof(uint8_t); 2710 /* reserve space for sequence size */ 2711 p += sizeof(uint8_t); 2712 dst->data_size += sizeof(uint8_t); 2713 } 2714 2715 memcpy(dst->data + dst->data_size, data, len); 2716 dst->data_size += len; 2717 2718 dtd = *(uint8_t *)dst->data; 2719 if (dst->data_size > UCHAR_MAX && dtd == SDP_SEQ8) { 2720 short offset = sizeof(uint8_t) + sizeof(uint8_t); 2721 memmove(dst->data + offset + 1, dst->data + offset, 2722 dst->data_size - offset); 2723 p = dst->data; 2724 *(uint8_t *) p = SDP_SEQ16; 2725 p += sizeof(uint8_t); 2726 dst->data_size += 1; 2727 } 2728 p = dst->data; 2729 dtd = *(uint8_t *) p; 2730 p += sizeof(uint8_t); 2731 switch (dtd) { 2732 case SDP_SEQ8: 2733 *(uint8_t *) p = dst->data_size - sizeof(uint8_t) - sizeof(uint8_t); 2734 break; 2735 case SDP_SEQ16: 2736 bt_put_unaligned(htons(dst->data_size - sizeof(uint8_t) - sizeof(uint16_t)), (uint16_t *) p); 2737 break; 2738 case SDP_SEQ32: 2739 bt_put_unaligned(htonl(dst->data_size - sizeof(uint8_t) - sizeof(uint32_t)), (uint32_t *) p); 2740 break; 2741 } 2742 } 2743 2744 void sdp_append_to_pdu(sdp_buf_t *pdu, sdp_data_t *d) 2745 { 2746 sdp_buf_t append; 2747 2748 memset(&append, 0, sizeof(sdp_buf_t)); 2749 sdp_gen_buffer(&append, d); 2750 append.data = malloc(append.buf_size); 2751 if (!append.data) 2752 return; 2753 2754 sdp_set_attrid(&append, d->attrId); 2755 sdp_gen_pdu(&append, d); 2756 sdp_append_to_buf(pdu, append.data, append.data_size); 2757 free(append.data); 2758 } 2759 2760 /* 2761 * Registers an sdp record. 2762 * 2763 * It is incorrect to call this method on a record that 2764 * has been already registered with the server. 2765 * 2766 * Returns zero on success, otherwise -1 (and sets errno). 2767 */ 2768 int sdp_device_record_register_binary(sdp_session_t *session, bdaddr_t *device, uint8_t *data, uint32_t size, uint8_t flags, uint32_t *handle) 2769 { 2770 uint8_t *req, *rsp, *p; 2771 uint32_t reqsize, rspsize; 2772 sdp_pdu_hdr_t *reqhdr, *rsphdr; 2773 int status; 2774 2775 SDPDBG(""); 2776 2777 if (!session->local) { 2778 errno = EREMOTE; 2779 return -1; 2780 } 2781 req = malloc(SDP_REQ_BUFFER_SIZE); 2782 rsp = malloc(SDP_RSP_BUFFER_SIZE); 2783 if (req == NULL || rsp == NULL) { 2784 status = -1; 2785 errno = ENOMEM; 2786 goto end; 2787 } 2788 2789 reqhdr = (sdp_pdu_hdr_t *)req; 2790 reqhdr->pdu_id = SDP_SVC_REGISTER_REQ; 2791 reqhdr->tid = htons(sdp_gen_tid(session)); 2792 reqsize = sizeof(sdp_pdu_hdr_t) + 1; 2793 p = req + sizeof(sdp_pdu_hdr_t); 2794 2795 if (bacmp(device, BDADDR_ANY)) { 2796 *p++ = flags | SDP_DEVICE_RECORD; 2797 bacpy((bdaddr_t *) p, device); 2798 p += sizeof(bdaddr_t); 2799 reqsize += sizeof(bdaddr_t); 2800 } else 2801 *p++ = flags; 2802 2803 memcpy(p, data, size); 2804 reqsize += size; 2805 reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); 2806 2807 status = sdp_send_req_w4_rsp(session, req, rsp, reqsize, &rspsize); 2808 if (status < 0) 2809 goto end; 2810 2811 if (rspsize < sizeof(sdp_pdu_hdr_t)) { 2812 SDPERR("Unexpected end of packet"); 2813 errno = EPROTO; 2814 status = -1; 2815 goto end; 2816 } 2817 2818 rsphdr = (sdp_pdu_hdr_t *) rsp; 2819 p = rsp + sizeof(sdp_pdu_hdr_t); 2820 2821 if (rsphdr->pdu_id == SDP_ERROR_RSP) { 2822 /* Invalid service record */ 2823 errno = EINVAL; 2824 status = -1; 2825 } else if (rsphdr->pdu_id != SDP_SVC_REGISTER_RSP) { 2826 errno = EPROTO; 2827 status = -1; 2828 } else { 2829 if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint32_t)) { 2830 SDPERR("Unexpected end of packet"); 2831 errno = EPROTO; 2832 status = -1; 2833 goto end; 2834 } 2835 if (handle) 2836 *handle = ntohl(bt_get_unaligned((uint32_t *) p)); 2837 } 2838 2839 end: 2840 if (req) 2841 free(req); 2842 2843 if (rsp) 2844 free(rsp); 2845 2846 return status; 2847 } 2848 2849 int sdp_device_record_register(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec, uint8_t flags) 2850 { 2851 sdp_buf_t pdu; 2852 uint32_t handle; 2853 int err; 2854 2855 SDPDBG(""); 2856 2857 if (rec->handle && rec->handle != 0xffffffff) { 2858 uint32_t handle = rec->handle; 2859 sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle); 2860 sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data); 2861 } 2862 2863 if (sdp_gen_record_pdu(rec, &pdu) < 0) { 2864 errno = ENOMEM; 2865 return -1; 2866 } 2867 2868 err = sdp_device_record_register_binary(session, device, 2869 pdu.data, pdu.data_size, flags, &handle); 2870 2871 free(pdu.data); 2872 2873 if (err == 0) { 2874 sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle); 2875 rec->handle = handle; 2876 sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data); 2877 } 2878 2879 return err; 2880 } 2881 2882 int sdp_record_register(sdp_session_t *session, sdp_record_t *rec, uint8_t flags) 2883 { 2884 return sdp_device_record_register(session, BDADDR_ANY, rec, flags); 2885 } 2886 2887 /* 2888 * unregister a service record 2889 */ 2890 int sdp_device_record_unregister_binary(sdp_session_t *session, bdaddr_t *device, uint32_t handle) 2891 { 2892 uint8_t *reqbuf, *rspbuf, *p; 2893 uint32_t reqsize = 0, rspsize = 0; 2894 sdp_pdu_hdr_t *reqhdr, *rsphdr; 2895 int status; 2896 2897 SDPDBG(""); 2898 2899 if (handle == SDP_SERVER_RECORD_HANDLE) { 2900 errno = EINVAL; 2901 return -1; 2902 } 2903 2904 if (!session->local) { 2905 errno = EREMOTE; 2906 return -1; 2907 } 2908 2909 reqbuf = malloc(SDP_REQ_BUFFER_SIZE); 2910 rspbuf = malloc(SDP_RSP_BUFFER_SIZE); 2911 if (!reqbuf || !rspbuf) { 2912 errno = ENOMEM; 2913 status = -1; 2914 goto end; 2915 } 2916 reqhdr = (sdp_pdu_hdr_t *) reqbuf; 2917 reqhdr->pdu_id = SDP_SVC_REMOVE_REQ; 2918 reqhdr->tid = htons(sdp_gen_tid(session)); 2919 2920 p = reqbuf + sizeof(sdp_pdu_hdr_t); 2921 reqsize = sizeof(sdp_pdu_hdr_t); 2922 bt_put_unaligned(htonl(handle), (uint32_t *) p); 2923 reqsize += sizeof(uint32_t); 2924 2925 reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); 2926 status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); 2927 if (status < 0) 2928 goto end; 2929 2930 if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint16_t)) { 2931 SDPERR("Unexpected end of packet"); 2932 errno = EPROTO; 2933 status = -1; 2934 goto end; 2935 } 2936 2937 rsphdr = (sdp_pdu_hdr_t *) rspbuf; 2938 p = rspbuf + sizeof(sdp_pdu_hdr_t); 2939 status = bt_get_unaligned((uint16_t *) p); 2940 2941 if (rsphdr->pdu_id == SDP_ERROR_RSP) { 2942 /* For this case the status always is invalid record handle */ 2943 errno = EINVAL; 2944 status = -1; 2945 } else if (rsphdr->pdu_id != SDP_SVC_REMOVE_RSP) { 2946 errno = EPROTO; 2947 status = -1; 2948 } 2949 end: 2950 if (reqbuf) 2951 free(reqbuf); 2952 2953 if (rspbuf) 2954 free(rspbuf); 2955 2956 return status; 2957 } 2958 2959 int sdp_device_record_unregister(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec) 2960 { 2961 int err; 2962 2963 err = sdp_device_record_unregister_binary(session, device, rec->handle); 2964 if (err == 0) 2965 sdp_record_free(rec); 2966 2967 return err; 2968 } 2969 2970 int sdp_record_unregister(sdp_session_t *session, sdp_record_t *rec) 2971 { 2972 return sdp_device_record_unregister(session, BDADDR_ANY, rec); 2973 } 2974 2975 /* 2976 * modify an existing service record 2977 */ 2978 int sdp_device_record_update_binary(sdp_session_t *session, bdaddr_t *device, uint32_t handle, uint8_t *data, uint32_t size) 2979 { 2980 return -1; 2981 } 2982 2983 int sdp_device_record_update(sdp_session_t *session, bdaddr_t *device, const sdp_record_t *rec) 2984 { 2985 uint8_t *reqbuf, *rspbuf, *p; 2986 uint32_t reqsize, rspsize; 2987 sdp_pdu_hdr_t *reqhdr, *rsphdr; 2988 uint32_t handle; 2989 sdp_buf_t pdu; 2990 int status; 2991 2992 SDPDBG(""); 2993 2994 handle = rec->handle; 2995 2996 if (handle == SDP_SERVER_RECORD_HANDLE) { 2997 errno = EINVAL; 2998 return -1; 2999 } 3000 if (!session->local) { 3001 errno = EREMOTE; 3002 return -1; 3003 } 3004 reqbuf = malloc(SDP_REQ_BUFFER_SIZE); 3005 rspbuf = malloc(SDP_RSP_BUFFER_SIZE); 3006 if (!reqbuf || !rspbuf) { 3007 errno = ENOMEM; 3008 status = -1; 3009 goto end; 3010 } 3011 reqhdr = (sdp_pdu_hdr_t *) reqbuf; 3012 reqhdr->pdu_id = SDP_SVC_UPDATE_REQ; 3013 reqhdr->tid = htons(sdp_gen_tid(session)); 3014 3015 p = reqbuf + sizeof(sdp_pdu_hdr_t); 3016 reqsize = sizeof(sdp_pdu_hdr_t); 3017 3018 bt_put_unaligned(htonl(handle), (uint32_t *) p); 3019 reqsize += sizeof(uint32_t); 3020 p += sizeof(uint32_t); 3021 3022 if (sdp_gen_record_pdu(rec, &pdu) < 0) { 3023 errno = ENOMEM; 3024 status = -1; 3025 goto end; 3026 } 3027 memcpy(p, pdu.data, pdu.data_size); 3028 reqsize += pdu.data_size; 3029 free(pdu.data); 3030 3031 reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); 3032 status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); 3033 if (status < 0) 3034 goto end; 3035 3036 if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint16_t)) { 3037 SDPERR("Unexpected end of packet"); 3038 errno = EPROTO; 3039 status = -1; 3040 goto end; 3041 } 3042 3043 SDPDBG("Send req status : %d\n", status); 3044 3045 rsphdr = (sdp_pdu_hdr_t *) rspbuf; 3046 p = rspbuf + sizeof(sdp_pdu_hdr_t); 3047 status = bt_get_unaligned((uint16_t *) p); 3048 3049 if (rsphdr->pdu_id == SDP_ERROR_RSP) { 3050 /* The status can be invalid sintax or invalid record handle */ 3051 errno = EINVAL; 3052 status = -1; 3053 } else if (rsphdr->pdu_id != SDP_SVC_UPDATE_RSP) { 3054 errno = EPROTO; 3055 status = -1; 3056 } 3057 end: 3058 if (reqbuf) 3059 free(reqbuf); 3060 if (rspbuf) 3061 free(rspbuf); 3062 return status; 3063 } 3064 3065 int sdp_record_update(sdp_session_t *session, const sdp_record_t *rec) 3066 { 3067 return sdp_device_record_update(session, BDADDR_ANY, rec); 3068 } 3069 3070 sdp_record_t *sdp_record_alloc() 3071 { 3072 sdp_record_t *rec = malloc(sizeof(sdp_record_t)); 3073 memset((void *)rec, 0, sizeof(sdp_record_t)); 3074 rec->handle = 0xffffffff; 3075 return rec; 3076 } 3077 3078 /* 3079 * Free the contents of a service record 3080 */ 3081 void sdp_record_free(sdp_record_t *rec) 3082 { 3083 sdp_list_free(rec->attrlist, (sdp_free_func_t)sdp_data_free); 3084 sdp_list_free(rec->pattern, free); 3085 free(rec); 3086 } 3087 3088 void sdp_pattern_add_uuid(sdp_record_t *rec, uuid_t *uuid) 3089 { 3090 uuid_t *uuid128 = sdp_uuid_to_uuid128(uuid); 3091 3092 SDPDBG("SvcRec : 0x%lx\n", (unsigned long)rec); 3093 SDPDBG("Elements in target pattern : %d\n", sdp_list_len(rec->pattern)); 3094 SDPDBG("Trying to add : 0x%lx\n", (unsigned long)uuid128); 3095 3096 if (sdp_list_find(rec->pattern, uuid128, sdp_uuid128_cmp) == NULL) 3097 rec->pattern = sdp_list_insert_sorted(rec->pattern, uuid128, sdp_uuid128_cmp); 3098 else 3099 bt_free(uuid128); 3100 3101 SDPDBG("Elements in target pattern : %d\n", sdp_list_len(rec->pattern)); 3102 } 3103 3104 void sdp_pattern_add_uuidseq(sdp_record_t *rec, sdp_list_t *seq) 3105 { 3106 for (; seq; seq = seq->next) { 3107 uuid_t *uuid = (uuid_t *)seq->data; 3108 sdp_pattern_add_uuid(rec, uuid); 3109 } 3110 } 3111 3112 /* 3113 * Extract a sequence of service record handles from a PDU buffer 3114 * and add the entries to a sdp_list_t. Note that the service record 3115 * handles are not in "data element sequence" form, but just like 3116 * an array of service handles 3117 */ 3118 static void extract_record_handle_seq(uint8_t *pdu, int bufsize, sdp_list_t **seq, int count, unsigned int *scanned) 3119 { 3120 sdp_list_t *pSeq = *seq; 3121 uint8_t *pdata = pdu; 3122 int n; 3123 3124 for (n = 0; n < count; n++) { 3125 uint32_t *pSvcRec; 3126 if (bufsize < (int) sizeof(uint32_t)) { 3127 SDPERR("Unexpected end of packet"); 3128 break; 3129 } 3130 pSvcRec = malloc(sizeof(uint32_t)); 3131 if (!pSvcRec) 3132 break; 3133 *pSvcRec = ntohl(bt_get_unaligned((uint32_t *) pdata)); 3134 pSeq = sdp_list_append(pSeq, pSvcRec); 3135 pdata += sizeof(uint32_t); 3136 *scanned += sizeof(uint32_t); 3137 bufsize -= sizeof(uint32_t); 3138 } 3139 *seq = pSeq; 3140 } 3141 /* 3142 * Generate the attribute sequence pdu form 3143 * from sdp_list_t elements. Return length of attr seq 3144 */ 3145 static int gen_dataseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dtd) 3146 { 3147 sdp_data_t *dataseq; 3148 void **types, **values; 3149 sdp_buf_t buf; 3150 int i, seqlen = sdp_list_len(seq); 3151 3152 // Fill up the value and the dtd arrays 3153 SDPDBG(""); 3154 3155 SDPDBG("Seq length : %d\n", seqlen); 3156 3157 types = malloc(seqlen * sizeof(void *)); 3158 if (!types) 3159 return -ENOMEM; 3160 3161 values = malloc(seqlen * sizeof(void *)); 3162 if (!values) { 3163 free(types); 3164 return -ENOMEM; 3165 } 3166 3167 for (i = 0; i < seqlen; i++) { 3168 void *data = seq->data; 3169 types[i] = &dtd; 3170 if (SDP_IS_UUID(dtd)) 3171 data = &((uuid_t *)data)->value; 3172 values[i] = data; 3173 seq = seq->next; 3174 } 3175 3176 dataseq = sdp_seq_alloc(types, values, seqlen); 3177 if (!dataseq) { 3178 free(types); 3179 free(values); 3180 return -ENOMEM; 3181 } 3182 3183 memset(&buf, 0, sizeof(sdp_buf_t)); 3184 sdp_gen_buffer(&buf, dataseq); 3185 buf.data = malloc(buf.buf_size); 3186 3187 if (!buf.data) { 3188 sdp_data_free(dataseq); 3189 free(types); 3190 free(values); 3191 return -ENOMEM; 3192 } 3193 3194 SDPDBG("Data Seq : 0x%p\n", seq); 3195 seqlen = sdp_gen_pdu(&buf, dataseq); 3196 SDPDBG("Copying : %d\n", buf.data_size); 3197 memcpy(dst, buf.data, buf.data_size); 3198 3199 sdp_data_free(dataseq); 3200 3201 free(types); 3202 free(values); 3203 free(buf.data); 3204 return seqlen; 3205 } 3206 3207 static int gen_searchseq_pdu(uint8_t *dst, const sdp_list_t *seq) 3208 { 3209 uuid_t *uuid = (uuid_t *) seq->data; 3210 return gen_dataseq_pdu(dst, seq, uuid->type); 3211 } 3212 3213 static int gen_attridseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dataType) 3214 { 3215 return gen_dataseq_pdu(dst, seq, dataType); 3216 } 3217 3218 typedef struct { 3219 uint8_t length; 3220 unsigned char data[16]; 3221 } __attribute__ ((packed)) sdp_cstate_t; 3222 3223 static int copy_cstate(uint8_t *pdata, int pdata_len, const sdp_cstate_t *cstate) 3224 { 3225 if (cstate) { 3226 uint8_t len = cstate->length; 3227 if (len >= pdata_len) { 3228 SDPERR("Continuation state size exceeds internal buffer"); 3229 len = pdata_len - 1; 3230 } 3231 *pdata++ = len; 3232 memcpy(pdata, cstate->data, len); 3233 return len + 1; 3234 } 3235 *pdata = 0; 3236 return 1; 3237 } 3238 3239 /* 3240 * This is a service search request. 3241 * 3242 * INPUT : 3243 * 3244 * sdp_list_t *search 3245 * Singly linked list containing elements of the search 3246 * pattern. Each entry in the list is a UUID (DataTypeSDP_UUID16) 3247 * of the service to be searched 3248 * 3249 * uint16_t max_rec_num 3250 * A 16 bit integer which tells the service, the maximum 3251 * entries that the client can handle in the response. The 3252 * server is obliged not to return > max_rec_num entries 3253 * 3254 * OUTPUT : 3255 * 3256 * int return value 3257 * 0: 3258 * The request completed successfully. This does not 3259 * mean the requested services were found 3260 * -1: 3261 * On any failure and sets errno 3262 * 3263 * sdp_list_t **rsp_list 3264 * This variable is set on a successful return if there are 3265 * non-zero service handles. It is a singly linked list of 3266 * service record handles (uint16_t) 3267 */ 3268 int sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search, 3269 uint16_t max_rec_num, sdp_list_t **rsp) 3270 { 3271 int status = 0; 3272 uint32_t reqsize = 0, _reqsize; 3273 uint32_t rspsize = 0, rsplen; 3274 int seqlen = 0; 3275 int total_rec_count, rec_count; 3276 unsigned scanned, pdata_len; 3277 uint8_t *pdata, *_pdata; 3278 uint8_t *reqbuf, *rspbuf; 3279 sdp_pdu_hdr_t *reqhdr, *rsphdr; 3280 sdp_cstate_t *cstate = NULL; 3281 3282 reqbuf = malloc(SDP_REQ_BUFFER_SIZE); 3283 rspbuf = malloc(SDP_RSP_BUFFER_SIZE); 3284 if (!reqbuf || !rspbuf) { 3285 errno = ENOMEM; 3286 status = -1; 3287 goto end; 3288 } 3289 reqhdr = (sdp_pdu_hdr_t *) reqbuf; 3290 reqhdr->pdu_id = SDP_SVC_SEARCH_REQ; 3291 pdata = reqbuf + sizeof(sdp_pdu_hdr_t); 3292 reqsize = sizeof(sdp_pdu_hdr_t); 3293 3294 // add service class IDs for search 3295 seqlen = gen_searchseq_pdu(pdata, search); 3296 3297 SDPDBG("Data seq added : %d\n", seqlen); 3298 3299 // set the length and increment the pointer 3300 reqsize += seqlen; 3301 pdata += seqlen; 3302 3303 // specify the maximum svc rec count that client expects 3304 bt_put_unaligned(htons(max_rec_num), (uint16_t *) pdata); 3305 reqsize += sizeof(uint16_t); 3306 pdata += sizeof(uint16_t); 3307 3308 _reqsize = reqsize; 3309 _pdata = pdata; 3310 *rsp = NULL; 3311 3312 do { 3313 // Add continuation state or NULL (first time) 3314 reqsize = _reqsize + copy_cstate(_pdata, 3315 SDP_REQ_BUFFER_SIZE - _reqsize, cstate); 3316 3317 // Set the request header's param length 3318 reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); 3319 3320 reqhdr->tid = htons(sdp_gen_tid(session)); 3321 /* 3322 * Send the request, wait for response and if 3323 * no error, set the appropriate values and return 3324 */ 3325 status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); 3326 if (status < 0) 3327 goto end; 3328 3329 if (rspsize < sizeof(sdp_pdu_hdr_t)) { 3330 SDPERR("Unexpected end of packet"); 3331 status = -1; 3332 goto end; 3333 } 3334 3335 rsphdr = (sdp_pdu_hdr_t *) rspbuf; 3336 rsplen = ntohs(rsphdr->plen); 3337 3338 if (rsphdr->pdu_id == SDP_ERROR_RSP) { 3339 SDPDBG("Status : 0x%x\n", rsphdr->pdu_id); 3340 status = -1; 3341 goto end; 3342 } 3343 scanned = 0; 3344 pdata = rspbuf + sizeof(sdp_pdu_hdr_t); 3345 pdata_len = rspsize - sizeof(sdp_pdu_hdr_t); 3346 3347 if (pdata_len < sizeof(uint16_t) + sizeof(uint16_t)) { 3348 SDPERR("Unexpected end of packet"); 3349 status = -1; 3350 goto end; 3351 } 3352 3353 // net service record match count 3354 total_rec_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); 3355 pdata += sizeof(uint16_t); 3356 scanned += sizeof(uint16_t); 3357 pdata_len -= sizeof(uint16_t); 3358 rec_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); 3359 pdata += sizeof(uint16_t); 3360 scanned += sizeof(uint16_t); 3361 pdata_len -= sizeof(uint16_t); 3362 3363 SDPDBG("Total svc count: %d\n", total_rec_count); 3364 SDPDBG("Current svc count: %d\n", rec_count); 3365 SDPDBG("ResponseLength: %d\n", rsplen); 3366 3367 if (!rec_count) { 3368 status = -1; 3369 goto end; 3370 } 3371 extract_record_handle_seq(pdata, pdata_len, rsp, rec_count, &scanned); 3372 SDPDBG("BytesScanned : %d\n", scanned); 3373 3374 if (rsplen > scanned) { 3375 uint8_t cstate_len; 3376 3377 if (rspsize < sizeof(sdp_pdu_hdr_t) + scanned + sizeof(uint8_t)) { 3378 SDPERR("Unexpected end of packet: continuation state data missing"); 3379 status = -1; 3380 goto end; 3381 } 3382 3383 pdata = rspbuf + sizeof(sdp_pdu_hdr_t) + scanned; 3384 cstate_len = *(uint8_t *) pdata; 3385 if (cstate_len > 0) { 3386 cstate = (sdp_cstate_t *)pdata; 3387 SDPDBG("Cont state length: %d\n", cstate_len); 3388 } else 3389 cstate = NULL; 3390 } 3391 } while (cstate); 3392 3393 end: 3394 if (reqbuf) 3395 free(reqbuf); 3396 if (rspbuf) 3397 free(rspbuf); 3398 3399 return status; 3400 } 3401 3402 /* 3403 * This is a service attribute request. 3404 * 3405 * INPUT : 3406 * 3407 * uint32_t handle 3408 * The handle of the service for which the attribute(s) are 3409 * requested 3410 * 3411 * sdp_attrreq_type_t reqtype 3412 * Attribute identifiers are 16 bit unsigned integers specified 3413 * in one of 2 ways described below : 3414 * SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers 3415 * They are the actual attribute identifiers in ascending order 3416 * 3417 * SDP_ATTR_REQ_RANGE - 32bit identifier range 3418 * The high-order 16bits is the start of range 3419 * the low-order 16bits are the end of range 3420 * 0x0000 to 0xFFFF gets all attributes 3421 * 3422 * sdp_list_t *attrid 3423 * Singly linked list containing attribute identifiers desired. 3424 * Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL) 3425 * or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE) 3426 * 3427 * OUTPUT : 3428 * return sdp_record_t * 3429 * 0: 3430 * On any error and sets errno 3431 * !0: 3432 * The service record 3433 */ 3434 sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle, 3435 sdp_attrreq_type_t reqtype, const sdp_list_t *attrids) 3436 { 3437 uint32_t reqsize = 0, _reqsize; 3438 uint32_t rspsize = 0, rsp_count; 3439 int attr_list_len = 0; 3440 int seqlen = 0; 3441 unsigned int pdata_len; 3442 uint8_t *pdata, *_pdata; 3443 uint8_t *reqbuf, *rspbuf; 3444 sdp_pdu_hdr_t *reqhdr, *rsphdr; 3445 sdp_cstate_t *cstate = NULL; 3446 uint8_t cstate_len = 0; 3447 sdp_buf_t rsp_concat_buf; 3448 sdp_record_t *rec = 0; 3449 3450 if (reqtype != SDP_ATTR_REQ_INDIVIDUAL && reqtype != SDP_ATTR_REQ_RANGE) { 3451 errno = EINVAL; 3452 return 0; 3453 } 3454 3455 reqbuf = malloc(SDP_REQ_BUFFER_SIZE); 3456 rspbuf = malloc(SDP_RSP_BUFFER_SIZE); 3457 if (!reqbuf || !rspbuf) { 3458 errno = ENOMEM; 3459 goto end; 3460 } 3461 memset((char *) &rsp_concat_buf, 0, sizeof(sdp_buf_t)); 3462 reqhdr = (sdp_pdu_hdr_t *) reqbuf; 3463 reqhdr->pdu_id = SDP_SVC_ATTR_REQ; 3464 3465 pdata = reqbuf + sizeof(sdp_pdu_hdr_t); 3466 reqsize = sizeof(sdp_pdu_hdr_t); 3467 3468 // add the service record handle 3469 bt_put_unaligned(htonl(handle), (uint32_t *) pdata); 3470 reqsize += sizeof(uint32_t); 3471 pdata += sizeof(uint32_t); 3472 3473 // specify the response limit 3474 bt_put_unaligned(htons(65535), (uint16_t *) pdata); 3475 reqsize += sizeof(uint16_t); 3476 pdata += sizeof(uint16_t); 3477 3478 // get attr seq PDU form 3479 seqlen = gen_attridseq_pdu(pdata, attrids, 3480 reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16 : SDP_UINT32); 3481 if (seqlen == -1) { 3482 errno = EINVAL; 3483 goto end; 3484 } 3485 pdata += seqlen; 3486 reqsize += seqlen; 3487 SDPDBG("Attr list length : %d\n", seqlen); 3488 3489 // save before Continuation State 3490 _pdata = pdata; 3491 _reqsize = reqsize; 3492 3493 do { 3494 int status; 3495 3496 // add NULL continuation state 3497 reqsize = _reqsize + copy_cstate(_pdata, 3498 SDP_REQ_BUFFER_SIZE - _reqsize, cstate); 3499 3500 // set the request header's param length 3501 reqhdr->tid = htons(sdp_gen_tid(session)); 3502 reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); 3503 3504 status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); 3505 if (status < 0) 3506 goto end; 3507 3508 if (rspsize < sizeof(sdp_pdu_hdr_t)) { 3509 SDPERR("Unexpected end of packet"); 3510 goto end; 3511 } 3512 3513 rsphdr = (sdp_pdu_hdr_t *) rspbuf; 3514 if (rsphdr->pdu_id == SDP_ERROR_RSP) { 3515 SDPDBG("PDU ID : 0x%x\n", rsphdr->pdu_id); 3516 goto end; 3517 } 3518 pdata = rspbuf + sizeof(sdp_pdu_hdr_t); 3519 pdata_len = rspsize - sizeof(sdp_pdu_hdr_t); 3520 3521 if (pdata_len < sizeof(uint16_t)) { 3522 SDPERR("Unexpected end of packet"); 3523 goto end; 3524 } 3525 3526 rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); 3527 attr_list_len += rsp_count; 3528 pdata += sizeof(uint16_t); 3529 pdata_len -= sizeof(uint16_t); 3530 3531 // if continuation state set need to re-issue request before parsing 3532 if (pdata_len < rsp_count + sizeof(uint8_t)) { 3533 SDPERR("Unexpected end of packet: continuation state data missing"); 3534 goto end; 3535 } 3536 cstate_len = *(uint8_t *) (pdata + rsp_count); 3537 3538 SDPDBG("Response id : %d\n", rsphdr->pdu_id); 3539 SDPDBG("Attrlist byte count : %d\n", rsp_count); 3540 SDPDBG("sdp_cstate_t length : %d\n", cstate_len); 3541 3542 /* 3543 * a split response: concatenate intermediate responses 3544 * and the last one (which has cstate_len == 0) 3545 */ 3546 if (cstate_len > 0 || rsp_concat_buf.data_size != 0) { 3547 uint8_t *targetPtr = NULL; 3548 3549 cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0; 3550 3551 // build concatenated response buffer 3552 rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count); 3553 rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count; 3554 targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size; 3555 memcpy(targetPtr, pdata, rsp_count); 3556 rsp_concat_buf.data_size += rsp_count; 3557 } 3558 } while (cstate); 3559 3560 if (attr_list_len > 0) { 3561 int scanned = 0; 3562 if (rsp_concat_buf.data_size != 0) { 3563 pdata = rsp_concat_buf.data; 3564 pdata_len = rsp_concat_buf.data_size; 3565 } 3566 rec = sdp_extract_pdu(pdata, pdata_len, &scanned); 3567 } 3568 3569 end: 3570 if (reqbuf) 3571 free(reqbuf); 3572 if (rsp_concat_buf.data) 3573 free(rsp_concat_buf.data); 3574 if (rspbuf) 3575 free(rspbuf); 3576 return rec; 3577 } 3578 3579 /* 3580 * SDP transaction structure for asynchronous search 3581 */ 3582 struct sdp_transaction { 3583 sdp_callback_t *cb; /* called when the transaction finishes */ 3584 void *udata; /* client user data */ 3585 uint8_t *reqbuf; /* pointer to request PDU */ 3586 sdp_buf_t rsp_concat_buf; 3587 uint32_t reqsize; /* without cstate */ 3588 int err; /* ZERO if success or the errno if failed */ 3589 }; 3590 3591 /* 3592 * Creates a new sdp session for asynchronous search 3593 * INPUT: 3594 * int sk 3595 * non-blocking L2CAP socket 3596 * 3597 * RETURN: 3598 * sdp_session_t * 3599 * NULL - On memory allocation failure 3600 */ 3601 sdp_session_t *sdp_create(int sk, uint32_t flags) 3602 { 3603 sdp_session_t *session; 3604 struct sdp_transaction *t; 3605 3606 session = malloc(sizeof(sdp_session_t)); 3607 if (!session) { 3608 errno = ENOMEM; 3609 return NULL; 3610 } 3611 memset(session, 0, sizeof(*session)); 3612 3613 session->flags = flags; 3614 session->sock = sk; 3615 3616 t = malloc(sizeof(struct sdp_transaction)); 3617 if (!t) { 3618 errno = ENOMEM; 3619 free(session); 3620 return NULL; 3621 } 3622 memset(t, 0, sizeof(*t)); 3623 3624 session->priv = t; 3625 3626 return session; 3627 } 3628 3629 /* 3630 * Sets the callback function/user data used to notify the application 3631 * that the asynchronous transaction finished. This function must be 3632 * called before request an asynchronous search. 3633 * 3634 * INPUT: 3635 * sdp_session_t *session 3636 * Current sdp session to be handled 3637 * sdp_callback_t *cb 3638 * callback to be called when the transaction finishes 3639 * void *udata 3640 * user data passed to callback 3641 * RETURN: 3642 * 0 - Success 3643 * -1 - Failure 3644 */ 3645 int sdp_set_notify(sdp_session_t *session, sdp_callback_t *func, void *udata) 3646 { 3647 struct sdp_transaction *t; 3648 3649 if (!session || !session->priv) 3650 return -1; 3651 3652 t = session->priv; 3653 t->cb = func; 3654 t->udata = udata; 3655 3656 return 0; 3657 } 3658 3659 /* 3660 * This function starts an asynchronous service search request. 3661 * The incomming and outgoing data are stored in the transaction structure 3662 * buffers. When there is incomming data the sdp_process function must be 3663 * called to get the data and handle the continuation state. 3664 * 3665 * INPUT : 3666 * sdp_session_t *session 3667 * Current sdp session to be handled 3668 * 3669 * sdp_list_t *search 3670 * Singly linked list containing elements of the search 3671 * pattern. Each entry in the list is a UUID (DataTypeSDP_UUID16) 3672 * of the service to be searched 3673 * 3674 * uint16_t max_rec_num 3675 * A 16 bit integer which tells the service, the maximum 3676 * entries that the client can handle in the response. The 3677 * server is obliged not to return > max_rec_num entries 3678 * 3679 * OUTPUT : 3680 * 3681 * int return value 3682 * 0 - if the request has been sent properly 3683 * -1 - On any failure and sets errno 3684 */ 3685 3686 int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search, uint16_t max_rec_num) 3687 { 3688 struct sdp_transaction *t; 3689 sdp_pdu_hdr_t *reqhdr; 3690 uint8_t *pdata; 3691 int cstate_len, seqlen = 0; 3692 3693 if (!session || !session->priv) 3694 return -1; 3695 3696 t = session->priv; 3697 3698 /* check if the buffer is already allocated */ 3699 if (t->rsp_concat_buf.data) 3700 free(t->rsp_concat_buf.data); 3701 memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t)); 3702 3703 if (!t->reqbuf) { 3704 t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE); 3705 if (!t->reqbuf) { 3706 t->err = ENOMEM; 3707 goto end; 3708 } 3709 } 3710 memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE); 3711 3712 reqhdr = (sdp_pdu_hdr_t *) t->reqbuf; 3713 reqhdr->tid = htons(sdp_gen_tid(session)); 3714 reqhdr->pdu_id = SDP_SVC_SEARCH_REQ; 3715 3716 // generate PDU 3717 pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t); 3718 t->reqsize = sizeof(sdp_pdu_hdr_t); 3719 3720 // add service class IDs for search 3721 seqlen = gen_searchseq_pdu(pdata, search); 3722 3723 SDPDBG("Data seq added : %d\n", seqlen); 3724 3725 // now set the length and increment the pointer 3726 t->reqsize += seqlen; 3727 pdata += seqlen; 3728 3729 bt_put_unaligned(htons(max_rec_num), (uint16_t *) pdata); 3730 t->reqsize += sizeof(uint16_t); 3731 pdata += sizeof(uint16_t); 3732 3733 // set the request header's param length 3734 cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL); 3735 reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t)); 3736 3737 if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) { 3738 SDPERR("Error sendind data:%s", strerror(errno)); 3739 t->err = errno; 3740 goto end; 3741 } 3742 3743 return 0; 3744 end: 3745 3746 if (t->reqbuf) { 3747 free(t->reqbuf); 3748 t->reqbuf = NULL; 3749 } 3750 3751 return -1; 3752 } 3753 3754 /* 3755 * This function starts an asynchronous service attribute request. 3756 * The incomming and outgoing data are stored in the transaction structure 3757 * buffers. When there is incomming data the sdp_process function must be 3758 * called to get the data and handle the continuation state. 3759 * 3760 * INPUT : 3761 * sdp_session_t *session 3762 * Current sdp session to be handled 3763 * 3764 * uint32_t handle 3765 * The handle of the service for which the attribute(s) are 3766 * requested 3767 * 3768 * sdp_attrreq_type_t reqtype 3769 * Attribute identifiers are 16 bit unsigned integers specified 3770 * in one of 2 ways described below : 3771 * SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers 3772 * They are the actual attribute identifiers in ascending order 3773 * 3774 * SDP_ATTR_REQ_RANGE - 32bit identifier range 3775 * The high-order 16bits is the start of range 3776 * the low-order 16bits are the end of range 3777 * 0x0000 to 0xFFFF gets all attributes 3778 * 3779 * sdp_list_t *attrid_list 3780 * Singly linked list containing attribute identifiers desired. 3781 * Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL) 3782 * or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE) 3783 * 3784 * OUTPUT : 3785 * int return value 3786 * 0 - if the request has been sent properly 3787 * -1 - On any failure and sets errno 3788 */ 3789 3790 int sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list) 3791 { 3792 struct sdp_transaction *t; 3793 sdp_pdu_hdr_t *reqhdr; 3794 uint8_t *pdata; 3795 int cstate_len, seqlen = 0; 3796 3797 if (!session || !session->priv) 3798 return -1; 3799 3800 t = session->priv; 3801 3802 /* check if the buffer is already allocated */ 3803 if (t->rsp_concat_buf.data) 3804 free(t->rsp_concat_buf.data); 3805 memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t)); 3806 3807 if (!t->reqbuf) { 3808 t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE); 3809 if (!t->reqbuf) { 3810 t->err = ENOMEM; 3811 goto end; 3812 } 3813 } 3814 memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE); 3815 3816 reqhdr = (sdp_pdu_hdr_t *) t->reqbuf; 3817 reqhdr->tid = htons(sdp_gen_tid(session)); 3818 reqhdr->pdu_id = SDP_SVC_ATTR_REQ; 3819 3820 // generate PDU 3821 pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t); 3822 t->reqsize = sizeof(sdp_pdu_hdr_t); 3823 3824 // add the service record handle 3825 bt_put_unaligned(htonl(handle), (uint32_t *) pdata); 3826 t->reqsize += sizeof(uint32_t); 3827 pdata += sizeof(uint32_t); 3828 3829 // specify the response limit 3830 bt_put_unaligned(htons(65535), (uint16_t *) pdata); 3831 t->reqsize += sizeof(uint16_t); 3832 pdata += sizeof(uint16_t); 3833 3834 // get attr seq PDU form 3835 seqlen = gen_attridseq_pdu(pdata, attrid_list, 3836 reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16 : SDP_UINT32); 3837 if (seqlen == -1) { 3838 t->err = EINVAL; 3839 goto end; 3840 } 3841 3842 // now set the length and increment the pointer 3843 t->reqsize += seqlen; 3844 pdata += seqlen; 3845 SDPDBG("Attr list length : %d\n", seqlen); 3846 3847 // set the request header's param length 3848 cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL); 3849 reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t)); 3850 3851 if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) { 3852 SDPERR("Error sendind data:%s", strerror(errno)); 3853 t->err = errno; 3854 goto end; 3855 } 3856 3857 return 0; 3858 end: 3859 3860 if (t->reqbuf) { 3861 free(t->reqbuf); 3862 t->reqbuf = NULL; 3863 } 3864 3865 return -1; 3866 } 3867 3868 /* 3869 * This function starts an asynchronous service search attributes. 3870 * It is a service search request combined with attribute request. The incomming 3871 * and outgoing data are stored in the transaction structure buffers. When there 3872 * is incomming data the sdp_process function must be called to get the data 3873 * and handle the continuation state. 3874 * 3875 * INPUT: 3876 * sdp_session_t *session 3877 * Current sdp session to be handled 3878 * 3879 * sdp_list_t *search 3880 * Singly linked list containing elements of the search 3881 * pattern. Each entry in the list is a UUID(DataTypeSDP_UUID16) 3882 * of the service to be searched 3883 * 3884 * AttributeSpecification attrSpec 3885 * Attribute identifiers are 16 bit unsigned integers specified 3886 * in one of 2 ways described below : 3887 * SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers 3888 * They are the actual attribute identifiers in ascending order 3889 * 3890 * SDP_ATTR_REQ_RANGE - 32bit identifier range 3891 * The high-order 16bits is the start of range 3892 * the low-order 16bits are the end of range 3893 * 0x0000 to 0xFFFF gets all attributes 3894 * 3895 * sdp_list_t *attrid_list 3896 * Singly linked list containing attribute identifiers desired. 3897 * Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL) 3898 * or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE) 3899 * 3900 3901 * RETURN: 3902 * 0 - if the request has been sent properly 3903 * -1 - On any failure 3904 */ 3905 int sdp_service_search_attr_async(sdp_session_t *session, const sdp_list_t *search, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list) 3906 { 3907 struct sdp_transaction *t; 3908 sdp_pdu_hdr_t *reqhdr; 3909 uint8_t *pdata; 3910 int cstate_len, seqlen = 0; 3911 3912 if (!session || !session->priv) 3913 return -1; 3914 3915 t = session->priv; 3916 3917 /* check if the buffer is already allocated */ 3918 if (t->rsp_concat_buf.data) 3919 free(t->rsp_concat_buf.data); 3920 memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t)); 3921 3922 if (!t->reqbuf) { 3923 t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE); 3924 if (!t->reqbuf) { 3925 t->err = ENOMEM; 3926 goto end; 3927 } 3928 } 3929 memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE); 3930 3931 reqhdr = (sdp_pdu_hdr_t *) t->reqbuf; 3932 reqhdr->tid = htons(sdp_gen_tid(session)); 3933 reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ; 3934 3935 // generate PDU 3936 pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t); 3937 t->reqsize = sizeof(sdp_pdu_hdr_t); 3938 3939 // add service class IDs for search 3940 seqlen = gen_searchseq_pdu(pdata, search); 3941 3942 SDPDBG("Data seq added : %d\n", seqlen); 3943 3944 // now set the length and increment the pointer 3945 t->reqsize += seqlen; 3946 pdata += seqlen; 3947 3948 bt_put_unaligned(htons(SDP_MAX_ATTR_LEN), (uint16_t *) pdata); 3949 t->reqsize += sizeof(uint16_t); 3950 pdata += sizeof(uint16_t); 3951 3952 SDPDBG("Max attr byte count : %d\n", SDP_MAX_ATTR_LEN); 3953 3954 // get attr seq PDU form 3955 seqlen = gen_attridseq_pdu(pdata, attrid_list, 3956 reqtype == SDP_ATTR_REQ_INDIVIDUAL ? SDP_UINT16 : SDP_UINT32); 3957 if (seqlen == -1) { 3958 t->err = EINVAL; 3959 goto end; 3960 } 3961 3962 pdata += seqlen; 3963 SDPDBG("Attr list length : %d\n", seqlen); 3964 t->reqsize += seqlen; 3965 3966 // set the request header's param length 3967 cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL); 3968 reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t)); 3969 3970 if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) { 3971 SDPERR("Error sendind data:%s", strerror(errno)); 3972 t->err = errno; 3973 goto end; 3974 } 3975 3976 return 0; 3977 end: 3978 3979 if (t->reqbuf) { 3980 free(t->reqbuf); 3981 t->reqbuf = NULL; 3982 } 3983 3984 return -1; 3985 } 3986 3987 /* 3988 * Function used to get the error reason after sdp_callback_t function has been called 3989 * and the status is 0xffff or if sdp_service_{search, attr, search_attr}_async returns -1. 3990 * It indicates that an error NOT related to SDP_ErrorResponse happened. Get errno directly 3991 * is not safe because multiple transactions can be triggered. 3992 * This function must be used with asynchronous sdp functions only. 3993 * 3994 * INPUT: 3995 * sdp_session_t *session 3996 * Current sdp session to be handled 3997 * RETURN: 3998 * 0 = No error in the current transaction 3999 * -1 - if the session is invalid 4000 * positive value - the errno value 4001 * 4002 */ 4003 int sdp_get_error(sdp_session_t *session) 4004 { 4005 struct sdp_transaction *t; 4006 4007 if (!session || !session->priv) { 4008 SDPERR("Invalid session"); 4009 return -1; 4010 } 4011 4012 t = session->priv; 4013 4014 return t->err; 4015 } 4016 4017 /* 4018 * Receive the incomming SDP PDU. This function must be called when there is data 4019 * available to be read. On continuation state, the original request (with a new 4020 * transaction ID) and the continuation state data will be appended in the initial PDU. 4021 * If an error happens or the transaction finishes the callback function will be called. 4022 * 4023 * INPUT: 4024 * sdp_session_t *session 4025 * Current sdp session to be handled 4026 * RETURN: 4027 * 0 - if the transaction is on continuation state 4028 * -1 - On any failure or the transaction finished 4029 */ 4030 int sdp_process(sdp_session_t *session) 4031 { 4032 struct sdp_transaction *t; 4033 sdp_pdu_hdr_t *reqhdr, *rsphdr; 4034 sdp_cstate_t *pcstate; 4035 uint8_t *pdata, *rspbuf, *targetPtr; 4036 int rsp_count, err = -1; 4037 size_t size = 0; 4038 int n, plen; 4039 uint16_t status = 0xffff; 4040 uint8_t pdu_id = 0x00; 4041 4042 if (!session || !session->priv) { 4043 SDPERR("Invalid session"); 4044 return -1; 4045 } 4046 4047 rspbuf = malloc(SDP_RSP_BUFFER_SIZE); 4048 if (!rspbuf) { 4049 SDPERR("Response buffer alloc failure:%s (%d)", 4050 strerror(errno), errno); 4051 return -1; 4052 } 4053 4054 memset(rspbuf, 0, SDP_RSP_BUFFER_SIZE); 4055 4056 t = session->priv; 4057 reqhdr = (sdp_pdu_hdr_t *)t->reqbuf; 4058 rsphdr = (sdp_pdu_hdr_t *)rspbuf; 4059 4060 pdata = rspbuf + sizeof(sdp_pdu_hdr_t); 4061 4062 n = sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE); 4063 if (n < 0) { 4064 SDPERR("Read response:%s (%d)", strerror(errno), errno); 4065 t->err = errno; 4066 goto end; 4067 } 4068 4069 if (n == 0 || reqhdr->tid != rsphdr->tid || 4070 (n != (ntohs(rsphdr->plen) + (int) sizeof(sdp_pdu_hdr_t)))) { 4071 t->err = EPROTO; 4072 SDPERR("Protocol error."); 4073 goto end; 4074 } 4075 4076 pdu_id = rsphdr->pdu_id; 4077 switch (rsphdr->pdu_id) { 4078 uint8_t *ssr_pdata; 4079 uint16_t tsrc, csrc; 4080 case SDP_SVC_SEARCH_RSP: 4081 /* 4082 * TSRC: Total Service Record Count (2 bytes) 4083 * CSRC: Current Service Record Count (2 bytes) 4084 */ 4085 ssr_pdata = pdata; 4086 tsrc = ntohs(bt_get_unaligned((uint16_t *) ssr_pdata)); 4087 ssr_pdata += sizeof(uint16_t); 4088 csrc = ntohs(bt_get_unaligned((uint16_t *) ssr_pdata)); 4089 4090 /* csrc should never be larger than tsrc */ 4091 if (csrc > tsrc) { 4092 t->err = EPROTO; 4093 SDPERR("Protocol error: wrong current service record count value."); 4094 goto end; 4095 } 4096 4097 SDPDBG("Total svc count: %d\n", tsrc); 4098 SDPDBG("Current svc count: %d\n", csrc); 4099 4100 /* parameter length without continuation state */ 4101 plen = sizeof(tsrc) + sizeof(csrc) + csrc * 4; 4102 4103 if (t->rsp_concat_buf.data_size == 0) { 4104 /* first fragment */ 4105 rsp_count = sizeof(tsrc) + sizeof(csrc) + csrc * 4; 4106 } else { 4107 /* point to the first csrc */ 4108 uint16_t *pcsrc = (uint16_t *) (t->rsp_concat_buf.data + 2); 4109 4110 /* FIXME: update the interface later. csrc doesn't need be passed to clients */ 4111 4112 pdata += sizeof(uint16_t); /* point to csrc */ 4113 4114 /* the first csrc contains the sum of partial csrc responses */ 4115 *pcsrc += bt_get_unaligned((uint16_t *) pdata); 4116 4117 pdata += sizeof(uint16_t); /* point to the first handle */ 4118 rsp_count = csrc * 4; 4119 } 4120 status = 0x0000; 4121 break; 4122 case SDP_SVC_ATTR_RSP: 4123 case SDP_SVC_SEARCH_ATTR_RSP: 4124 rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); 4125 SDPDBG("Attrlist byte count : %d\n", rsp_count); 4126 4127 /* 4128 * Number of bytes in the AttributeLists parameter(without 4129 * continuation state) + AttributeListsByteCount field size. 4130 */ 4131 plen = sizeof(uint16_t) + rsp_count; 4132 4133 pdata += sizeof(uint16_t); // points to attribute list 4134 status = 0x0000; 4135 break; 4136 case SDP_ERROR_RSP: 4137 status = ntohs(bt_get_unaligned((uint16_t *) pdata)); 4138 size = ntohs(rsphdr->plen); 4139 4140 /* error code + error info */ 4141 plen = size; 4142 goto end; 4143 default: 4144 t->err = EPROTO; 4145 SDPERR("Illegal PDU ID: 0x%x", rsphdr->pdu_id); 4146 goto end; 4147 } 4148 4149 pcstate = (sdp_cstate_t *) (pdata + rsp_count); 4150 4151 SDPDBG("Cstate length : %d\n", pcstate->length); 4152 4153 /* 4154 * Check out of bound. Continuation state must have at least 4155 * 1 byte: ZERO to indicate that it is not a partial response. 4156 */ 4157 if ((n - (int) sizeof(sdp_pdu_hdr_t)) != (plen + pcstate->length + 1)) { 4158 t->err = EPROTO; 4159 SDPERR("Protocol error: wrong PDU size."); 4160 status = 0xffff; 4161 goto end; 4162 } 4163 4164 /* 4165 * This is a split response, need to concatenate intermediate 4166 * responses and the last one which will have cstate length == 0 4167 */ 4168 t->rsp_concat_buf.data = realloc(t->rsp_concat_buf.data, t->rsp_concat_buf.data_size + rsp_count); 4169 targetPtr = t->rsp_concat_buf.data + t->rsp_concat_buf.data_size; 4170 t->rsp_concat_buf.buf_size = t->rsp_concat_buf.data_size + rsp_count; 4171 memcpy(targetPtr, pdata, rsp_count); 4172 t->rsp_concat_buf.data_size += rsp_count; 4173 4174 if (pcstate->length > 0) { 4175 int reqsize, cstate_len; 4176 4177 reqhdr->tid = htons(sdp_gen_tid(session)); 4178 4179 // add continuation state 4180 cstate_len = copy_cstate(t->reqbuf + t->reqsize, 4181 SDP_REQ_BUFFER_SIZE - t->reqsize, pcstate); 4182 4183 reqsize = t->reqsize + cstate_len; 4184 4185 // set the request header's param length 4186 reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); 4187 4188 if (sdp_send_req(session, t->reqbuf, reqsize) < 0) { 4189 SDPERR("Error sendind data:%s(%d)", strerror(errno), errno); 4190 status = 0xffff; 4191 t->err = errno; 4192 goto end; 4193 } 4194 err = 0; 4195 } 4196 4197 end: 4198 if (err) { 4199 if (t->rsp_concat_buf.data_size != 0) { 4200 pdata = t->rsp_concat_buf.data; 4201 size = t->rsp_concat_buf.data_size; 4202 } 4203 if (t->cb) 4204 t->cb(pdu_id, status, pdata, size, t->udata); 4205 } 4206 4207 if (rspbuf) 4208 free(rspbuf); 4209 4210 return err; 4211 } 4212 4213 /* 4214 * This is a service search request combined with the service 4215 * attribute request. First a service class match is done and 4216 * for matching service, requested attributes are extracted 4217 * 4218 * INPUT : 4219 * 4220 * sdp_list_t *search 4221 * Singly linked list containing elements of the search 4222 * pattern. Each entry in the list is a UUID(DataTypeSDP_UUID16) 4223 * of the service to be searched 4224 * 4225 * AttributeSpecification attrSpec 4226 * Attribute identifiers are 16 bit unsigned integers specified 4227 * in one of 2 ways described below : 4228 * SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers 4229 * They are the actual attribute identifiers in ascending order 4230 * 4231 * SDP_ATTR_REQ_RANGE - 32bit identifier range 4232 * The high-order 16bits is the start of range 4233 * the low-order 16bits are the end of range 4234 * 0x0000 to 0xFFFF gets all attributes 4235 * 4236 * sdp_list_t *attrids 4237 * Singly linked list containing attribute identifiers desired. 4238 * Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL) 4239 * or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE) 4240 * 4241 * OUTPUT : 4242 * int return value 4243 * 0: 4244 * The request completed successfully. This does not 4245 * mean the requested services were found 4246 * -1: 4247 * On any error and sets errno 4248 * 4249 * sdp_list_t **rsp 4250 * This variable is set on a successful return to point to 4251 * service(s) found. Each element of this list is of type 4252 * sdp_record_t* (of the services which matched the search list) 4253 */ 4254 int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search, sdp_attrreq_type_t reqtype, const sdp_list_t *attrids, sdp_list_t **rsp) 4255 { 4256 int status = 0; 4257 uint32_t reqsize = 0, _reqsize; 4258 uint32_t rspsize = 0; 4259 int seqlen = 0, attr_list_len = 0; 4260 int rsp_count = 0, cstate_len = 0; 4261 unsigned int pdata_len; 4262 uint8_t *pdata, *_pdata; 4263 uint8_t *reqbuf, *rspbuf; 4264 sdp_pdu_hdr_t *reqhdr, *rsphdr; 4265 uint8_t dataType; 4266 sdp_list_t *rec_list = NULL; 4267 sdp_buf_t rsp_concat_buf; 4268 sdp_cstate_t *cstate = NULL; 4269 4270 if (reqtype != SDP_ATTR_REQ_INDIVIDUAL && reqtype != SDP_ATTR_REQ_RANGE) { 4271 errno = EINVAL; 4272 return -1; 4273 } 4274 reqbuf = malloc(SDP_REQ_BUFFER_SIZE); 4275 rspbuf = malloc(SDP_RSP_BUFFER_SIZE); 4276 if (!reqbuf || !rspbuf) { 4277 errno = ENOMEM; 4278 status = -1; 4279 goto end; 4280 } 4281 4282 memset((char *)&rsp_concat_buf, 0, sizeof(sdp_buf_t)); 4283 reqhdr = (sdp_pdu_hdr_t *) reqbuf; 4284 reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ; 4285 4286 // generate PDU 4287 pdata = reqbuf + sizeof(sdp_pdu_hdr_t); 4288 reqsize = sizeof(sdp_pdu_hdr_t); 4289 4290 // add service class IDs for search 4291 seqlen = gen_searchseq_pdu(pdata, search); 4292 4293 SDPDBG("Data seq added : %d\n", seqlen); 4294 4295 /* now set the length and increment the pointer */ 4296 reqsize += seqlen; 4297 pdata += seqlen; 4298 4299 bt_put_unaligned(htons(SDP_MAX_ATTR_LEN), (uint16_t *) pdata); 4300 reqsize += sizeof(uint16_t); 4301 pdata += sizeof(uint16_t); 4302 4303 SDPDBG("Max attr byte count : %d\n", SDP_MAX_ATTR_LEN); 4304 4305 /* get attr seq PDU form */ 4306 seqlen = gen_attridseq_pdu(pdata, attrids, 4307 reqtype == SDP_ATTR_REQ_INDIVIDUAL ? SDP_UINT16 : SDP_UINT32); 4308 if (seqlen == -1) { 4309 status = EINVAL; 4310 goto end; 4311 } 4312 pdata += seqlen; 4313 SDPDBG("Attr list length : %d\n", seqlen); 4314 reqsize += seqlen; 4315 *rsp = 0; 4316 4317 /* save before Continuation State */ 4318 _pdata = pdata; 4319 _reqsize = reqsize; 4320 4321 do { 4322 reqhdr->tid = htons(sdp_gen_tid(session)); 4323 4324 /* add continuation state (can be null) */ 4325 reqsize = _reqsize + copy_cstate(_pdata, 4326 SDP_REQ_BUFFER_SIZE - _reqsize, cstate); 4327 4328 /* set the request header's param length */ 4329 reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); 4330 rsphdr = (sdp_pdu_hdr_t *) rspbuf; 4331 status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); 4332 if (rspsize < sizeof(sdp_pdu_hdr_t)) { 4333 SDPERR("Unexpected end of packet"); 4334 status = -1; 4335 goto end; 4336 } 4337 4338 if (status < 0) { 4339 SDPDBG("Status : 0x%x\n", rsphdr->pdu_id); 4340 goto end; 4341 } 4342 4343 if (rsphdr->pdu_id == SDP_ERROR_RSP) { 4344 status = -1; 4345 goto end; 4346 } 4347 4348 pdata = rspbuf + sizeof(sdp_pdu_hdr_t); 4349 pdata_len = rspsize - sizeof(sdp_pdu_hdr_t); 4350 4351 if (pdata_len < sizeof(uint16_t)) { 4352 SDPERR("Unexpected end of packet"); 4353 status = -1; 4354 goto end; 4355 } 4356 4357 rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); 4358 attr_list_len += rsp_count; 4359 pdata += sizeof(uint16_t); // pdata points to attribute list 4360 pdata_len -= sizeof(uint16_t); 4361 4362 if (pdata_len < rsp_count + sizeof(uint8_t)) { 4363 SDPERR("Unexpected end of packet: continuation state data missing"); 4364 status = -1; 4365 goto end; 4366 } 4367 4368 cstate_len = *(uint8_t *) (pdata + rsp_count); 4369 4370 SDPDBG("Attrlist byte count : %d\n", attr_list_len); 4371 SDPDBG("Response byte count : %d\n", rsp_count); 4372 SDPDBG("Cstate length : %d\n", cstate_len); 4373 /* 4374 * This is a split response, need to concatenate intermediate 4375 * responses and the last one which will have cstate_len == 0 4376 */ 4377 if (cstate_len > 0 || rsp_concat_buf.data_size != 0) { 4378 uint8_t *targetPtr = NULL; 4379 4380 cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0; 4381 4382 /* build concatenated response buffer */ 4383 rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count); 4384 targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size; 4385 rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count; 4386 memcpy(targetPtr, pdata, rsp_count); 4387 rsp_concat_buf.data_size += rsp_count; 4388 } 4389 } while (cstate); 4390 4391 if (attr_list_len > 0) { 4392 int scanned = 0; 4393 4394 if (rsp_concat_buf.data_size != 0) { 4395 pdata = rsp_concat_buf.data; 4396 pdata_len = rsp_concat_buf.data_size; 4397 } 4398 4399 /* 4400 * Response is a sequence of sequence(s) for one or 4401 * more data element sequence(s) representing services 4402 * for which attributes are returned 4403 */ 4404 scanned = sdp_extract_seqtype(pdata, pdata_len, &dataType, &seqlen); 4405 4406 SDPDBG("Bytes scanned : %d\n", scanned); 4407 SDPDBG("Seq length : %d\n", seqlen); 4408 4409 if (scanned && seqlen) { 4410 pdata += scanned; 4411 pdata_len -= scanned; 4412 do { 4413 int recsize = 0; 4414 sdp_record_t *rec = sdp_extract_pdu(pdata, pdata_len, &recsize); 4415 if (rec == NULL) { 4416 SDPERR("SVC REC is null\n"); 4417 status = -1; 4418 goto end; 4419 } 4420 if (!recsize) { 4421 sdp_record_free(rec); 4422 break; 4423 } 4424 scanned += recsize; 4425 pdata += recsize; 4426 pdata_len -= recsize; 4427 4428 SDPDBG("Loc seq length : %d\n", recsize); 4429 SDPDBG("Svc Rec Handle : 0x%x\n", rec->handle); 4430 SDPDBG("Bytes scanned : %d\n", scanned); 4431 SDPDBG("Attrlist byte count : %d\n", attr_list_len); 4432 rec_list = sdp_list_append(rec_list, rec); 4433 } while (scanned < attr_list_len && pdata_len > 0); 4434 4435 SDPDBG("Successful scan of service attr lists\n"); 4436 *rsp = rec_list; 4437 } 4438 } 4439 end: 4440 if (rsp_concat_buf.data) 4441 free(rsp_concat_buf.data); 4442 if (reqbuf) 4443 free(reqbuf); 4444 if (rspbuf) 4445 free(rspbuf); 4446 return status; 4447 } 4448 4449 /* 4450 * Find devices in the piconet. 4451 */ 4452 int sdp_general_inquiry(inquiry_info *ii, int num_dev, int duration, uint8_t *found) 4453 { 4454 int n = hci_inquiry(-1, 10, num_dev, NULL, &ii, 0); 4455 if (n < 0) { 4456 SDPERR("Inquiry failed:%s", strerror(errno)); 4457 return -1; 4458 } 4459 *found = n; 4460 return 0; 4461 } 4462 4463 int sdp_close(sdp_session_t *session) 4464 { 4465 struct sdp_transaction *t; 4466 int ret; 4467 4468 if (!session) 4469 return -1; 4470 4471 ret = close(session->sock); 4472 4473 t = session->priv; 4474 4475 if (t) { 4476 if (t->reqbuf) 4477 free(t->reqbuf); 4478 4479 if (t->rsp_concat_buf.data) 4480 free(t->rsp_concat_buf.data); 4481 4482 free(t); 4483 } 4484 free(session); 4485 return ret; 4486 } 4487 4488 static inline int sdp_is_local(const bdaddr_t *device) 4489 { 4490 return memcmp(device, BDADDR_LOCAL, sizeof(bdaddr_t)) == 0; 4491 } 4492 4493 static int sdp_connect_local(sdp_session_t *session) 4494 { 4495 struct sockaddr_un sa; 4496 4497 session->sock = socket(PF_UNIX, SOCK_STREAM, 0); 4498 if (session->sock < 0) 4499 return -1; 4500 session->local = 1; 4501 4502 sa.sun_family = AF_UNIX; 4503 strcpy(sa.sun_path, SDP_UNIX_PATH); 4504 4505 return connect(session->sock, (struct sockaddr *)&sa, sizeof(sa)); 4506 } 4507 4508 static int sdp_connect_l2cap(const bdaddr_t *src, 4509 const bdaddr_t *dst, sdp_session_t *session) 4510 { 4511 uint32_t flags = session->flags; 4512 struct sockaddr_l2 sa; 4513 int sk; 4514 4515 session->sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); 4516 if (session->sock < 0) 4517 return -1; 4518 session->local = 0; 4519 4520 sk = session->sock; 4521 4522 if (flags & SDP_NON_BLOCKING) { 4523 long arg = fcntl(sk, F_GETFL, 0); 4524 fcntl(sk, F_SETFL, arg | O_NONBLOCK); 4525 } 4526 4527 memset(&sa, 0, sizeof(sa)); 4528 4529 sa.l2_family = AF_BLUETOOTH; 4530 sa.l2_psm = 0; 4531 4532 if (bacmp(src, BDADDR_ANY)) { 4533 sa.l2_bdaddr = *src; 4534 if (bind(sk, (struct sockaddr *) &sa, sizeof(sa)) < 0) 4535 return -1; 4536 } 4537 4538 if (flags & SDP_WAIT_ON_CLOSE) { 4539 struct linger l = { .l_onoff = 1, .l_linger = 1 }; 4540 setsockopt(sk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)); 4541 } 4542 4543 sa.l2_psm = htobs(SDP_PSM); 4544 sa.l2_bdaddr = *dst; 4545 4546 do { 4547 int ret = connect(sk, (struct sockaddr *) &sa, sizeof(sa)); 4548 if (!ret) 4549 return 0; 4550 if (ret < 0 && (flags & SDP_NON_BLOCKING) && 4551 (errno == EAGAIN || errno == EINPROGRESS)) 4552 return 0; 4553 } while (errno == EBUSY && (flags & SDP_RETRY_IF_BUSY)); 4554 4555 return -1; 4556 } 4557 4558 sdp_session_t *sdp_connect(const bdaddr_t *src, 4559 const bdaddr_t *dst, uint32_t flags) 4560 { 4561 sdp_session_t *session; 4562 int err; 4563 4564 if ((flags & SDP_RETRY_IF_BUSY) && (flags & SDP_NON_BLOCKING)) { 4565 errno = EINVAL; 4566 return NULL; 4567 } 4568 4569 session = sdp_create(-1, flags); 4570 if (!session) 4571 return NULL; 4572 4573 if (sdp_is_local(dst)) { 4574 if (sdp_connect_local(session) < 0) 4575 goto fail; 4576 } else { 4577 if (sdp_connect_l2cap(src, dst, session) < 0) 4578 goto fail; 4579 } 4580 4581 return session; 4582 4583 fail: 4584 err = errno; 4585 if (session->sock >= 0) 4586 close(session->sock); 4587 if (session->priv) 4588 free(session->priv); 4589 free(session); 4590 errno = err; 4591 4592 return NULL; 4593 } 4594 4595 int sdp_get_socket(const sdp_session_t *session) 4596 { 4597 return session->sock; 4598 } 4599 4600 uint16_t sdp_gen_tid(sdp_session_t *session) 4601 { 4602 return session->tid++; 4603 } 4604