Home | History | Annotate | Download | only in sdp
      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