/******************************************************************************
 *
 *  Copyright (C) 2014 The Android Open Source Project
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

/******************************************************************************
 *  This file contains action functions for SDP search.
 ******************************************************************************/

#include <arpa/inet.h>
#include <hardware/bluetooth.h>
#include <hardware/bt_sdp.h>
#include <stdlib.h>
#include <string.h>

#include "bt_common.h"
#include "bt_types.h"
#include "bta_api.h"
#include "bta_sdp_api.h"
#include "bta_sdp_int.h"
#include "bta_sys.h"
#include "btm_api.h"
#include "btm_int.h"
#include "osi/include/allocator.h"
#include "sdp_api.h"
#include "utl.h"

/*****************************************************************************
 *  Constants
 ****************************************************************************/

static const uint8_t UUID_OBEX_OBJECT_PUSH[] = {
    0x00, 0x00, 0x11, 0x05, 0x00, 0x00, 0x10, 0x00,
    0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
static const uint8_t UUID_PBAP_PSE[] = {0x00, 0x00, 0x11, 0x2F, 0x00, 0x00,
                                        0x10, 0x00, 0x80, 0x00, 0x00, 0x80,
                                        0x5F, 0x9B, 0x34, 0xFB};
static const uint8_t UUID_MAP_MAS[] = {0x00, 0x00, 0x11, 0x32, 0x00, 0x00,
                                       0x10, 0x00, 0x80, 0x00, 0x00, 0x80,
                                       0x5F, 0x9B, 0x34, 0xFB};
static const uint8_t UUID_MAP_MNS[] = {0x00, 0x00, 0x11, 0x33, 0x00, 0x00,
                                       0x10, 0x00, 0x80, 0x00, 0x00, 0x80,
                                       0x5F, 0x9B, 0x34, 0xFB};
static const uint8_t UUID_SAP[] = {0x00, 0x00, 0x11, 0x2D, 0x00, 0x00,
                                   0x10, 0x00, 0x80, 0x00, 0x00, 0x80,
                                   0x5F, 0x9B, 0x34, 0xFB};
// TODO:
// Both the fact that the UUIDs are declared in multiple places, plus the fact
// that there is a mess of UUID comparison and shortening methods will have to
// be fixed.
// The btcore->uuid module should be used for all instances.

#define UUID_MAX_LENGTH 16
#define IS_UUID(u1, u2) !memcmp(u1, u2, UUID_MAX_LENGTH)

static inline tBT_UUID shorten_sdp_uuid(const tBT_UUID* u) {
  static uint8_t bt_base_uuid[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                   0x10, 0x00, 0x80, 0x00, 0x00, 0x80,
                                   0x5F, 0x9B, 0x34, 0xFB};

  APPL_TRACE_DEBUG("%s() - uuid len:%d", __func__, u->len);
  if (u->len != 16) return *u;

  if (memcmp(&u->uu.uuid128[4], &bt_base_uuid[4], 12) != 0) return *u;

  tBT_UUID su;
  memset(&su, 0, sizeof(su));
  if (u->uu.uuid128[0] == 0 && u->uu.uuid128[1] == 0) {
    su.len = 2;
    uint16_t u16;
    memcpy(&u16, &u->uu.uuid128[2], sizeof(u16));
    su.uu.uuid16 = ntohs(u16);
  } else {
    su.len = 4;
    uint32_t u32;
    memcpy(&u32, &u->uu.uuid128[0], sizeof(u32));
    su.uu.uuid32 = ntohl(u32);
  }
  return su;
}

static void bta_create_mns_sdp_record(bluetooth_sdp_record* record,
                                      tSDP_DISC_REC* p_rec) {
  tSDP_DISC_ATTR* p_attr;
  tSDP_PROTOCOL_ELEM pe;
  uint16_t pversion = 0;
  record->mns.hdr.type = SDP_TYPE_MAP_MNS;
  record->mns.hdr.service_name_length = 0;
  record->mns.hdr.service_name = NULL;
  record->mns.hdr.rfcomm_channel_number = 0;
  record->mns.hdr.l2cap_psm = -1;
  record->mns.hdr.profile_version = 0;
  record->mns.supported_features = 0x0000001F;  // default value if not found

  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_MAP_SUPPORTED_FEATURES);
  if (p_attr != NULL) {
    record->mns.supported_features = p_attr->attr_value.v.u32;
  }

  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
  if (p_attr != NULL) {
    record->mns.hdr.service_name_length =
        SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
    record->mns.hdr.service_name = (char*)p_attr->attr_value.v.array;
  }

  if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_MAP_PROFILE,
                                  &pversion)) {
    record->mns.hdr.profile_version = pversion;
  }

  if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
    record->mns.hdr.rfcomm_channel_number = pe.params[0];
  }

  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM);
  if (p_attr != NULL) {
    record->mns.hdr.l2cap_psm = p_attr->attr_value.v.u16;
  }
}

