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