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