static void bta_create_mas_sdp_record(bluetooth_sdp_record* record,
                                      tSDP_DISC_REC* p_rec) {
  tSDP_DISC_ATTR* p_attr;
  tSDP_PROTOCOL_ELEM pe;
  uint16_t pversion = -1;

  record->mas.hdr.type = SDP_TYPE_MAP_MAS;
  record->mas.hdr.service_name_length = 0;
  record->mas.hdr.service_name = NULL;
  record->mas.hdr.rfcomm_channel_number = 0;
  record->mas.hdr.l2cap_psm = -1;
  record->mas.hdr.profile_version = 0;
  record->mas.mas_instance_id = 0;
  record->mas.supported_features = 0x0000001F;
  record->mas.supported_message_types = 0;

  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_MAS_INSTANCE_ID);
  if (p_attr != NULL) {
    record->mas.mas_instance_id = p_attr->attr_value.v.u8;
  }

  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_MSG_TYPE);
  if (p_attr != NULL) {
    record->mas.supported_message_types = p_attr->attr_value.v.u8;
  }

  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_MAP_SUPPORTED_FEATURES);
  if (p_attr != NULL) {
    record->mas.supported_features = p_attr->attr_value.v.u32;
  }

  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
  if (p_attr != NULL) {
    record->mas.hdr.service_name_length =
        SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
    record->mas.hdr.service_name = (char*)p_attr->attr_value.v.array;
  }

  if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_MAP_PROFILE,
                                  &pversion)) {
    record->mas.hdr.profile_version = pversion;
  }

  if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
    record->mas.hdr.rfcomm_channel_number = pe.params[0];
  }

  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM);
  if (p_attr != NULL) {
    record->mas.hdr.l2cap_psm = p_attr->attr_value.v.u16;
  }
}

static void bta_create_pse_sdp_record(bluetooth_sdp_record* record,
                                      tSDP_DISC_REC* p_rec) {
  tSDP_DISC_ATTR* p_attr;
  uint16_t pversion;
  tSDP_PROTOCOL_ELEM pe;

  record->pse.hdr.type = SDP_TYPE_PBAP_PSE;
  record->pse.hdr.service_name_length = 0;
  record->pse.hdr.service_name = NULL;
  record->pse.hdr.rfcomm_channel_number = 0;
  record->pse.hdr.l2cap_psm = -1;
  record->pse.hdr.profile_version = 0;
  record->pse.supported_features = 0x00000003;
  record->pse.supported_repositories = 0;

  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_REPOSITORIES);
  if (p_attr != NULL) {
    record->pse.supported_repositories = p_attr->attr_value.v.u8;
  }
  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PBAP_SUPPORTED_FEATURES);
  if (p_attr != NULL) {
    record->pse.supported_features = p_attr->attr_value.v.u32;
  }

  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
  if (p_attr != NULL) {
    record->pse.hdr.service_name_length =
        SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
    record->pse.hdr.service_name = (char*)p_attr->attr_value.v.array;
  }

  if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_PHONE_ACCESS,
                                  &pversion)) {
    record->pse.hdr.profile_version = pversion;
  }

  if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
    record->pse.hdr.rfcomm_channel_number = pe.params[0];
  }

  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM);
  if (p_attr != NULL) {
    record->pse.hdr.l2cap_psm = p_attr->attr_value.v.u16;
  }
}

