Home | History | Annotate | Download | only in src
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2009-2012 Broadcom Corporation
      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  *
     21  *  Filename:      btif_hf.c
     22  *
     23  *  Description:   Handsfree Profile Bluetooth Interface
     24  *
     25  *
     26  ***********************************************************************************/
     27 
     28 #include <hardware/bluetooth.h>
     29 #include <hardware/bt_sock.h>
     30 #include <sys/types.h>
     31 #include <sys/socket.h>
     32 #include <errno.h>
     33 
     34 #define LOG_TAG "BTIF_SOCK_SDP"
     35 #include "btif_common.h"
     36 #include "btif_util.h"
     37 
     38 #include "bd.h"
     39 
     40 #include "bta_api.h"
     41 
     42 
     43 #include "bt_target.h"
     44 #include "gki.h"
     45 #include "hcimsgs.h"
     46 #include "sdp_api.h"
     47 #include "btu.h"
     48 #include "btm_api.h"
     49 #include "btm_int.h"
     50 #include "btif_sock_sdp.h"
     51 #include "utl.h"
     52 #include "../bta/pb/bta_pbs_int.h"
     53 #include "../include/bta_op_api.h"
     54 #include "bta_jv_api.h"
     55 #include <cutils/log.h>
     56 
     57 #define RESERVED_SCN_PBS 19
     58 #define RESERVED_SCN_OPS 12
     59 
     60 #define UUID_MAX_LENGTH 16
     61 
     62 
     63 #define IS_UUID(u1,u2)  !memcmp(u1,u2,UUID_MAX_LENGTH)
     64 
     65 
     66 #define BTM_NUM_PROTO_ELEMS 2
     67 static int add_sdp_by_uuid(const char *name,  const uint8_t *service_uuid, UINT16 channel)
     68 {
     69 
     70     UINT32 btm_sdp_handle;
     71 
     72     tSDP_PROTOCOL_ELEM  proto_elem_list[BTM_NUM_PROTO_ELEMS];
     73 
     74     /* register the service */
     75     if ((btm_sdp_handle = SDP_CreateRecord()) != FALSE)
     76     {
     77         /*** Fill out the protocol element sequence for SDP ***/
     78         proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
     79         proto_elem_list[0].num_params = 0;
     80         proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
     81         proto_elem_list[1].num_params = 1;
     82 
     83         proto_elem_list[1].params[0] = channel;
     84 
     85         if (SDP_AddProtocolList(btm_sdp_handle, BTM_NUM_PROTO_ELEMS,
     86             proto_elem_list))
     87         {
     88             UINT8           buff[48];
     89             UINT8           *p, *type_buf[1];
     90             UINT8       type[1], type_len[1];
     91          p = type_buf[0] = buff;
     92          type[0] = UUID_DESC_TYPE;
     93 
     94 //         UINT8_TO_BE_STREAM  (p, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES);
     95          ARRAY_TO_BE_STREAM (p, service_uuid, 16);
     96             type_len[0] = 16;
     97             if( SDP_AddSequence(btm_sdp_handle, (UINT16) ATTR_ID_SERVICE_CLASS_ID_LIST,
     98                           1, type, type_len, type_buf) )
     99 //            if (SDP_AddServiceClassIdList(btm_sdp_handle, 1, &service_uuid))
    100             {
    101                 if ((SDP_AddAttribute(btm_sdp_handle, ATTR_ID_SERVICE_NAME,
    102                     TEXT_STR_DESC_TYPE, (UINT32)(strlen(name)+1),
    103                     (UINT8 *)name)) )
    104                 {
    105                     UINT16  list[1];
    106 
    107                     /* Make the service browseable */
    108                     list[0] = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
    109                     if ((SDP_AddUuidSequence (btm_sdp_handle,  ATTR_ID_BROWSE_GROUP_LIST,
    110                         1, list)) )
    111 
    112                         return btm_sdp_handle;
    113                 }
    114             }
    115         }
    116     }
    117     else APPL_TRACE_ERROR1("failed to create sdp record, service_name:%s", name);
    118     return 0;
    119 }
    120 
    121 
    122 /* Realm Character Set */
    123 #define BTA_PBS_REALM_CHARSET   0       /* ASCII */
    124 
    125 /* Specifies whether or not client's user id is required during obex authentication */
    126 #define BTA_PBS_USERID_REQ      FALSE
    127 extern const tBTA_PBS_CFG bta_pbs_cfg;
    128 const tBTA_PBS_CFG bta_pbs_cfg =
    129 {
    130     BTA_PBS_REALM_CHARSET,      /* Server only */
    131     BTA_PBS_USERID_REQ,         /* Server only */
    132     (BTA_PBS_SUPF_DOWNLOAD | BTA_PBS_SURF_BROWSE),
    133     BTA_PBS_REPOSIT_LOCAL,
    134 };
    135 
    136 static int add_pbap_sdp(const char* p_service_name, int scn)
    137 {
    138 
    139     tSDP_PROTOCOL_ELEM  protoList [3];
    140     UINT16              pbs_service = UUID_SERVCLASS_PBAP_PSE;
    141     UINT16              browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
    142     BOOLEAN             status = FALSE;
    143     UINT32              sdp_handle = 0;
    144     tBTA_PBS_CFG *p_bta_pbs_cfg = (tBTA_PBS_CFG *)&bta_pbs_cfg;
    145 
    146     APPL_TRACE_DEBUG2("add_pbap_sdd:scn %d, service name %s", scn, p_service_name);
    147 
    148     if ((sdp_handle = SDP_CreateRecord()) == 0)
    149     {
    150         APPL_TRACE_ERROR0("PBS SDP: Unable to register PBS Service");
    151         return sdp_handle;
    152     }
    153 
    154     /* add service class */
    155     if (SDP_AddServiceClassIdList(sdp_handle, 1, &pbs_service))
    156     {
    157         memset( protoList, 0 , 3*sizeof(tSDP_PROTOCOL_ELEM) );
    158         /* add protocol list, including RFCOMM scn */
    159         protoList[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
    160         protoList[0].num_params = 0;
    161         protoList[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
    162         protoList[1].num_params = 1;
    163         protoList[1].params[0] = scn;
    164         protoList[2].protocol_uuid = UUID_PROTOCOL_OBEX;
    165         protoList[2].num_params = 0;
    166 
    167         if (SDP_AddProtocolList(sdp_handle, 3, protoList))
    168         {
    169             status = TRUE;  /* All mandatory fields were successful */
    170 
    171             /* optional:  if name is not "", add a name entry */
    172             if (*p_service_name != '\0')
    173                 SDP_AddAttribute(sdp_handle,
    174                                  (UINT16)ATTR_ID_SERVICE_NAME,
    175                                  (UINT8)TEXT_STR_DESC_TYPE,
    176                                  (UINT32)(strlen(p_service_name) + 1),
    177                                  (UINT8 *)p_service_name);
    178 
    179             /* Add in the Bluetooth Profile Descriptor List */
    180             SDP_AddProfileDescriptorList(sdp_handle,
    181                                              UUID_SERVCLASS_PHONE_ACCESS,
    182                                              BTA_PBS_DEFAULT_VERSION);
    183 
    184         } /* end of setting mandatory protocol list */
    185     } /* end of setting mandatory service class */
    186 
    187     /* add supported feature and repositories */
    188     if (status)
    189     {
    190         SDP_AddAttribute(sdp_handle, ATTR_ID_SUPPORTED_REPOSITORIES, UINT_DESC_TYPE,
    191                   (UINT32)1, (UINT8*)&p_bta_pbs_cfg->supported_repositories);
    192 
    193         /* Make the service browseable */
    194         SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
    195     }
    196 
    197     if (!status)
    198     {
    199         SDP_DeleteRecord(sdp_handle);
    200         sdp_handle = 0;
    201         APPL_TRACE_ERROR0("bta_pbs_sdp_register FAILED");
    202     }
    203     else
    204     {
    205         bta_sys_add_uuid(pbs_service);  /* UUID_SERVCLASS_PBAP_PSE */
    206         APPL_TRACE_DEBUG1("PBS:  SDP Registered (handle 0x%08x)", sdp_handle);
    207     }
    208 
    209     return sdp_handle;
    210 }
    211 
    212 /* This is horrible design - to reserve channel ID's and use them to magically link
    213  * a channel number to a hard coded SDP entry.
    214  * TODO: expose a prober SDP API, to avoid hacks like this, and make it possible
    215  *        to set useful names for the ServiceName */
    216 #define BTA_MAP_MSG_TYPE_EMAIL    0x01
    217 #define BTA_MAP_MSG_TYPE_SMS_GSM  0x02
    218 #define BTA_MAP_MSG_TYPE_SMS_CDMA 0x04
    219 #define BTA_MAP_MSG_TYPE_MMS      0x08
    220 
    221 #define BTA_MAPS_DEFAULT_VERSION 0x0101 /* MAP 1.1 */
    222 typedef struct
    223 {
    224     UINT8       mas_id;                 /* the MAS instance id */
    225     const char* service_name;          /* Description of the MAS instance */
    226     UINT8       supported_message_types;/* Server supported message types - SMS/MMS/EMAIL */
    227 } tBTA_MAPS_CFG;
    228 const tBTA_MAPS_CFG bta_maps_cfg_sms =
    229 {
    230     0,                  /* Mas id 0 is for SMS/MMS */
    231     "MAP SMS",
    232     BTA_MAP_MSG_TYPE_SMS_GSM | BTA_MAP_MSG_TYPE_SMS_CDMA
    233 };
    234 const tBTA_MAPS_CFG bta_maps_cfg_email =
    235 {
    236     1,                  /* Mas id 1 is for EMAIL */
    237     "MAP EMAIL",
    238     BTA_MAP_MSG_TYPE_EMAIL
    239 };
    240 static int add_maps_sdp(const char* p_service_name, int scn)
    241 {
    242 
    243     tSDP_PROTOCOL_ELEM  protoList [3];
    244     UINT16              service = UUID_SERVCLASS_MESSAGE_ACCESS;
    245     UINT16              browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
    246     BOOLEAN             status = FALSE;
    247     UINT32              sdp_handle = 0;
    248     // TODO: To add support for EMAIL set below depending on the scn to either SMS or Email
    249     const tBTA_MAPS_CFG *p_bta_maps_cfg = &bta_maps_cfg_sms;
    250 
    251     APPL_TRACE_DEBUG2("add_maps_sdd:scn %d, service name %s", scn, p_service_name);
    252 
    253     if ((sdp_handle = SDP_CreateRecord()) == 0)
    254     {
    255         APPL_TRACE_ERROR0("MAPS SDP: Unable to register MAPS Service");
    256         return sdp_handle;
    257     }
    258 
    259     /* add service class */
    260     if (SDP_AddServiceClassIdList(sdp_handle, 1, &service))
    261     {
    262         memset( protoList, 0 , 3*sizeof(tSDP_PROTOCOL_ELEM) );
    263         /* add protocol list, including RFCOMM scn */
    264         protoList[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
    265         protoList[0].num_params = 0;
    266         protoList[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
    267         protoList[1].num_params = 1;
    268         protoList[1].params[0] = scn;
    269         protoList[2].protocol_uuid = UUID_PROTOCOL_OBEX;
    270         protoList[2].num_params = 0;
    271 
    272         if (SDP_AddProtocolList(sdp_handle, 3, protoList))
    273         {
    274             status = TRUE;  /* All mandatory fields were successful */
    275 
    276             /* optional:  if name is not "", add a name entry */
    277             SDP_AddAttribute(sdp_handle,
    278                             (UINT16)ATTR_ID_SERVICE_NAME,
    279                             (UINT8)TEXT_STR_DESC_TYPE,
    280                             (UINT32)(strlen(p_bta_maps_cfg->service_name) + 1),
    281                             (UINT8 *)p_bta_maps_cfg->service_name);
    282 
    283             /* Add in the Bluetooth Profile Descriptor List */
    284             SDP_AddProfileDescriptorList(sdp_handle,
    285                                              UUID_SERVCLASS_MAP_PROFILE,
    286                                              BTA_MAPS_DEFAULT_VERSION);
    287 
    288         } /* end of setting mandatory protocol list */
    289     } /* end of setting mandatory service class */
    290 
    291     /* add supported feature and repositories */
    292     if (status)
    293     {
    294         SDP_AddAttribute(sdp_handle, ATTR_ID_MAS_INSTANCE_ID, UINT_DESC_TYPE,
    295                   (UINT32)1, (UINT8*)&p_bta_maps_cfg->mas_id);
    296         SDP_AddAttribute(sdp_handle, ATTR_ID_SUPPORTED_MSG_TYPE, UINT_DESC_TYPE,
    297                   (UINT32)1, (UINT8*)&p_bta_maps_cfg->supported_message_types);
    298 
    299         /* Make the service browseable */
    300         SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
    301     }
    302 
    303     if (!status)
    304     {
    305         SDP_DeleteRecord(sdp_handle);
    306         sdp_handle = 0;
    307         APPL_TRACE_ERROR0("bta_mass_sdp_register FAILED");
    308     }
    309     else
    310     {
    311         bta_sys_add_uuid(service);  /* UUID_SERVCLASS_MESSAGE_ACCESS */
    312         APPL_TRACE_DEBUG1("MAPSS:  SDP Registered (handle 0x%08x)", sdp_handle);
    313     }
    314 
    315     return sdp_handle;
    316 }
    317 
    318 
    319 /* object format lookup table */
    320 static const tBTA_OP_FMT bta_ops_obj_fmt[] =
    321 {
    322     BTA_OP_VCARD21_FMT,
    323     BTA_OP_VCARD30_FMT,
    324     BTA_OP_VCAL_FMT,
    325     BTA_OP_ICAL_FMT,
    326     BTA_OP_VNOTE_FMT,
    327     BTA_OP_VMSG_FMT,
    328     BTA_OP_OTHER_FMT
    329 };
    330 
    331 #define BTA_OPS_NUM_FMTS        7
    332 #define BTA_OPS_PROTOCOL_COUNT  3
    333 
    334 #ifndef BTUI_OPS_FORMATS
    335 #define BTUI_OPS_FORMATS            (BTA_OP_VCARD21_MASK | BTA_OP_VCARD30_MASK | \
    336                                          BTA_OP_VCAL_MASK | BTA_OP_ICAL_MASK | \
    337                                          BTA_OP_VNOTE_MASK | BTA_OP_VMSG_MASK | \
    338                                          BTA_OP_ANY_MASK )
    339 #endif
    340 
    341 static int add_ops_sdp(const char *p_service_name,int scn)
    342 {
    343 
    344 
    345     tSDP_PROTOCOL_ELEM  protoList [BTA_OPS_PROTOCOL_COUNT];
    346     UINT16      servclass = UUID_SERVCLASS_OBEX_OBJECT_PUSH;
    347     int         i, j;
    348     tBTA_UTL_COD cod;
    349     UINT8       desc_type[BTA_OPS_NUM_FMTS];
    350     UINT8       type_len[BTA_OPS_NUM_FMTS];
    351     UINT8       *type_value[BTA_OPS_NUM_FMTS];
    352     UINT16      browse;
    353     UINT32 sdp_handle;
    354     tBTA_OP_FMT_MASK    formats = BTUI_OPS_FORMATS;
    355 
    356     APPL_TRACE_DEBUG2("scn %d, service name %s", scn, p_service_name);
    357 
    358     sdp_handle = SDP_CreateRecord();
    359 
    360     /* add service class */
    361     if (SDP_AddServiceClassIdList(sdp_handle, 1, &servclass))
    362     {
    363         /* add protocol list, including RFCOMM scn */
    364         protoList[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
    365         protoList[0].num_params = 0;
    366         protoList[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
    367         protoList[1].num_params = 1;
    368         protoList[1].params[0] = scn;
    369         protoList[2].protocol_uuid = UUID_PROTOCOL_OBEX;
    370         protoList[2].num_params = 0;
    371 
    372         if (SDP_AddProtocolList(sdp_handle, BTA_OPS_PROTOCOL_COUNT, protoList))
    373         {
    374             SDP_AddAttribute(sdp_handle,
    375                (UINT16)ATTR_ID_SERVICE_NAME,
    376                 (UINT8)TEXT_STR_DESC_TYPE,
    377                 (UINT32)(strlen(p_service_name) + 1),
    378                 (UINT8 *)p_service_name);
    379 
    380             SDP_AddProfileDescriptorList(sdp_handle,
    381                 UUID_SERVCLASS_OBEX_OBJECT_PUSH,
    382                 0x0100);
    383         }
    384     }
    385 
    386     /* Make the service browseable */
    387     browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
    388     SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
    389 
    390     /* add sequence for supported types */
    391     for (i = 0, j = 0; i < BTA_OPS_NUM_FMTS; i++)
    392     {
    393         if ((formats >> i) & 1)
    394         {
    395             type_value[j] = (UINT8 *) &bta_ops_obj_fmt[i];
    396             desc_type[j] = UINT_DESC_TYPE;
    397             type_len[j++] = 1;
    398         }
    399     }
    400 
    401     SDP_AddSequence(sdp_handle, (UINT16) ATTR_ID_SUPPORTED_FORMATS_LIST,
    402         (UINT8) j, desc_type, type_len, type_value);
    403 
    404     /* set class of device */
    405     cod.service = BTM_COD_SERVICE_OBJ_TRANSFER;
    406     utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
    407 
    408     bta_sys_add_uuid(servclass); /* UUID_SERVCLASS_OBEX_OBJECT_PUSH */
    409 
    410     return sdp_handle;
    411 }
    412 #define SPP_NUM_PROTO_ELEMS 2
    413 static int add_spp_sdp(const char *service_name, int scn)
    414 {
    415     UINT16 serviceclassid = UUID_SERVCLASS_SERIAL_PORT;
    416     tSDP_PROTOCOL_ELEM  proto_elem_list[SPP_NUM_PROTO_ELEMS];
    417     int              sdp_handle;
    418 
    419     APPL_TRACE_DEBUG2("scn %d, service name %s", scn, service_name);
    420 
    421     /* register the service */
    422     if ((sdp_handle = SDP_CreateRecord()) != FALSE)
    423     {
    424         /*** Fill out the protocol element sequence for SDP ***/
    425         proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
    426         proto_elem_list[0].num_params = 0;
    427         proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
    428         proto_elem_list[1].num_params = 1;
    429 
    430         proto_elem_list[1].params[0] = scn;
    431 
    432         if (SDP_AddProtocolList(sdp_handle, SPP_NUM_PROTO_ELEMS, proto_elem_list))
    433         {
    434             if (SDP_AddServiceClassIdList(sdp_handle, 1, &serviceclassid))
    435             {
    436                 if ((SDP_AddAttribute(sdp_handle, ATTR_ID_SERVICE_NAME,
    437                                 TEXT_STR_DESC_TYPE, (UINT32)(strlen(service_name)+1),
    438                                 (UINT8 *)service_name)))
    439                 {
    440                     UINT16  list[1];
    441                     /* Make the service browseable */
    442                     list[0] = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
    443                     SDP_AddUuidSequence (sdp_handle,  ATTR_ID_BROWSE_GROUP_LIST,
    444                                     1, list);
    445                 }
    446             }
    447         }
    448     }
    449     return sdp_handle;
    450 }
    451 
    452 
    453 
    454 static int add_rfc_sdp_by_uuid(const char* name, const uint8_t* uuid, int scn)
    455 {
    456     int handle = 0;
    457 
    458     APPL_TRACE_DEBUG2("name:%s, scn:%d", name, scn);
    459 
    460     /*
    461         Bluetooth Socket API relies on having preregistered bluez sdp records for HSAG, HFAG, OPP & PBAP
    462         that are mapped to rc chan 10, 11,12 & 19. Today HSAG and HFAG is routed to BRCM AG and are not
    463         using BT socket API so for now we will need to support OPP and PBAP to enable 3rd party developer
    464         apps running on BRCM Android.
    465 
    466         To do this we will check the UUID for the requested service and mimic the SDP records of bluez
    467         upon reception.  See functions add_opush() and add_pbap() in sdptool.c for actual records
    468     */
    469 
    470     /* special handling for preregistered bluez services (OPP, PBAP) that we need to mimic */
    471 
    472     int final_scn = get_reserved_rfc_channel(uuid);
    473     if (final_scn == -1)
    474     {
    475         final_scn=scn;
    476     }
    477     if (IS_UUID(UUID_OBEX_OBJECT_PUSH,uuid))
    478     {
    479         handle = add_ops_sdp(name,final_scn);
    480     }
    481     else if (IS_UUID(UUID_PBAP_PSE,uuid))
    482     {
    483         handle = add_pbap_sdp(name, final_scn); //PBAP Server is always 19
    484     }
    485     else if (IS_UUID(UUID_MAPS_MAS,uuid))
    486     {
    487         handle = add_maps_sdp(name, final_scn); //MAP Server is always 19
    488     }
    489     else if (IS_UUID(UUID_SPP, uuid))
    490     {
    491         handle = add_spp_sdp(name, final_scn);
    492     }
    493     else
    494     {
    495         handle = add_sdp_by_uuid(name, uuid, final_scn);
    496     }
    497     return handle;
    498 }
    499 
    500 BOOLEAN is_reserved_rfc_channel(int scn)
    501 {
    502     switch(scn)
    503     {
    504         case RESERVED_SCN_PBS:
    505         case RESERVED_SCN_OPS:
    506             return TRUE;
    507     }
    508     return FALSE;
    509 }
    510 
    511 
    512 int get_reserved_rfc_channel (const uint8_t* uuid)
    513 {
    514     if (IS_UUID(UUID_PBAP_PSE,uuid))
    515     {
    516       return RESERVED_SCN_PBS;
    517     }
    518     else if (IS_UUID(UUID_OBEX_OBJECT_PUSH,uuid))
    519     {
    520       return RESERVED_SCN_OPS;
    521     }
    522     return -1;
    523 }
    524 
    525 int add_rfc_sdp_rec(const char* name, const uint8_t* uuid, int scn)
    526 {
    527     int sdp_handle = 0;
    528     if(is_uuid_empty(uuid))
    529     {
    530         switch(scn)
    531         {
    532             case RESERVED_SCN_PBS: // PBAP Reserved port
    533                 uuid = UUID_PBAP_PSE;
    534                 break;
    535              case RESERVED_SCN_OPS:
    536                 uuid = UUID_OBEX_OBJECT_PUSH;
    537                 break;
    538             default:
    539                 uuid = UUID_SPP;
    540                 break;
    541         }
    542     }
    543     sdp_handle = add_rfc_sdp_by_uuid(name, uuid, scn);
    544     return sdp_handle;
    545 }
    546 
    547 void del_rfc_sdp_rec(int handle)
    548 {
    549     APPL_TRACE_DEBUG1("del_rfc_sdp_rec: handle:0x%x", handle);
    550     if(handle != -1 && handle != 0)
    551         BTA_JvDeleteRecord( handle );
    552 }
    553 
    554