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 "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 
     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 
    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 *******************************************************************************/
    145 void 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 *******************************************************************************/
    178 UINT8 *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 *******************************************************************************/
    232 UINT8 *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 *******************************************************************************/
    317 void 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 *******************************************************************************/
    373 UINT8 *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 *******************************************************************************/
    487 UINT8 *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 *******************************************************************************/
    591 UINT8 *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 *******************************************************************************/
    642 BOOLEAN 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 *******************************************************************************/
    667 BOOLEAN 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 *******************************************************************************/
    750 BOOLEAN 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 *******************************************************************************/
    783 BOOLEAN 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 *******************************************************************************/
    819 void 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 *******************************************************************************/
    862 UINT16 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 *******************************************************************************/
    892 UINT16 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 *******************************************************************************/
    940 UINT16 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 *******************************************************************************/
   1011 UINT8 *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 *******************************************************************************/
   1051 void 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