static void bta_create_ops_sdp_record(bluetooth_sdp_record* record,
                                      tSDP_DISC_REC* p_rec) {
  tSDP_DISC_ATTR *p_attr, *p_sattr;
  tSDP_PROTOCOL_ELEM pe;
  uint16_t pversion = -1;

  record->ops.hdr.type = SDP_TYPE_OPP_SERVER;
  record->ops.hdr.service_name_length = 0;
  record->ops.hdr.service_name = NULL;
  record->ops.hdr.rfcomm_channel_number = 0;
  record->ops.hdr.l2cap_psm = -1;
  record->ops.hdr.profile_version = 0;
  record->ops.supported_formats_list_len = 0;

  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
  if (p_attr != NULL) {
    record->ops.hdr.service_name_length =
        SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
    record->ops.hdr.service_name = (char*)p_attr->attr_value.v.array;
  }

  if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_OBEX_OBJECT_PUSH,
                                  &pversion)) {
    record->ops.hdr.profile_version = pversion;
  }

  if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
    record->ops.hdr.rfcomm_channel_number = pe.params[0];
  }

  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM);
  if (p_attr != NULL) {
    record->ops.hdr.l2cap_psm = p_attr->attr_value.v.u16;
  }
  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_FORMATS_LIST);
  if (p_attr != NULL) {
    /* Safety check - each entry should itself be a sequence */
    if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE) {
      record->ops.supported_formats_list_len = 0;
      APPL_TRACE_ERROR(
          "%s() - supported_formats_list - wrong attribute length/type:"
          " 0x%02x - expected 0x06",
          __func__, p_attr->attr_len_type);
    } else {
      int count = 0;
      /* 1 byte for type/length 1 byte for value */
      record->ops.supported_formats_list_len =
          SDP_DISC_ATTR_LEN(p_attr->attr_len_type) / 2;

      /* Extract each value into */
      for (p_sattr = p_attr->attr_value.v.p_sub_attr; p_sattr != NULL;
           p_sattr = p_sattr->p_next_attr) {
        if ((SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) == UINT_DESC_TYPE) &&
            (SDP_DISC_ATTR_LEN(p_sattr->attr_len_type) == 1)) {
          if (count == sizeof(record->ops.supported_formats_list)) {
            APPL_TRACE_ERROR(
                "%s() - supported_formats_list - count overflow - "
                "too many sub attributes!!",
                __func__);
            /* If you hit this, new formats have been added,
             * update SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH */
            break;
          }
          record->ops.supported_formats_list[count] = p_sattr->attr_value.v.u8;
          count++;
        } else {
          APPL_TRACE_ERROR(
              "%s() - supported_formats_list - wrong sub attribute "
              "length/type: 0x%02x - expected 0x80",
              __func__, p_sattr->attr_len_type);
          break;
        }
      }
      if (record->ops.supported_formats_list_len != count) {
        APPL_TRACE_WARNING(
            "%s() - supported_formats_list - Length of attribute different "
            "from the actual number of sub-attributes in the sequence "
            "att-length: %d - number of elements: %d",
            __func__, record->ops.supported_formats_list_len, count);
      }
      record->ops.supported_formats_list_len = count;
    }
  }
}

static void bta_create_sap_sdp_record(bluetooth_sdp_record* record,
                                      tSDP_DISC_REC* p_rec) {
  tSDP_DISC_ATTR* p_attr;
  tSDP_PROTOCOL_ELEM pe;
  uint16_t pversion = -1;

  record->sap.hdr.type = SDP_TYPE_MAP_MAS;
  record->sap.hdr.service_name_length = 0;
  record->sap.hdr.service_name = NULL;
  record->sap.hdr.rfcomm_channel_number = 0;
  record->sap.hdr.l2cap_psm = -1;
  record->sap.hdr.profile_version = 0;

  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
  if (p_attr != NULL) {
    record->sap.hdr.service_name_length =
        SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
    record->sap.hdr.service_name = (char*)p_attr->attr_value.v.array;
  }

  if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_SAP, &pversion)) {
    record->sap.hdr.profile_version = pversion;
  }

  if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
    record->sap.hdr.rfcomm_channel_number = pe.params[0];
  }
}

static void bta_create_raw_sdp_record(bluetooth_sdp_record* record,
                                      tSDP_DISC_REC* p_rec) {
  tSDP_DISC_ATTR* p_attr;
  tSDP_PROTOCOL_ELEM pe;

  record->hdr.type = SDP_TYPE_RAW;
  record->hdr.service_name_length = 0;
  record->hdr.service_name = NULL;
  record->hdr.rfcomm_channel_number = -1;
  record->hdr.l2cap_psm = -1;
  record->hdr.profile_version = -1;

  /* Try to extract a service name */
  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
  if (p_attr != NULL) {
    record->pse.hdr.service_name_length =
        SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
    record->pse.hdr.service_name = (char*)p_attr->attr_value.v.array;
  }

  /* Try to extract an RFCOMM channel */
  if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
    record->pse.hdr.rfcomm_channel_number = pe.params[0];
  }
  record->hdr.user1_ptr_len = p_bta_sdp_cfg->p_sdp_db->raw_size;
  record->hdr.user1_ptr = p_bta_sdp_cfg->p_sdp_db->raw_data;
}

