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_FEATURES, UINT_DESC_TYPE,
    191                   (UINT32)1, (UINT8*)&p_bta_pbs_cfg->supported_features);
    192         SDP_AddAttribute(sdp_handle, ATTR_ID_SUPPORTED_REPOSITORIES, UINT_DESC_TYPE,
    193                   (UINT32)1, (UINT8*)&p_bta_pbs_cfg->supported_repositories);
    194 
    195         /* Make the service browseable */
    196         SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
    197     }
    198 
    199     if (!status)
    200     {
    201         SDP_DeleteRecord(sdp_handle);
    202         sdp_handle = 0;
    203         APPL_TRACE_ERROR0("bta_pbs_sdp_register FAILED");
    204     }
    205     else
    206     {
    207         bta_sys_add_uuid(pbs_service);  /* UUID_SERVCLASS_PBAP_PSE */
    208         APPL_TRACE_DEBUG1("PBS:  SDP Registered (handle 0x%08x)", sdp_handle);
    209     }
    210 
    211     return sdp_handle;
    212 }
    213 
    214 
    215 /* object format lookup table */
    216 static const tBTA_OP_FMT bta_ops_obj_fmt[] =
    217 {
    218     BTA_OP_VCARD21_FMT,
    219     BTA_OP_VCARD30_FMT,
    220     BTA_OP_VCAL_FMT,
    221     BTA_OP_ICAL_FMT,
    222     BTA_OP_VNOTE_FMT,
    223     BTA_OP_VMSG_FMT,
    224     BTA_OP_OTHER_FMT
    225 };
    226 
    227 #define BTA_OPS_NUM_FMTS        7
    228 #define BTA_OPS_PROTOCOL_COUNT  3
    229 
    230 #ifndef BTUI_OPS_FORMATS
    231 #define BTUI_OPS_FORMATS            (BTA_OP_VCARD21_MASK | BTA_OP_VCARD30_MASK | \
    232                                          BTA_OP_VCAL_MASK | BTA_OP_ICAL_MASK | \
    233                                          BTA_OP_VNOTE_MASK | BTA_OP_VMSG_MASK | \
    234                                          BTA_OP_ANY_MASK )
    235 #endif
    236 
    237 static int add_ops_sdp(const char *p_service_name,int scn)
    238 {
    239 
    240 
    241     tSDP_PROTOCOL_ELEM  protoList [BTA_OPS_PROTOCOL_COUNT];
    242     UINT16      servclass = UUID_SERVCLASS_OBEX_OBJECT_PUSH;
    243     int         i, j;
    244     tBTA_UTL_COD cod;
    245     UINT8       desc_type[BTA_OPS_NUM_FMTS];
    246     UINT8       type_len[BTA_OPS_NUM_FMTS];
    247     UINT8       *type_value[BTA_OPS_NUM_FMTS];
    248     UINT16      browse;
    249     UINT32 sdp_handle;
    250     tBTA_OP_FMT_MASK    formats = BTUI_OPS_FORMATS;
    251 
    252     APPL_TRACE_DEBUG2("scn %d, service name %s", scn, p_service_name);
    253 
    254     sdp_handle = SDP_CreateRecord();
    255 
    256     /* add service class */
    257     if (SDP_AddServiceClassIdList(sdp_handle, 1, &servclass))
    258     {
    259         /* add protocol list, including RFCOMM scn */
    260         protoList[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
    261         protoList[0].num_params = 0;
    262         protoList[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
    263         protoList[1].num_params = 1;
    264         protoList[1].params[0] = scn;
    265         protoList[2].protocol_uuid = UUID_PROTOCOL_OBEX;
    266         protoList[2].num_params = 0;
    267 
    268         if (SDP_AddProtocolList(sdp_handle, BTA_OPS_PROTOCOL_COUNT, protoList))
    269         {
    270             SDP_AddAttribute(sdp_handle,
    271                (UINT16)ATTR_ID_SERVICE_NAME,
    272                 (UINT8)TEXT_STR_DESC_TYPE,
    273                 (UINT32)(strlen(p_service_name) + 1),
    274                 (UINT8 *)p_service_name);
    275 
    276             SDP_AddProfileDescriptorList(sdp_handle,
    277                 UUID_SERVCLASS_OBEX_OBJECT_PUSH,
    278                 0x0100);
    279         }
    280     }
    281 
    282     /* Make the service browseable */
    283     browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
    284     SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
    285 
    286     /* add sequence for supported types */
    287     for (i = 0, j = 0; i < BTA_OPS_NUM_FMTS; i++)
    288     {
    289         if ((formats >> i) & 1)
    290         {
    291             type_value[j] = (UINT8 *) &bta_ops_obj_fmt[i];
    292             desc_type[j] = UINT_DESC_TYPE;
    293             type_len[j++] = 1;
    294         }
    295     }
    296 
    297     SDP_AddSequence(sdp_handle, (UINT16) ATTR_ID_SUPPORTED_FORMATS_LIST,
    298         (UINT8) j, desc_type, type_len, type_value);
    299 
    300     /* set class of device */
    301     cod.service = BTM_COD_SERVICE_OBJ_TRANSFER;
    302     utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
    303 
    304     bta_sys_add_uuid(servclass); /* UUID_SERVCLASS_OBEX_OBJECT_PUSH */
    305 
    306     return sdp_handle;
    307 }
    308 #define SPP_NUM_PROTO_ELEMS 2
    309 static int add_spp_sdp(const char *service_name, int scn)
    310 {
    311     UINT16 serviceclassid = UUID_SERVCLASS_SERIAL_PORT;
    312     tSDP_PROTOCOL_ELEM  proto_elem_list[SPP_NUM_PROTO_ELEMS];
    313     int              sdp_handle;
    314 
    315     APPL_TRACE_DEBUG2("scn %d, service name %s", scn, service_name);
    316 
    317     /* register the service */
    318     if ((sdp_handle = SDP_CreateRecord()) != FALSE)
    319     {
    320         /*** Fill out the protocol element sequence for SDP ***/
    321         proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
    322         proto_elem_list[0].num_params = 0;
    323         proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
    324         proto_elem_list[1].num_params = 1;
    325 
    326         proto_elem_list[1].params[0] = scn;
    327 
    328         if (SDP_AddProtocolList(sdp_handle, SPP_NUM_PROTO_ELEMS, proto_elem_list))
    329         {
    330             if (SDP_AddServiceClassIdList(sdp_handle, 1, &serviceclassid))
    331             {
    332                 if ((SDP_AddAttribute(sdp_handle, ATTR_ID_SERVICE_NAME,
    333                                 TEXT_STR_DESC_TYPE, (UINT32)(strlen(service_name)+1),
    334                                 (UINT8 *)service_name)))
    335                 {
    336                     UINT16  list[1];
    337                     /* Make the service browseable */
    338                     list[0] = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
    339                     SDP_AddUuidSequence (sdp_handle,  ATTR_ID_BROWSE_GROUP_LIST,
    340                                     1, list);
    341                 }
    342             }
    343         }
    344     }
    345     return sdp_handle;
    346 }
    347 
    348 
    349 
    350 static int add_rfc_sdp_by_uuid(const char* name, const uint8_t* uuid, int scn)
    351 {
    352     int handle = 0;
    353 
    354     APPL_TRACE_DEBUG2("name:%s, scn:%d", name, scn);
    355 
    356     /*
    357         Bluetooth Socket API relies on having preregistered bluez sdp records for HSAG, HFAG, OPP & PBAP
    358         that are mapped to rc chan 10, 11,12 & 19. Today HSAG and HFAG is routed to BRCM AG and are not
    359         using BT socket API so for now we will need to support OPP and PBAP to enable 3rd party developer
    360         apps running on BRCM Android.
    361 
    362         To do this we will check the UUID for the requested service and mimic the SDP records of bluez
    363         upon reception.  See functions add_opush() and add_pbap() in sdptool.c for actual records
    364     */
    365 
    366     /* special handling for preregistered bluez services (OPP, PBAP) that we need to mimic */
    367 
    368     int final_scn = get_reserved_rfc_channel(uuid);
    369     if (final_scn == -1)
    370     {
    371         final_scn=scn;
    372     }
    373     if (IS_UUID(UUID_OBEX_OBJECT_PUSH,uuid))
    374     {
    375         handle = add_ops_sdp(name,final_scn);
    376     }
    377     else if (IS_UUID(UUID_PBAP_PSE,uuid))
    378     {
    379         handle = add_pbap_sdp(name, final_scn); //PBAP Server is always 19
    380     }
    381     else if (IS_UUID(UUID_SPP, uuid))
    382     {
    383         handle = add_spp_sdp(name, final_scn);
    384     }
    385     else
    386     {
    387         handle = add_sdp_by_uuid(name, uuid, final_scn);
    388     }
    389     return handle;
    390 }
    391 
    392 BOOLEAN is_reserved_rfc_channel(int scn)
    393 {
    394     switch(scn)
    395     {
    396         case RESERVED_SCN_PBS:
    397         case RESERVED_SCN_OPS:
    398             return TRUE;
    399     }
    400     return FALSE;
    401 }
    402 
    403 
    404 int get_reserved_rfc_channel (const uint8_t* uuid)
    405 {
    406     if (IS_UUID(UUID_PBAP_PSE,uuid))
    407     {
    408       return RESERVED_SCN_PBS;
    409     }
    410     else if (IS_UUID(UUID_OBEX_OBJECT_PUSH,uuid))
    411     {
    412       return RESERVED_SCN_OPS;
    413     }
    414     return -1;
    415 }
    416 
    417 int add_rfc_sdp_rec(const char* name, const uint8_t* uuid, int scn)
    418 {
    419     int sdp_handle = 0;
    420     if(is_uuid_empty(uuid))
    421     {
    422         switch(scn)
    423         {
    424             case RESERVED_SCN_PBS: // PBAP Reserved port
    425                 uuid = UUID_PBAP_PSE;
    426                 break;
    427              case RESERVED_SCN_OPS:
    428                 uuid = UUID_OBEX_OBJECT_PUSH;
    429                 break;
    430             default:
    431                 uuid = UUID_SPP;
    432                 break;
    433         }
    434     }
    435     sdp_handle = add_rfc_sdp_by_uuid(name, uuid, scn);
    436     return sdp_handle;
    437 }
    438 
    439 void del_rfc_sdp_rec(int handle)
    440 {
    441     APPL_TRACE_DEBUG1("del_rfc_sdp_rec: handle:0x%x", handle);
    442     if(handle != -1 && handle != 0)
    443         BTA_JvDeleteRecord( handle );
    444 }
    445 
    446