Home | History | Annotate | Download | only in sdp
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2014 The Android Open Source Project
      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  *  This file contains action functions for SDP search.
     21  ******************************************************************************/
     22 
     23 #include <hardware/bluetooth.h>
     24 #include <hardware/bt_sdp.h>
     25 #include <arpa/inet.h>
     26 #include <stdlib.h>
     27 #include <string.h>
     28 
     29 #include "osi/include/allocator.h"
     30 #include "bt_types.h"
     31 #include "gki.h"
     32 #include "utl.h"
     33 #include "bta_sys.h"
     34 #include "bta_api.h"
     35 #include "bta_sdp_api.h"
     36 #include "bta_sdp_int.h"
     37 #include "btm_api.h"
     38 #include "btm_int.h"
     39 #include "sdp_api.h"
     40 
     41 /*****************************************************************************
     42 **  Constants
     43 *****************************************************************************/
     44 
     45 static const uint8_t  UUID_OBEX_OBJECT_PUSH[] = {0x00, 0x00, 0x11, 0x05, 0x00, 0x00, 0x10, 0x00,
     46                                                  0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
     47 static const uint8_t  UUID_PBAP_PSE[] = {0x00, 0x00, 0x11, 0x2F, 0x00, 0x00, 0x10, 0x00,
     48                                          0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
     49 static const uint8_t  UUID_MAP_MAS[] = {0x00, 0x00, 0x11, 0x32, 0x00, 0x00, 0x10, 0x00,
     50                                         0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
     51 static const uint8_t  UUID_MAP_MNS[] = {0x00, 0x00, 0x11, 0x33, 0x00, 0x00, 0x10, 0x00,
     52                                         0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
     53 static const uint8_t  UUID_SPP[] = {0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x10, 0x00,
     54                                     0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
     55 static const uint8_t  UUID_SAP[] = {0x00, 0x00, 0x11, 0x2D, 0x00, 0x00, 0x10, 0x00,
     56                                     0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
     57 // TODO:
     58 // Both the fact that the UUIDs are declared in multiple places, plus the fact
     59 // that there is a mess of UUID comparison and shortening methods will have to
     60 // be fixed.
     61 // The btcore->uuid module should be used for all instances.
     62 
     63 #define UUID_MAX_LENGTH 16
     64 #define IS_UUID(u1,u2)  !memcmp(u1,u2,UUID_MAX_LENGTH)
     65 
     66 static inline tBT_UUID shorten_sdp_uuid(const tBT_UUID* u)
     67 {
     68     static uint8_t bt_base_uuid[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
     69                                      0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB };
     70 
     71     APPL_TRACE_DEBUG("%s() - uuid len:%d", __func__, u->len);
     72     if(u->len != 16)
     73         return *u;
     74 
     75     if(memcmp(&u->uu.uuid128[4], &bt_base_uuid[4], 12) != 0)
     76         return *u;
     77 
     78     tBT_UUID su;
     79     memset(&su, 0, sizeof(su));
     80     if(u->uu.uuid128[0] == 0 && u->uu.uuid128[1] == 0)
     81     {
     82         su.len = 2;
     83         uint16_t u16;
     84         memcpy(&u16, &u->uu.uuid128[2], sizeof(u16));
     85         su.uu.uuid16 = ntohs(u16);
     86     } else {
     87         su.len = 4;
     88         uint32_t u32;
     89         memcpy(&u32, &u->uu.uuid128[0], sizeof(u32));
     90         su.uu.uuid32 = ntohl(u32);
     91     }
     92     return su;
     93 }
     94 
     95 static void bta_create_mns_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
     96 {
     97     tSDP_DISCOVERY_DB *db = p_bta_sdp_cfg->p_sdp_db;
     98     tSDP_DISC_ATTR *p_attr;
     99     tSDP_PROTOCOL_ELEM pe;
    100     UINT16 pversion = 0;
    101     UINT8 offset = 0;
    102     record->mns.hdr.type = SDP_TYPE_MAP_MNS;
    103     record->mns.hdr.service_name_length = 0;
    104     record->mns.hdr.service_name = NULL;
    105     record->mns.hdr.rfcomm_channel_number = 0;
    106     record->mns.hdr.l2cap_psm = -1;
    107     record->mns.hdr.profile_version = 0;
    108     record->mns.supported_features = 0x0000001F; //default value if not found
    109 
    110     if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_MAP_SUPPORTED_FEATURES)) != NULL)
    111     {
    112         record->mns.supported_features = p_attr->attr_value.v.u32;
    113     }
    114 
    115     if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME)) != NULL)
    116     {
    117         record->mns.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
    118         record->mns.hdr.service_name = (char *)p_attr->attr_value.v.array;
    119     }
    120 
    121     if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_MAP_PROFILE, &pversion))
    122     {
    123         record->mns.hdr.profile_version = pversion;
    124     }
    125 
    126     if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe))
    127     {
    128         record->mns.hdr.rfcomm_channel_number = pe.params[0];
    129     }
    130 
    131     if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM)) != NULL)
    132     {
    133         record->mns.hdr.l2cap_psm = p_attr->attr_value.v.u16;
    134     }
    135 }
    136 
    137 static void bta_create_mas_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
    138 {
    139     tSDP_DISCOVERY_DB *db = p_bta_sdp_cfg->p_sdp_db;
    140     tSDP_DISC_ATTR *p_attr;
    141     tSDP_PROTOCOL_ELEM pe;
    142     UINT16 pversion = -1;
    143 
    144     record->mas.hdr.type = SDP_TYPE_MAP_MAS;
    145     record->mas.hdr.service_name_length = 0;
    146     record->mas.hdr.service_name = NULL;
    147     record->mas.hdr.rfcomm_channel_number = 0;
    148     record->mas.hdr.l2cap_psm = -1;
    149     record->mas.hdr.profile_version = 0;
    150     record->mas.mas_instance_id = 0;
    151     record->mas.supported_features = 0x0000001F;
    152     record->mas.supported_message_types = 0;
    153 
    154     if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_MAS_INSTANCE_ID)) != NULL)
    155     {
    156         record->mas.mas_instance_id = p_attr->attr_value.v.u8;
    157     }
    158 
    159     if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_MSG_TYPE)) != NULL)
    160     {
    161         record->mas.supported_message_types = p_attr->attr_value.v.u8;
    162     }
    163 
    164     if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_MAP_SUPPORTED_FEATURES)) != NULL)
    165     {
    166         record->mas.supported_features = p_attr->attr_value.v.u32;
    167     }
    168 
    169     if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME)) != NULL)
    170     {
    171         record->mas.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
    172         record->mas.hdr.service_name = (char *)p_attr->attr_value.v.array;
    173     }
    174 
    175     if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_MAP_PROFILE, &pversion))
    176     {
    177         record->mas.hdr.profile_version = pversion;
    178     }
    179 
    180     if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe))
    181     {
    182         record->mas.hdr.rfcomm_channel_number = pe.params[0];
    183     }
    184 
    185     if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM)) != NULL)
    186     {
    187         record->mas.hdr.l2cap_psm = p_attr->attr_value.v.u16;
    188     }
    189 }
    190 
    191 static void bta_create_pse_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
    192 {
    193     tSDP_DISCOVERY_DB *db = p_bta_sdp_cfg->p_sdp_db;
    194     tSDP_DISC_ATTR *p_attr;
    195     UINT16 pversion;
    196     tSDP_PROTOCOL_ELEM pe;
    197 
    198     record->pse.hdr.type = SDP_TYPE_PBAP_PSE;
    199     record->pse.hdr.service_name_length = 0;
    200     record->pse.hdr.service_name = NULL;
    201     record->pse.hdr.rfcomm_channel_number = 0;
    202     record->pse.hdr.l2cap_psm = -1;
    203     record->pse.hdr.profile_version = 0;
    204     record->pse.supported_features = 0x00000003;
    205     record->pse.supported_repositories = 0;
    206 
    207     if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_REPOSITORIES)) != NULL)
    208     {
    209         record->pse.supported_repositories = p_attr->attr_value.v.u8;
    210     }
    211     if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PBAP_SUPPORTED_FEATURES)) != NULL)
    212     {
    213         record->pse.supported_features = p_attr->attr_value.v.u32;
    214     }
    215 
    216     if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME)) != NULL)
    217     {
    218         record->pse.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
    219         record->pse.hdr.service_name = (char *)p_attr->attr_value.v.array;
    220     }
    221 
    222     if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_PHONE_ACCESS, &pversion))
    223     {
    224         record->pse.hdr.profile_version = pversion;
    225     }
    226 
    227     if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe))
    228     {
    229         record->pse.hdr.rfcomm_channel_number = pe.params[0];
    230     }
    231 
    232     if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM)) != NULL)
    233     {
    234         record->pse.hdr.l2cap_psm = p_attr->attr_value.v.u16;
    235     }
    236 }
    237 
    238 static void bta_create_ops_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
    239 {
    240     tSDP_DISCOVERY_DB *db = p_bta_sdp_cfg->p_sdp_db;
    241     tSDP_DISC_ATTR *p_attr, *p_sattr;
    242     tSDP_PROTOCOL_ELEM pe;
    243     UINT16 pversion = -1;
    244 
    245     record->ops.hdr.type = SDP_TYPE_OPP_SERVER;
    246     record->ops.hdr.service_name_length = 0;
    247     record->ops.hdr.service_name = NULL;
    248     record->ops.hdr.rfcomm_channel_number = 0;
    249     record->ops.hdr.l2cap_psm = -1;
    250     record->ops.hdr.profile_version = 0;
    251     record->ops.supported_formats_list_len = 0;
    252 
    253     if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME)) != NULL)
    254     {
    255         record->ops.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
    256         record->ops.hdr.service_name = (char *)p_attr->attr_value.v.array;
    257     }
    258 
    259     if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_OBEX_OBJECT_PUSH, &pversion))
    260     {
    261         record->ops.hdr.profile_version = pversion;
    262     }
    263 
    264     if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe))
    265     {
    266         record->ops.hdr.rfcomm_channel_number = pe.params[0];
    267     }
    268 
    269     if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM)) != NULL)
    270     {
    271         record->ops.hdr.l2cap_psm = p_attr->attr_value.v.u16;
    272     }
    273     if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_FORMATS_LIST)) != NULL)
    274     {
    275         /* Safety check - each entry should itself be a sequence */
    276         if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE) {
    277             record->ops.supported_formats_list_len = 0;
    278             APPL_TRACE_ERROR("%s() - supported_formats_list - wrong attribute length/type:"
    279                     " 0x%02x - expected 0x06", __func__, p_attr->attr_len_type);
    280         } else {
    281             int count = 0;
    282             /* 1 byte for type/length 1 byte for value */
    283             record->ops.supported_formats_list_len = SDP_DISC_ATTR_LEN(p_attr->attr_len_type)/2;
    284 
    285             /* Extract each value into */
    286             for (p_sattr = p_attr->attr_value.v.p_sub_attr;
    287                     p_sattr != NULL; p_sattr = p_sattr->p_next_attr)
    288             {
    289                 if ((SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) == UINT_DESC_TYPE)
    290                     && (SDP_DISC_ATTR_LEN(p_sattr->attr_len_type) == 1))
    291                 {
    292                     if (count == sizeof(record->ops.supported_formats_list)) {
    293                         APPL_TRACE_ERROR("%s() - supported_formats_list - count overflow - "
    294                                 "too many sub attributes!!", __func__);
    295                         /* If you hit this, new formats have been added,
    296                          * update SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH */
    297                         break;
    298                     }
    299                     record->ops.supported_formats_list[count] = p_sattr->attr_value.v.u8;
    300                     count++;
    301                 } else {
    302                     APPL_TRACE_ERROR("%s() - supported_formats_list - wrong sub attribute "
    303                                 "length/type: 0x%02x - expected 0x80", __func__,
    304                                 p_sattr->attr_len_type);
    305                     break;
    306                 }
    307             }
    308             if (record->ops.supported_formats_list_len != count) {
    309                 APPL_TRACE_WARNING("%s() - supported_formats_list - Length of attribute different "
    310                         "from the actual number of sub-attributes in the sequence "
    311                         "att-length: %d - number of elements: %d", __func__,
    312                         record->ops.supported_formats_list_len , count);
    313 
    314             }
    315             record->ops.supported_formats_list_len = count;
    316         }
    317     }
    318 }
    319 
    320 static void bta_create_sap_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
    321 {
    322     tSDP_DISCOVERY_DB *db = p_bta_sdp_cfg->p_sdp_db;
    323     tSDP_DISC_ATTR *p_attr;
    324     tSDP_PROTOCOL_ELEM pe;
    325     UINT16 pversion = -1;
    326 
    327     record->sap.hdr.type = SDP_TYPE_MAP_MAS;
    328     record->sap.hdr.service_name_length = 0;
    329     record->sap.hdr.service_name = NULL;
    330     record->sap.hdr.rfcomm_channel_number = 0;
    331     record->sap.hdr.l2cap_psm = -1;
    332     record->sap.hdr.profile_version = 0;
    333 
    334     if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME)) != NULL)
    335     {
    336         record->sap.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
    337         record->sap.hdr.service_name = (char *)p_attr->attr_value.v.array;
    338     }
    339 
    340     if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_SAP, &pversion))
    341     {
    342         record->sap.hdr.profile_version = pversion;
    343     }
    344 
    345     if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe))
    346     {
    347         record->sap.hdr.rfcomm_channel_number = pe.params[0];
    348     }
    349 }
    350 
    351 static void bta_create_raw_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
    352 {
    353     tSDP_DISCOVERY_DB *db = p_bta_sdp_cfg->p_sdp_db;
    354     tSDP_DISC_ATTR *p_attr;
    355     UINT16 pversion;
    356     tSDP_PROTOCOL_ELEM pe;
    357 
    358     record->hdr.type = SDP_TYPE_RAW;
    359     record->hdr.service_name_length = 0;
    360     record->hdr.service_name = NULL;
    361     record->hdr.rfcomm_channel_number = -1;
    362     record->hdr.l2cap_psm = -1;
    363     record->hdr.profile_version = -1;
    364 
    365     /* Try to extract a service name */
    366     if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME)) != NULL)
    367     {
    368         record->pse.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
    369         record->pse.hdr.service_name = (char *)p_attr->attr_value.v.array;
    370     }
    371 
    372     /* Try to extract an RFCOMM channel */
    373     if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe))
    374     {
    375         record->pse.hdr.rfcomm_channel_number = pe.params[0];
    376     }
    377     record->hdr.user1_ptr_len = p_bta_sdp_cfg->p_sdp_db->raw_size;
    378     record->hdr.user1_ptr = p_bta_sdp_cfg->p_sdp_db->raw_data;
    379 }
    380 
    381 
    382 /*******************************************************************************
    383 **
    384 ** Function     bta_sdp_search_cback
    385 **
    386 ** Description  Callback from btm after search is completed
    387 **
    388 ** Returns      void
    389 **
    390 *******************************************************************************/
    391 static void bta_sdp_search_cback(UINT16 result, void * user_data)
    392 {
    393     tSDP_DISC_REC *p_rec = NULL;
    394     tBTA_SDP_SEARCH_COMP evt_data = {0}; // We need to zero-initialize
    395     tBTA_SDP_STATUS status = BTA_SDP_FAILURE;
    396     UINT16 uuid16 = 0;
    397     int count = 0;
    398     tBT_UUID su;
    399     APPL_TRACE_DEBUG("%s() -  res: 0x%x", __func__, result);
    400 
    401     bta_sdp_cb.sdp_active = BTA_SDP_ACTIVE_NONE;
    402 
    403     if (bta_sdp_cb.p_dm_cback == NULL) return;
    404 
    405     bdcpy(evt_data.remote_addr, bta_sdp_cb.remote_addr);
    406     tBT_UUID *uuid = (tBT_UUID*)user_data;
    407     memcpy(&evt_data.uuid, uuid, sizeof(tBT_UUID));
    408     su = shorten_sdp_uuid(uuid);
    409 
    410     if (result == SDP_SUCCESS || result == SDP_DB_FULL)
    411     {
    412         do {
    413             p_rec = SDP_FindServiceUUIDInDb(p_bta_sdp_cfg->p_sdp_db, &su, p_rec);
    414             /* generate the matching record data pointer */
    415             if(p_rec != NULL){
    416                 status = BTA_SDP_SUCCESS;
    417                 if (IS_UUID(UUID_MAP_MAS,uuid->uu.uuid128)) {
    418                     APPL_TRACE_DEBUG("%s() - found MAP (MAS) uuid", __func__);
    419                     bta_create_mas_sdp_record(&evt_data.records[count], p_rec);
    420                 } else if (IS_UUID(UUID_MAP_MNS,uuid->uu.uuid128)) {
    421                     APPL_TRACE_DEBUG("%s() - found MAP (MNS) uuid", __func__);
    422                     bta_create_mns_sdp_record(&evt_data.records[count], p_rec);
    423                 } else if (IS_UUID(UUID_PBAP_PSE,uuid->uu.uuid128)){
    424                     APPL_TRACE_DEBUG("%s() - found PBAP (PSE) uuid", __func__);
    425                     bta_create_pse_sdp_record(&evt_data.records[count], p_rec);
    426                 } else if (IS_UUID(UUID_OBEX_OBJECT_PUSH,uuid->uu.uuid128)){
    427                     APPL_TRACE_DEBUG("%s() - found Object Push Server (OPS) uuid", __func__);
    428                     bta_create_ops_sdp_record(&evt_data.records[count], p_rec);
    429                 } else if (IS_UUID(UUID_SAP,uuid->uu.uuid128)) {
    430                     APPL_TRACE_DEBUG("%s() - found SAP uuid", __func__);
    431                     bta_create_sap_sdp_record(&evt_data.records[count], p_rec);
    432                 } else {
    433 
    434                     /* we do not have specific structure for this */
    435                     APPL_TRACE_DEBUG("%s() - profile not identified. using raw data", __func__);
    436                     bta_create_raw_sdp_record(&evt_data.records[count], p_rec);
    437                     p_rec = NULL; // Terminate loop
    438                     /* For raw, we only extract the first entry, and then return the entire
    439                        raw data chunk.
    440                        TODO: Find a way to split the raw data into record chunks, and iterate
    441                              to extract generic data for each chunk - e.g. rfcomm channel and
    442                              service name. */
    443                 }
    444                 count++;
    445             } else {
    446                 APPL_TRACE_DEBUG("%s() - UUID not found", __func__);
    447             }
    448         } while (p_rec != NULL && count < BTA_SDP_MAX_RECORDS);
    449 
    450         evt_data.record_count = count;
    451     }
    452     evt_data.status = status;
    453 
    454     bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, (tBTA_SDP*) &evt_data, (void*)&uuid->uu.uuid128);
    455     osi_free(user_data); // We no longer need the user data to track the search
    456 }
    457 
    458 /*******************************************************************************
    459 **
    460 ** Function     bta_sdp_enable
    461 **
    462 ** Description  Initializes the SDP I/F
    463 **
    464 ** Returns      void
    465 **
    466 *******************************************************************************/
    467 void bta_sdp_enable(tBTA_SDP_MSG *p_data)
    468 {
    469     APPL_TRACE_DEBUG("%s in, sdp_active:%d", __func__, bta_sdp_cb.sdp_active);
    470     tBTA_SDP_STATUS status = BTA_SDP_SUCCESS;
    471     bta_sdp_cb.p_dm_cback = p_data->enable.p_cback;
    472     bta_sdp_cb.p_dm_cback(BTA_SDP_ENABLE_EVT, (tBTA_SDP *)&status, NULL);
    473 }
    474 
    475 /*******************************************************************************
    476 **
    477 ** Function     bta_sdp_search
    478 **
    479 ** Description  Discovers all sdp records for an uuid on remote device
    480 **
    481 ** Returns      void
    482 **
    483 *******************************************************************************/
    484 void bta_sdp_search(tBTA_SDP_MSG *p_data)
    485 {
    486     int x=0;
    487     // TODO: Leaks!!! but needed as user-data pointer
    488     tBT_UUID *bta_sdp_search_uuid = osi_malloc(sizeof(tBT_UUID));
    489     if(p_data == NULL)
    490     {
    491         APPL_TRACE_DEBUG("SDP control block handle is null");
    492         return;
    493     }
    494     tBTA_SDP_STATUS status = BTA_SDP_FAILURE;
    495 
    496     APPL_TRACE_DEBUG("%s in, sdp_active:%d", __func__, bta_sdp_cb.sdp_active);
    497 
    498     if (bta_sdp_cb.sdp_active != BTA_SDP_ACTIVE_NONE)
    499     {
    500         /* SDP is still in progress */
    501         status = BTA_SDP_BUSY;
    502         if(bta_sdp_cb.p_dm_cback) {
    503             tBTA_SDP_SEARCH_COMP result = {0};
    504             result.uuid = p_data->get_search.uuid;
    505             bdcpy(result.remote_addr, p_data->get_search.bd_addr);
    506             result.status = status;
    507             bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, (tBTA_SDP *)&result, NULL);
    508         }
    509         return;
    510     }
    511 
    512     bta_sdp_cb.sdp_active = BTA_SDP_ACTIVE_YES;
    513     bdcpy(bta_sdp_cb.remote_addr, p_data->get_search.bd_addr);
    514     /* set the uuid used in the search */
    515     memcpy(bta_sdp_search_uuid, &(p_data->get_search.uuid),sizeof(tBT_UUID));
    516 
    517     /* initialize the search for the uuid */
    518     APPL_TRACE_DEBUG("%s init discovery with UUID(len: %d):",
    519             __func__, bta_sdp_search_uuid->len);
    520     for(x = 0; x<bta_sdp_search_uuid->len;x++){
    521         APPL_TRACE_DEBUG("%X",bta_sdp_search_uuid->uu.uuid128[x]);
    522     }
    523     SDP_InitDiscoveryDb (p_bta_sdp_cfg->p_sdp_db, p_bta_sdp_cfg->sdp_db_size, 1,
    524                                 bta_sdp_search_uuid, 0, NULL);
    525 
    526     if (!SDP_ServiceSearchAttributeRequest2(p_data->get_search.bd_addr, p_bta_sdp_cfg->p_sdp_db,
    527                                                 bta_sdp_search_cback, (void*)bta_sdp_search_uuid))
    528     {
    529         bta_sdp_cb.sdp_active = BTA_SDP_ACTIVE_NONE;
    530 
    531         /* failed to start SDP. report the failure right away */
    532         if (bta_sdp_cb.p_dm_cback) {
    533             tBTA_SDP_SEARCH_COMP result = {0};
    534             result.uuid = p_data->get_search.uuid;
    535             bdcpy(result.remote_addr, p_data->get_search.bd_addr);
    536             result.status = status;
    537             bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, (tBTA_SDP *)&result, NULL);
    538         }
    539     }
    540     /*
    541     else report the result when the cback is called
    542     */
    543 }
    544 
    545 /*******************************************************************************
    546 **
    547 ** Function     bta_sdp_record
    548 **
    549 ** Description  Discovers all sdp records for an uuid on remote device
    550 **
    551 ** Returns      void
    552 **
    553 *******************************************************************************/
    554 void bta_sdp_create_record(tBTA_SDP_MSG *p_data)
    555 {
    556     APPL_TRACE_DEBUG("%s() event: %d", __func__, p_data->record.hdr.event);
    557     if (bta_sdp_cb.p_dm_cback)
    558         bta_sdp_cb.p_dm_cback(BTA_SDP_CREATE_RECORD_USER_EVT, NULL, p_data->record.user_data);
    559 }
    560 
    561 /*******************************************************************************
    562 **
    563 ** Function     bta_sdp_create_record
    564 **
    565 ** Description  Discovers all sdp records for an uuid on remote device
    566 **
    567 ** Returns      void
    568 **
    569 *******************************************************************************/
    570 void bta_sdp_remove_record(tBTA_SDP_MSG *p_data)
    571 {
    572     APPL_TRACE_DEBUG("%s() event: %d", __func__, p_data->record.hdr.event);
    573     if (bta_sdp_cb.p_dm_cback)
    574         bta_sdp_cb.p_dm_cback(BTA_SDP_REMOVE_RECORD_USER_EVT, NULL, p_data->record.user_data);
    575 }
    576