/*******************************************************************************
 *
 * Function     bta_sdp_search_cback
 *
 * Description  Callback from btm after search is completed
 *
 * Returns      void
 *
 ******************************************************************************/
static void bta_sdp_search_cback(uint16_t result, void* user_data) {
  tSDP_DISC_REC* p_rec = NULL;
  tBTA_SDP_SEARCH_COMP evt_data;
  tBTA_SDP_STATUS status = BTA_SDP_FAILURE;
  int count = 0;
  tBT_UUID su;
  APPL_TRACE_DEBUG("%s() -  res: 0x%x", __func__, result);

  memset(&evt_data, 0, sizeof(evt_data));
  bta_sdp_cb.sdp_active = BTA_SDP_ACTIVE_NONE;

  if (bta_sdp_cb.p_dm_cback == NULL) return;

  bdcpy(evt_data.remote_addr, bta_sdp_cb.remote_addr);
  tBT_UUID* uuid = (tBT_UUID*)user_data;
  memcpy(&evt_data.uuid, uuid, sizeof(tBT_UUID));
  su = shorten_sdp_uuid(uuid);

  if (result == SDP_SUCCESS || result == SDP_DB_FULL) {
    do {
      p_rec = SDP_FindServiceUUIDInDb(p_bta_sdp_cfg->p_sdp_db, &su, p_rec);
      /* generate the matching record data pointer */
      if (p_rec != NULL) {
        status = BTA_SDP_SUCCESS;
        if (IS_UUID(UUID_MAP_MAS, uuid->uu.uuid128)) {
          APPL_TRACE_DEBUG("%s() - found MAP (MAS) uuid", __func__);
          bta_create_mas_sdp_record(&evt_data.records[count], p_rec);
        } else if (IS_UUID(UUID_MAP_MNS, uuid->uu.uuid128)) {
          APPL_TRACE_DEBUG("%s() - found MAP (MNS) uuid", __func__);
          bta_create_mns_sdp_record(&evt_data.records[count], p_rec);
        } else if (IS_UUID(UUID_PBAP_PSE, uuid->uu.uuid128)) {
          APPL_TRACE_DEBUG("%s() - found PBAP (PSE) uuid", __func__);
          bta_create_pse_sdp_record(&evt_data.records[count], p_rec);
        } else if (IS_UUID(UUID_OBEX_OBJECT_PUSH, uuid->uu.uuid128)) {
          APPL_TRACE_DEBUG("%s() - found Object Push Server (OPS) uuid",
                           __func__);
          bta_create_ops_sdp_record(&evt_data.records[count], p_rec);
        } else if (IS_UUID(UUID_SAP, uuid->uu.uuid128)) {
          APPL_TRACE_DEBUG("%s() - found SAP uuid", __func__);
          bta_create_sap_sdp_record(&evt_data.records[count], p_rec);
        } else {
          /* we do not have specific structure for this */
          APPL_TRACE_DEBUG("%s() - profile not identified. using raw data",
                           __func__);
          bta_create_raw_sdp_record(&evt_data.records[count], p_rec);
          p_rec = NULL;  // Terminate loop
          /* For raw, we only extract the first entry, and then return the
             entire
             raw data chunk.
             TODO: Find a way to split the raw data into record chunks, and
             iterate
                   to extract generic data for each chunk - e.g. rfcomm channel
             and
                   service name. */
        }
        count++;
      } else {
        APPL_TRACE_DEBUG("%s() - UUID not found", __func__);
      }
    } while (p_rec != NULL && count < BTA_SDP_MAX_RECORDS);

    evt_data.record_count = count;
  }
  evt_data.status = status;

  bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, (tBTA_SDP*)&evt_data,
                        (void*)&uuid->uu.uuid128);
  osi_free(user_data);  // We no longer need the user data to track the search
}

/*******************************************************************************
 *
 * Function     bta_sdp_enable
 *
 * Description  Initializes the SDP I/F
 *
 * Returns      void
 *
 ******************************************************************************/
void bta_sdp_enable(tBTA_SDP_MSG* p_data) {
  APPL_TRACE_DEBUG("%s in, sdp_active:%d", __func__, bta_sdp_cb.sdp_active);
  tBTA_SDP_STATUS status = BTA_SDP_SUCCESS;
  bta_sdp_cb.p_dm_cback = p_data->enable.p_cback;
  bta_sdp_cb.p_dm_cback(BTA_SDP_ENABLE_EVT, (tBTA_SDP*)&status, NULL);
}

