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