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