/*******************************************************************************
 *
 * Function     bta_sdp_search
 *
 * Description  Discovers all sdp records for an uuid on remote device
 *
 * Returns      void
 *
 ******************************************************************************/
void bta_sdp_search(tBTA_SDP_MSG* p_data) {
  if (p_data == NULL) {
    APPL_TRACE_DEBUG("SDP control block handle is null");
    return;
  }
  tBTA_SDP_STATUS status = BTA_SDP_FAILURE;

  APPL_TRACE_DEBUG("%s in, sdp_active:%d", __func__, bta_sdp_cb.sdp_active);

  if (bta_sdp_cb.sdp_active != BTA_SDP_ACTIVE_NONE) {
    /* SDP is still in progress */
    status = BTA_SDP_BUSY;
    if (bta_sdp_cb.p_dm_cback) {
      tBTA_SDP_SEARCH_COMP result;
      memset(&result, 0, sizeof(result));
      result.uuid = p_data->get_search.uuid;
      bdcpy(result.remote_addr, p_data->get_search.bd_addr);
      result.status = status;
      bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, (tBTA_SDP*)&result, NULL);
    }
    return;
  }

  bta_sdp_cb.sdp_active = BTA_SDP_ACTIVE_YES;
  bdcpy(bta_sdp_cb.remote_addr, p_data->get_search.bd_addr);
  /* set the uuid used in the search */
  tBT_UUID* bta_sdp_search_uuid =
      static_cast<tBT_UUID*>(osi_malloc(sizeof(tBT_UUID)));
  memcpy(bta_sdp_search_uuid, &(p_data->get_search.uuid), sizeof(tBT_UUID));

  /* initialize the search for the uuid */
  APPL_TRACE_DEBUG("%s init discovery with UUID(len: %d):", __func__,
                   bta_sdp_search_uuid->len);
  for (int x = 0; x < bta_sdp_search_uuid->len; x++) {
    APPL_TRACE_DEBUG("%X", bta_sdp_search_uuid->uu.uuid128[x]);
  }
  SDP_InitDiscoveryDb(p_bta_sdp_cfg->p_sdp_db, p_bta_sdp_cfg->sdp_db_size, 1,
                      bta_sdp_search_uuid, 0, NULL);

  if (!SDP_ServiceSearchAttributeRequest2(
          p_data->get_search.bd_addr, p_bta_sdp_cfg->p_sdp_db,
          bta_sdp_search_cback, (void*)bta_sdp_search_uuid)) {
    bta_sdp_cb.sdp_active = BTA_SDP_ACTIVE_NONE;

    /* failed to start SDP. report the failure right away */
    if (bta_sdp_cb.p_dm_cback) {
      tBTA_SDP_SEARCH_COMP result;
      memset(&result, 0, sizeof(result));
      result.uuid = p_data->get_search.uuid;
      bdcpy(result.remote_addr, p_data->get_search.bd_addr);
      result.status = status;
      bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, (tBTA_SDP*)&result, NULL);
    }
  }
  /*
  else report the result when the cback is called
  */
}

/*******************************************************************************
 *
 * Function     bta_sdp_record
 *
 * Description  Discovers all sdp records for an uuid on remote device
 *
 * Returns      void
 *
 ******************************************************************************/
void bta_sdp_create_record(tBTA_SDP_MSG* p_data) {
  APPL_TRACE_DEBUG("%s() event: %d", __func__, p_data->record.hdr.event);
  if (bta_sdp_cb.p_dm_cback)
    bta_sdp_cb.p_dm_cback(BTA_SDP_CREATE_RECORD_USER_EVT, NULL,
                          p_data->record.user_data);
}

/*******************************************************************************
 *
 * Function     bta_sdp_create_record
 *
 * Description  Discovers all sdp records for an uuid on remote device
 *
 * Returns      void
 *
 ******************************************************************************/
void bta_sdp_remove_record(tBTA_SDP_MSG* p_data) {
  APPL_TRACE_DEBUG("%s() event: %d", __func__, p_data->record.hdr.event);
  if (bta_sdp_cb.p_dm_cback)
    bta_sdp_cb.p_dm_cback(BTA_SDP_REMOVE_RECORD_USER_EVT, NULL,
                          p_data->record.user_data);
}
