1 /****************************************************************************** 2 * 3 * Copyright (C) 1999-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 /****************************************************************************** 20 * 21 * This file contains SDP utility functions 22 * 23 ******************************************************************************/ 24 25 #include <stdlib.h> 26 #include <string.h> 27 #include <netinet/in.h> 28 #include <stdio.h> 29 30 #include "bt_common.h" 31 #include "bt_types.h" 32 33 #include "l2cdefs.h" 34 #include "hcidefs.h" 35 #include "hcimsgs.h" 36 37 #include "sdp_api.h" 38 #include "sdpint.h" 39 40 #include "btu.h" 41 42 43 static const UINT8 sdp_base_uuid[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 44 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}; 45 46 /******************************************************************************* 47 ** 48 ** Function sdpu_find_ccb_by_cid 49 ** 50 ** Description This function searches the CCB table for an entry with the 51 ** passed CID. 52 ** 53 ** Returns the CCB address, or NULL if not found. 54 ** 55 *******************************************************************************/ 56 tCONN_CB *sdpu_find_ccb_by_cid (UINT16 cid) 57 { 58 UINT16 xx; 59 tCONN_CB *p_ccb; 60 61 /* Look through each connection control block */ 62 for (xx = 0, p_ccb = sdp_cb.ccb; xx < SDP_MAX_CONNECTIONS; xx++, p_ccb++) 63 { 64 if ((p_ccb->con_state != SDP_STATE_IDLE) && (p_ccb->connection_id == cid)) 65 return (p_ccb); 66 } 67 68 /* If here, not found */ 69 return (NULL); 70 } 71 72 73 /******************************************************************************* 74 ** 75 ** Function sdpu_find_ccb_by_db 76 ** 77 ** Description This function searches the CCB table for an entry with the 78 ** passed discovery db. 79 ** 80 ** Returns the CCB address, or NULL if not found. 81 ** 82 *******************************************************************************/ 83 tCONN_CB *sdpu_find_ccb_by_db (tSDP_DISCOVERY_DB *p_db) 84 { 85 #if SDP_CLIENT_ENABLED == TRUE 86 UINT16 xx; 87 tCONN_CB *p_ccb; 88 89 if (p_db) 90 { 91 /* Look through each connection control block */ 92 for (xx = 0, p_ccb = sdp_cb.ccb; xx < SDP_MAX_CONNECTIONS; xx++, p_ccb++) 93 { 94 if ((p_ccb->con_state != SDP_STATE_IDLE) && (p_ccb->p_db == p_db)) 95 return (p_ccb); 96 } 97 } 98 #endif 99 /* If here, not found */ 100 return (NULL); 101 } 102 103 104 /******************************************************************************* 105 ** 106 ** Function sdpu_allocate_ccb 107 ** 108 ** Description This function allocates a new CCB. 109 ** 110 ** Returns CCB address, or NULL if none available. 111 ** 112 *******************************************************************************/ 113 tCONN_CB *sdpu_allocate_ccb (void) 114 { 115 UINT16 xx; 116 tCONN_CB *p_ccb; 117 118 /* Look through each connection control block for a free one */ 119 for (xx = 0, p_ccb = sdp_cb.ccb; xx < SDP_MAX_CONNECTIONS; xx++, p_ccb++) 120 { 121 if (p_ccb->con_state == SDP_STATE_IDLE) 122 { 123 memset(p_ccb, 0, sizeof(tCONN_CB)); 124 p_ccb->sdp_conn_timer = alarm_new("sdp.sdp_conn_timer"); 125 return (p_ccb); 126 } 127 } 128 129 /* If here, no free CCB found */ 130 return (NULL); 131 } 132 133 134 /******************************************************************************* 135 ** 136 ** Function sdpu_release_ccb 137 ** 138 ** Description This function releases a CCB. 139 ** 140 ** Returns void 141 ** 142 *******************************************************************************/ 143 void sdpu_release_ccb (tCONN_CB *p_ccb) 144 { 145 /* Ensure timer is stopped */ 146 alarm_free(p_ccb->sdp_conn_timer); 147 p_ccb->sdp_conn_timer = NULL; 148 149 /* Drop any response pointer we may be holding */ 150 p_ccb->con_state = SDP_STATE_IDLE; 151 #if SDP_CLIENT_ENABLED == TRUE 152 p_ccb->is_attr_search = FALSE; 153 #endif 154 155 /* Free the response buffer */ 156 if (p_ccb->rsp_list) 157 SDP_TRACE_DEBUG("releasing SDP rsp_list"); 158 osi_free_and_reset((void **)&p_ccb->rsp_list); 159 } 160 161 162 /******************************************************************************* 163 ** 164 ** Function sdpu_build_attrib_seq 165 ** 166 ** Description This function builds an attribute sequence from the list of 167 ** passed attributes. It is also passed the address of the output 168 ** buffer. 169 ** 170 ** Returns Pointer to next byte in the output buffer. 171 ** 172 *******************************************************************************/ 173 UINT8 *sdpu_build_attrib_seq (UINT8 *p_out, UINT16 *p_attr, UINT16 num_attrs) 174 { 175 UINT16 xx; 176 177 /* First thing is the data element header. See if the length fits 1 byte */ 178 /* If no attributes, assume a 4-byte wildcard */ 179 if (!p_attr) 180 xx = 5; 181 else 182 xx = num_attrs * 3; 183 184 if (xx > 255) 185 { 186 UINT8_TO_BE_STREAM (p_out, (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_WORD); 187 UINT16_TO_BE_STREAM (p_out, xx); 188 } 189 else 190 { 191 UINT8_TO_BE_STREAM (p_out, (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE); 192 UINT8_TO_BE_STREAM (p_out, xx); 193 } 194 195 /* If there are no attributes specified, assume caller wants wildcard */ 196 if (!p_attr) 197 { 198 UINT8_TO_BE_STREAM (p_out, (UINT_DESC_TYPE << 3) | SIZE_FOUR_BYTES); 199 UINT16_TO_BE_STREAM (p_out, 0); 200 UINT16_TO_BE_STREAM (p_out, 0xFFFF); 201 } 202 else 203 { 204 /* Loop through and put in all the attributes(s) */ 205 for (xx = 0; xx < num_attrs; xx++, p_attr++) 206 { 207 UINT8_TO_BE_STREAM (p_out, (UINT_DESC_TYPE << 3) | SIZE_TWO_BYTES); 208 UINT16_TO_BE_STREAM (p_out, *p_attr); 209 } 210 } 211 212 return (p_out); 213 } 214 215 216 /******************************************************************************* 217 ** 218 ** Function sdpu_build_attrib_entry 219 ** 220 ** Description This function builds an attribute entry from the passed 221 ** attribute record. It is also passed the address of the output 222 ** buffer. 223 ** 224 ** Returns Pointer to next byte in the output buffer. 225 ** 226 *******************************************************************************/ 227 UINT8 *sdpu_build_attrib_entry (UINT8 *p_out, tSDP_ATTRIBUTE *p_attr) 228 { 229 /* First, store the attribute ID. Goes as a UINT */ 230 UINT8_TO_BE_STREAM (p_out, (UINT_DESC_TYPE << 3) | SIZE_TWO_BYTES); 231 UINT16_TO_BE_STREAM (p_out, p_attr->id); 232 233 /* the attribute is in the db record. 234 * assuming the attribute len is less than SDP_MAX_ATTR_LEN */ 235 switch(p_attr->type) 236 { 237 case TEXT_STR_DESC_TYPE: /* 4 */ 238 case DATA_ELE_SEQ_DESC_TYPE:/* 6 */ 239 case DATA_ELE_ALT_DESC_TYPE:/* 7 */ 240 case URL_DESC_TYPE: /* 8 */ 241 #if (SDP_MAX_ATTR_LEN > 0xFFFF) 242 if(p_attr->len > 0xFFFF) 243 { 244 UINT8_TO_BE_STREAM (p_out, (p_attr->type << 3) | SIZE_IN_NEXT_LONG); 245 UINT32_TO_BE_STREAM (p_out, p_attr->len); 246 } 247 else 248 249 #endif /* 0xFFFF - 0xFF */ 250 #if (SDP_MAX_ATTR_LEN > 0xFF) 251 if(p_attr->len > 0xFF) 252 { 253 UINT8_TO_BE_STREAM (p_out, (p_attr->type << 3) | SIZE_IN_NEXT_WORD); 254 UINT16_TO_BE_STREAM (p_out, p_attr->len); 255 } 256 else 257 258 #endif /* 0xFF and less*/ 259 { 260 UINT8_TO_BE_STREAM (p_out, (p_attr->type << 3) | SIZE_IN_NEXT_BYTE); 261 UINT8_TO_BE_STREAM (p_out, p_attr->len); 262 } 263 264 if (p_attr->value_ptr != NULL) { 265 ARRAY_TO_BE_STREAM (p_out, p_attr->value_ptr, (int)p_attr->len); 266 } 267 268 return (p_out); 269 } 270 271 /* Now, store the attribute value */ 272 switch (p_attr->len) 273 { 274 case 1: 275 UINT8_TO_BE_STREAM (p_out, (p_attr->type << 3) | SIZE_ONE_BYTE); 276 break; 277 case 2: 278 UINT8_TO_BE_STREAM (p_out, (p_attr->type << 3) | SIZE_TWO_BYTES); 279 break; 280 case 4: 281 UINT8_TO_BE_STREAM (p_out, (p_attr->type << 3) | SIZE_FOUR_BYTES); 282 break; 283 case 8: 284 UINT8_TO_BE_STREAM (p_out, (p_attr->type << 3) | SIZE_EIGHT_BYTES); 285 break; 286 case 16: 287 UINT8_TO_BE_STREAM (p_out, (p_attr->type << 3) | SIZE_SIXTEEN_BYTES); 288 break; 289 default: 290 UINT8_TO_BE_STREAM (p_out, (p_attr->type << 3) | SIZE_IN_NEXT_BYTE); 291 UINT8_TO_BE_STREAM (p_out, p_attr->len); 292 break; 293 } 294 295 if (p_attr->value_ptr != NULL) { 296 ARRAY_TO_BE_STREAM (p_out, p_attr->value_ptr, (int)p_attr->len); 297 } 298 299 return (p_out); 300 } 301 302 303 /******************************************************************************* 304 ** 305 ** Function sdpu_build_n_send_error 306 ** 307 ** Description This function builds and sends an error packet. 308 ** 309 ** Returns void 310 ** 311 *******************************************************************************/ 312 void sdpu_build_n_send_error (tCONN_CB *p_ccb, UINT16 trans_num, UINT16 error_code, char *p_error_text) 313 { 314 UINT8 *p_rsp, *p_rsp_start, *p_rsp_param_len; 315 UINT16 rsp_param_len; 316 BT_HDR *p_buf = (BT_HDR *)osi_malloc(SDP_DATA_BUF_SIZE); 317 318 319 SDP_TRACE_WARNING ("SDP - sdpu_build_n_send_error code: 0x%x CID: 0x%x", 320 error_code, p_ccb->connection_id); 321 322 /* Send the packet to L2CAP */ 323 p_buf->offset = L2CAP_MIN_OFFSET; 324 p_rsp = p_rsp_start = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET; 325 326 UINT8_TO_BE_STREAM(p_rsp, SDP_PDU_ERROR_RESPONSE); 327 UINT16_TO_BE_STREAM(p_rsp, trans_num); 328 329 /* Skip the parameter length, we need to add it at the end */ 330 p_rsp_param_len = p_rsp; 331 p_rsp += 2; 332 333 UINT16_TO_BE_STREAM (p_rsp, error_code); 334 335 /* Unplugfest example traces do not have any error text */ 336 if (p_error_text) 337 ARRAY_TO_BE_STREAM(p_rsp, p_error_text, (int)strlen(p_error_text)); 338 339 /* Go back and put the parameter length into the buffer */ 340 rsp_param_len = p_rsp - p_rsp_param_len - 2; 341 UINT16_TO_BE_STREAM(p_rsp_param_len, rsp_param_len); 342 343 /* Set the length of the SDP data in the buffer */ 344 p_buf->len = p_rsp - p_rsp_start; 345 346 /* Send the buffer through L2CAP */ 347 L2CA_DataWrite(p_ccb->connection_id, p_buf); 348 } 349 350 351 352 /******************************************************************************* 353 ** 354 ** Function sdpu_extract_uid_seq 355 ** 356 ** Description This function extracts a UUID sequence from the passed input 357 ** buffer, and puts it into the passed output list. 358 ** 359 ** Returns Pointer to next byte in the input buffer after the sequence. 360 ** 361 *******************************************************************************/ 362 UINT8 *sdpu_extract_uid_seq (UINT8 *p, UINT16 param_len, tSDP_UUID_SEQ *p_seq) 363 { 364 UINT8 *p_seq_end; 365 UINT8 descr, type, size; 366 UINT32 seq_len, uuid_len; 367 368 /* Assume none found */ 369 p_seq->num_uids = 0; 370 371 /* A UID sequence is composed of a bunch of UIDs. */ 372 373 BE_STREAM_TO_UINT8 (descr, p); 374 type = descr >> 3; 375 size = descr & 7; 376 377 if (type != DATA_ELE_SEQ_DESC_TYPE) 378 return (NULL); 379 380 switch (size) 381 { 382 case SIZE_TWO_BYTES: 383 seq_len = 2; 384 break; 385 case SIZE_FOUR_BYTES: 386 seq_len = 4; 387 break; 388 case SIZE_SIXTEEN_BYTES: 389 seq_len = 16; 390 break; 391 case SIZE_IN_NEXT_BYTE: 392 BE_STREAM_TO_UINT8 (seq_len, p); 393 break; 394 case SIZE_IN_NEXT_WORD: 395 BE_STREAM_TO_UINT16 (seq_len, p); 396 break; 397 case SIZE_IN_NEXT_LONG: 398 BE_STREAM_TO_UINT32 (seq_len, p); 399 break; 400 default: 401 return (NULL); 402 } 403 404 if (seq_len >= param_len) 405 return (NULL); 406 407 p_seq_end = p + seq_len; 408 409 /* Loop through, extracting the UIDs */ 410 for ( ; p < p_seq_end ; ) 411 { 412 BE_STREAM_TO_UINT8 (descr, p); 413 type = descr >> 3; 414 size = descr & 7; 415 416 if (type != UUID_DESC_TYPE) 417 return (NULL); 418 419 switch (size) 420 { 421 case SIZE_TWO_BYTES: 422 uuid_len = 2; 423 break; 424 case SIZE_FOUR_BYTES: 425 uuid_len = 4; 426 break; 427 case SIZE_SIXTEEN_BYTES: 428 uuid_len = 16; 429 break; 430 case SIZE_IN_NEXT_BYTE: 431 BE_STREAM_TO_UINT8 (uuid_len, p); 432 break; 433 case SIZE_IN_NEXT_WORD: 434 BE_STREAM_TO_UINT16 (uuid_len, p); 435 break; 436 case SIZE_IN_NEXT_LONG: 437 BE_STREAM_TO_UINT32 (uuid_len, p); 438 break; 439 default: 440 return (NULL); 441 } 442 443 /* If UUID length is valid, copy it across */ 444 if ((uuid_len == 2) || (uuid_len == 4) || (uuid_len == 16)) 445 { 446 p_seq->uuid_entry[p_seq->num_uids].len = (UINT16) uuid_len; 447 BE_STREAM_TO_ARRAY (p, p_seq->uuid_entry[p_seq->num_uids].value, (int)uuid_len); 448 p_seq->num_uids++; 449 } 450 else 451 return (NULL); 452 453 /* We can only do so many */ 454 if (p_seq->num_uids >= MAX_UUIDS_PER_SEQ) 455 return (NULL); 456 } 457 458 if (p != p_seq_end) 459 return (NULL); 460 461 return (p); 462 } 463 464 465 466 /******************************************************************************* 467 ** 468 ** Function sdpu_extract_attr_seq 469 ** 470 ** Description This function extracts an attribute sequence from the passed 471 ** input buffer, and puts it into the passed output list. 472 ** 473 ** Returns Pointer to next byte in the input buffer after the sequence. 474 ** 475 *******************************************************************************/ 476 UINT8 *sdpu_extract_attr_seq (UINT8 *p, UINT16 param_len, tSDP_ATTR_SEQ *p_seq) 477 { 478 UINT8 *p_end_list; 479 UINT8 descr, type, size; 480 UINT32 list_len, attr_len; 481 482 /* Assume none found */ 483 p_seq->num_attr = 0; 484 485 /* Get attribute sequence info */ 486 BE_STREAM_TO_UINT8 (descr, p); 487 type = descr >> 3; 488 size = descr & 7; 489 490 if (type != DATA_ELE_SEQ_DESC_TYPE) 491 return (p); 492 493 switch (size) 494 { 495 case SIZE_IN_NEXT_BYTE: 496 BE_STREAM_TO_UINT8 (list_len, p); 497 break; 498 499 case SIZE_IN_NEXT_WORD: 500 BE_STREAM_TO_UINT16 (list_len, p); 501 break; 502 503 case SIZE_IN_NEXT_LONG: 504 BE_STREAM_TO_UINT32 (list_len, p); 505 break; 506 507 default: 508 return (p); 509 } 510 511 if (list_len > param_len) 512 return (p); 513 514 p_end_list = p + list_len; 515 516 /* Loop through, extracting the attribute IDs */ 517 for ( ; p < p_end_list ; ) 518 { 519 BE_STREAM_TO_UINT8 (descr, p); 520 type = descr >> 3; 521 size = descr & 7; 522 523 if (type != UINT_DESC_TYPE) 524 return (p); 525 526 switch (size) 527 { 528 case SIZE_TWO_BYTES: 529 attr_len = 2; 530 break; 531 case SIZE_FOUR_BYTES: 532 attr_len = 4; 533 break; 534 case SIZE_IN_NEXT_BYTE: 535 BE_STREAM_TO_UINT8 (attr_len, p); 536 break; 537 case SIZE_IN_NEXT_WORD: 538 BE_STREAM_TO_UINT16 (attr_len, p); 539 break; 540 case SIZE_IN_NEXT_LONG: 541 BE_STREAM_TO_UINT32 (attr_len, p); 542 break; 543 default: 544 return (NULL); 545 break; 546 } 547 548 /* Attribute length must be 2-bytes or 4-bytes for a paired entry. */ 549 if (attr_len == 2) 550 { 551 BE_STREAM_TO_UINT16 (p_seq->attr_entry[p_seq->num_attr].start, p); 552 p_seq->attr_entry[p_seq->num_attr].end = p_seq->attr_entry[p_seq->num_attr].start; 553 } 554 else if (attr_len == 4) 555 { 556 BE_STREAM_TO_UINT16 (p_seq->attr_entry[p_seq->num_attr].start, p); 557 BE_STREAM_TO_UINT16 (p_seq->attr_entry[p_seq->num_attr].end, p); 558 } 559 else 560 return (NULL); 561 562 /* We can only do so many */ 563 if (++p_seq->num_attr >= MAX_ATTR_PER_SEQ) 564 return (NULL); 565 } 566 567 return (p); 568 } 569 570 571 /******************************************************************************* 572 ** 573 ** Function sdpu_get_len_from_type 574 ** 575 ** Description This function gets the length 576 ** 577 ** Returns void 578 ** 579 *******************************************************************************/ 580 UINT8 *sdpu_get_len_from_type (UINT8 *p, UINT8 type, UINT32 *p_len) 581 { 582 UINT8 u8; 583 UINT16 u16; 584 UINT32 u32; 585 586 switch (type & 7) 587 { 588 case SIZE_ONE_BYTE: 589 *p_len = 1; 590 break; 591 case SIZE_TWO_BYTES: 592 *p_len = 2; 593 break; 594 case SIZE_FOUR_BYTES: 595 *p_len = 4; 596 break; 597 case SIZE_EIGHT_BYTES: 598 *p_len = 8; 599 break; 600 case SIZE_SIXTEEN_BYTES: 601 *p_len = 16; 602 break; 603 case SIZE_IN_NEXT_BYTE: 604 BE_STREAM_TO_UINT8 (u8, p); 605 *p_len = u8; 606 break; 607 case SIZE_IN_NEXT_WORD: 608 BE_STREAM_TO_UINT16 (u16, p); 609 *p_len = u16; 610 break; 611 case SIZE_IN_NEXT_LONG: 612 BE_STREAM_TO_UINT32 (u32, p); 613 *p_len = (UINT16) u32; 614 break; 615 } 616 617 return (p); 618 } 619 620 621 /******************************************************************************* 622 ** 623 ** Function sdpu_is_base_uuid 624 ** 625 ** Description This function checks a 128-bit UUID with the base to see if 626 ** it matches. Only the last 12 bytes are compared. 627 ** 628 ** Returns TRUE if matched, else FALSE 629 ** 630 *******************************************************************************/ 631 BOOLEAN sdpu_is_base_uuid (UINT8 *p_uuid) 632 { 633 UINT16 xx; 634 635 for (xx = 4; xx < MAX_UUID_SIZE; xx++) 636 if (p_uuid[xx] != sdp_base_uuid[xx]) 637 return (FALSE); 638 639 /* If here, matched */ 640 return (TRUE); 641 } 642 643 644 /******************************************************************************* 645 ** 646 ** Function sdpu_compare_uuid_arrays 647 ** 648 ** Description This function compares 2 BE UUIDs. If needed, they are expanded 649 ** to 128-bit UUIDs, then compared. 650 ** 651 ** NOTE it is assumed that the arrays are in Big Endian format 652 ** 653 ** Returns TRUE if matched, else FALSE 654 ** 655 *******************************************************************************/ 656 BOOLEAN sdpu_compare_uuid_arrays (UINT8 *p_uuid1, UINT32 len1, UINT8 *p_uuid2, UINT16 len2) 657 { 658 UINT8 nu1[MAX_UUID_SIZE]; 659 UINT8 nu2[MAX_UUID_SIZE]; 660 661 if( ((len1 != 2) && (len1 != 4) && (len1 != 16)) || 662 ((len2 != 2) && (len2 != 4) && (len2 != 16)) ) 663 { 664 SDP_TRACE_ERROR("%s: invalid length", __func__); 665 return FALSE; 666 } 667 668 /* If lengths match, do a straight compare */ 669 if (len1 == len2) 670 { 671 if (len1 == 2) 672 return ((p_uuid1[0] == p_uuid2[0]) && (p_uuid1[1] == p_uuid2[1])); 673 if (len1 == 4) 674 return ( (p_uuid1[0] == p_uuid2[0]) && (p_uuid1[1] == p_uuid2[1]) 675 && (p_uuid1[2] == p_uuid2[2]) && (p_uuid1[3] == p_uuid2[3]) ); 676 else 677 return (memcmp (p_uuid1, p_uuid2, (size_t)len1) == 0); 678 } 679 else if (len1 > len2) 680 { 681 /* If the len1 was 4-byte, (so len2 is 2-byte), compare on the fly */ 682 if (len1 == 4) 683 { 684 return ( (p_uuid1[0] == 0) && (p_uuid1[1] == 0) 685 && (p_uuid1[2] == p_uuid2[0]) && (p_uuid1[3] == p_uuid2[1]) ); 686 } 687 else 688 { 689 /* Normalize UUIDs to 16-byte form, then compare. Len1 must be 16 */ 690 memcpy (nu1, p_uuid1, MAX_UUID_SIZE); 691 memcpy (nu2, sdp_base_uuid, MAX_UUID_SIZE); 692 693 if (len2 == 4) 694 memcpy (nu2, p_uuid2, len2); 695 else if (len2 == 2) 696 memcpy (nu2 + 2, p_uuid2, len2); 697 698 return (memcmp (nu1, nu2, MAX_UUID_SIZE) == 0); 699 } 700 } 701 else 702 { 703 /* len2 is greater than len1 */ 704 /* If the len2 was 4-byte, (so len1 is 2-byte), compare on the fly */ 705 if (len2 == 4) 706 { 707 return ( (p_uuid2[0] == 0) && (p_uuid2[1] == 0) 708 && (p_uuid2[2] == p_uuid1[0]) && (p_uuid2[3] == p_uuid1[1]) ); 709 } 710 else 711 { 712 /* Normalize UUIDs to 16-byte form, then compare. Len1 must be 16 */ 713 memcpy (nu2, p_uuid2, MAX_UUID_SIZE); 714 memcpy (nu1, sdp_base_uuid, MAX_UUID_SIZE); 715 716 if (len1 == 4) 717 memcpy (nu1, p_uuid1, (size_t)len1); 718 else if (len1 == 2) 719 memcpy (nu1 + 2, p_uuid1, (size_t)len1); 720 721 return (memcmp (nu1, nu2, MAX_UUID_SIZE) == 0); 722 } 723 } 724 } 725 726 727 /******************************************************************************* 728 ** 729 ** Function sdpu_compare_bt_uuids 730 ** 731 ** Description This function compares 2 BT UUID structures. 732 ** 733 ** NOTE it is assumed that BT UUID structures are compressed to the 734 ** smallest possible UUIDs (by removing the base SDP UUID) 735 ** 736 ** Returns TRUE if matched, else FALSE 737 ** 738 *******************************************************************************/ 739 BOOLEAN sdpu_compare_bt_uuids (tBT_UUID *p_uuid1, tBT_UUID *p_uuid2) 740 { 741 /* Lengths must match for BT UUIDs to match */ 742 if (p_uuid1->len == p_uuid2->len) 743 { 744 if (p_uuid1->len == 2) 745 return (p_uuid1->uu.uuid16 == p_uuid2->uu.uuid16); 746 else if (p_uuid1->len == 4) 747 return (p_uuid1->uu.uuid32 == p_uuid2->uu.uuid32); 748 else if (!memcmp (p_uuid1->uu.uuid128, p_uuid2->uu.uuid128, 16)) 749 return (TRUE); 750 } 751 752 return (FALSE); 753 } 754 755 756 /******************************************************************************* 757 ** 758 ** Function sdpu_compare_uuid_with_attr 759 ** 760 ** Description This function compares a BT UUID structure with the UUID in an 761 ** SDP attribute record. If needed, they are expanded to 128-bit 762 ** UUIDs, then compared. 763 ** 764 ** NOTE - it is assumed that BT UUID structures are compressed to the 765 ** smallest possible UUIDs (by removing the base SDP UUID). 766 ** - it is also assumed that the discovery atribute is compressed 767 ** to the smallest possible 768 ** 769 ** Returns TRUE if matched, else FALSE 770 ** 771 *******************************************************************************/ 772 BOOLEAN sdpu_compare_uuid_with_attr (tBT_UUID *p_btuuid, tSDP_DISC_ATTR *p_attr) 773 { 774 UINT16 attr_len = SDP_DISC_ATTR_LEN (p_attr->attr_len_type); 775 776 /* Since both UUIDs are compressed, lengths must match */ 777 if (p_btuuid->len != attr_len) 778 return (FALSE); 779 780 if (p_btuuid->len == 2) 781 return (BOOLEAN)(p_btuuid->uu.uuid16 == p_attr->attr_value.v.u16); 782 else if (p_btuuid->len == 4) 783 return (BOOLEAN)(p_btuuid->uu.uuid32 == p_attr->attr_value.v.u32); 784 /* coverity[overrun-buffer-arg] */ 785 /* 786 Event overrun-buffer-arg: Overrun of static array "&p_attr->attr_value.v.array" of size 4 bytes by passing it to a function which indexes it with argument "16U" at byte position 15 787 FALSE-POSITIVE error from Coverity test tool. Please do NOT remove following comment. 788 False-positive: SDP uses scratch buffer to hold the attribute value. 789 The actual size of tSDP_DISC_ATVAL does not matter. 790 If the array size in tSDP_DISC_ATVAL is increase, we would increase the system RAM usage unnecessarily 791 */ 792 else if (!memcmp (p_btuuid->uu.uuid128,(void*) p_attr->attr_value.v.array, MAX_UUID_SIZE)) 793 return (TRUE); 794 795 return (FALSE); 796 } 797 798 /******************************************************************************* 799 ** 800 ** Function sdpu_sort_attr_list 801 ** 802 ** Description sorts a list of attributes in numeric order from lowest to 803 ** highest to conform to SDP specification 804 ** 805 ** Returns void 806 ** 807 *******************************************************************************/ 808 void sdpu_sort_attr_list( UINT16 num_attr, tSDP_DISCOVERY_DB *p_db ) 809 { 810 UINT16 i; 811 UINT16 x; 812 813 /* Done if no attributes to sort */ 814 if (num_attr <= 1) 815 { 816 return; 817 } 818 else if (num_attr > SDP_MAX_ATTR_FILTERS) 819 { 820 num_attr = SDP_MAX_ATTR_FILTERS; 821 } 822 823 num_attr--; /* for the for-loop */ 824 for( i = 0; i < num_attr; ) 825 { 826 if( p_db->attr_filters[i] > p_db->attr_filters[i+1] ) 827 { 828 /* swap the attribute IDs and start from the beginning */ 829 x = p_db->attr_filters[i]; 830 p_db->attr_filters[i] = p_db->attr_filters[i+1]; 831 p_db->attr_filters[i+1] = x; 832 833 i = 0; 834 } 835 else 836 i++; 837 } 838 } 839 840 841 /******************************************************************************* 842 ** 843 ** Function sdpu_get_list_len 844 ** 845 ** Description gets the total list length in the sdp database for a given 846 ** uid sequence and attr sequence 847 ** 848 ** Returns void 849 ** 850 *******************************************************************************/ 851 UINT16 sdpu_get_list_len(tSDP_UUID_SEQ *uid_seq, tSDP_ATTR_SEQ *attr_seq) 852 { 853 tSDP_RECORD *p_rec; 854 UINT16 len = 0; 855 UINT16 len1; 856 857 for (p_rec = sdp_db_service_search (NULL, uid_seq); p_rec; p_rec = sdp_db_service_search (p_rec, uid_seq)) 858 { 859 len += 3; 860 861 len1 = sdpu_get_attrib_seq_len(p_rec, attr_seq ); 862 863 if (len1 != 0) 864 len += len1; 865 else 866 len -= 3; 867 } 868 return len; 869 } 870 871 /******************************************************************************* 872 ** 873 ** Function sdpu_get_attrib_seq_len 874 ** 875 ** Description gets the length of the specific attributes in a given 876 ** sdp record 877 ** 878 ** Returns void 879 ** 880 *******************************************************************************/ 881 UINT16 sdpu_get_attrib_seq_len(tSDP_RECORD *p_rec, tSDP_ATTR_SEQ *attr_seq) 882 { 883 tSDP_ATTRIBUTE *p_attr; 884 UINT16 len1 = 0; 885 UINT16 xx; 886 BOOLEAN is_range = FALSE; 887 UINT16 start_id=0, end_id=0; 888 889 for (xx = 0; xx < attr_seq->num_attr; xx++) 890 { 891 if (is_range == FALSE) 892 { 893 start_id = attr_seq->attr_entry[xx].start; 894 end_id = attr_seq->attr_entry[xx].end; 895 } 896 p_attr = sdp_db_find_attr_in_rec (p_rec, 897 start_id, 898 end_id); 899 if (p_attr) 900 { 901 len1 += sdpu_get_attrib_entry_len (p_attr); 902 903 /* If doing a range, stick with this one till no more attributes found */ 904 if (start_id != end_id) 905 { 906 /* Update for next time through */ 907 start_id = p_attr->id + 1; 908 xx--; 909 is_range = TRUE; 910 } 911 else 912 is_range = FALSE; 913 } 914 else 915 is_range = FALSE; 916 } 917 return len1; 918 } 919 920 /******************************************************************************* 921 ** 922 ** Function sdpu_get_attrib_entry_len 923 ** 924 ** Description gets the length of a specific attribute 925 ** 926 ** Returns void 927 ** 928 *******************************************************************************/ 929 UINT16 sdpu_get_attrib_entry_len(tSDP_ATTRIBUTE *p_attr) 930 { 931 UINT16 len = 3; 932 933 /* the attribute is in the db record. 934 * assuming the attribute len is less than SDP_MAX_ATTR_LEN */ 935 switch(p_attr->type) 936 { 937 case TEXT_STR_DESC_TYPE: /* 4 */ 938 case DATA_ELE_SEQ_DESC_TYPE:/* 6 */ 939 case DATA_ELE_ALT_DESC_TYPE:/* 7 */ 940 case URL_DESC_TYPE: /* 8 */ 941 #if (SDP_MAX_ATTR_LEN > 0xFFFF) 942 if(p_attr->len > 0xFFFF) 943 { 944 len += 5; 945 } 946 else 947 948 #endif/* 0xFFFF - 0xFF */ 949 #if (SDP_MAX_ATTR_LEN > 0xFF) 950 if(p_attr->len > 0xFF) 951 { 952 len += 3; 953 } 954 else 955 956 #endif /* 0xFF and less*/ 957 { 958 len += 2; 959 } 960 len += p_attr->len; 961 return len; 962 } 963 964 /* Now, the attribute value */ 965 switch (p_attr->len) 966 { 967 case 1: 968 case 2: 969 case 4: 970 case 8: 971 case 16: 972 len += 1; 973 break; 974 default: 975 len += 2; 976 break; 977 } 978 979 len += p_attr->len; 980 return len; 981 } 982 983 984 /******************************************************************************* 985 ** 986 ** Function sdpu_build_partial_attrib_entry 987 ** 988 ** Description This function fills a buffer with partial attribute. It is 989 ** assumed that the maximum size of any attribute is 256 bytes. 990 ** 991 ** p_out: output buffer 992 ** p_attr: attribute to be copied partially into p_out 993 ** rem_len: num bytes to copy into p_out 994 ** offset: current start offset within the attr that needs to be copied 995 ** 996 ** Returns Pointer to next byte in the output buffer. 997 ** offset is also updated 998 ** 999 *******************************************************************************/ 1000 UINT8 *sdpu_build_partial_attrib_entry (UINT8 *p_out, tSDP_ATTRIBUTE *p_attr, UINT16 len, UINT16 *offset) 1001 { 1002 UINT8 *p_attr_buff = (UINT8 *)osi_malloc(sizeof(UINT8) * SDP_MAX_ATTR_LEN); 1003 sdpu_build_attrib_entry(p_attr_buff, p_attr); 1004 1005 UINT16 attr_len = sdpu_get_attrib_entry_len(p_attr); 1006 1007 if (len > SDP_MAX_ATTR_LEN) 1008 { 1009 SDP_TRACE_ERROR("%s len %d exceeds SDP_MAX_ATTR_LEN", __func__, len); 1010 len = SDP_MAX_ATTR_LEN; 1011 } 1012 1013 size_t len_to_copy = ((attr_len - *offset) < len) ? (attr_len - *offset) : len; 1014 memcpy(p_out, &p_attr_buff[*offset], len_to_copy); 1015 1016 p_out = &p_out[len_to_copy]; 1017 *offset += len_to_copy; 1018 1019 osi_free(p_attr_buff); 1020 return p_out; 1021 } 1022 1023 /******************************************************************************* 1024 ** 1025 ** Function sdpu_uuid16_to_uuid128 1026 ** 1027 ** Description This function converts UUID-16 to UUID-128 by including the base UUID 1028 ** 1029 ** uuid16: 2-byte UUID 1030 ** p_uuid128: Expanded 128-bit UUID 1031 ** 1032 ** Returns None 1033 ** 1034 *******************************************************************************/ 1035 void sdpu_uuid16_to_uuid128(UINT16 uuid16, UINT8* p_uuid128) 1036 { 1037 UINT16 uuid16_bo; 1038 memset(p_uuid128, 0, 16); 1039 1040 memcpy(p_uuid128, sdp_base_uuid, MAX_UUID_SIZE); 1041 uuid16_bo = ntohs(uuid16); 1042 memcpy(p_uuid128+ 2, &uuid16_bo, sizeof(uint16_t)); 1043 } 1044