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 <cutils/log.h>
     55 
     56 #define RESERVED_SCN_PBS 19
     57 #define RESERVED_SCN_OPS 12
     58 
     59 #define UUID_MAX_LENGTH 16
     60 
     61 
     62 #define IS_UUID(u1,u2)  !memcmp(u1,u2,UUID_MAX_LENGTH)
     63 
     64 
     65 #define BTM_NUM_PROTO_ELEMS 2
     66 static int add_sdp_by_uuid(const char *name,  const uint8_t *service_uuid, UINT16 channel)
     67 {
     68 
     69     UINT32 btm_sdp_handle;
     70 
     71     tSDP_PROTOCOL_ELEM  proto_elem_list[BTM_NUM_PROTO_ELEMS];
     72 
     73     /* register the service */
     74     if ((btm_sdp_handle = SDP_CreateRecord()) != FALSE)
     75     {
     76         /*** Fill out the protocol element sequence for SDP ***/
     77         proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
     78         proto_elem_list[0].num_params = 0;
     79         proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
     80         proto_elem_list[1].num_params = 1;
     81 
     82         proto_elem_list[1].params[0] = channel;
     83 
     84         if (SDP_AddProtocolList(btm_sdp_handle, BTM_NUM_PROTO_ELEMS,
     85             proto_elem_list))
     86         {
     87             UINT8           buff[48];
     88             UINT8           *p, *type_buf[1];
     89             UINT8       type[1], type_len[1];
     90          p = type_buf[0] = buff;
     91          type[0] = UUID_DESC_TYPE;
     92 
     93 //         UINT8_TO_BE_STREAM  (p, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES);
     94          ARRAY_TO_BE_STREAM (p, service_uuid, 16);
     95             type_len[0] = 16;
     96             if( SDP_AddSequence(btm_sdp_handle, (UINT16) ATTR_ID_SERVICE_CLASS_ID_LIST,
     97                           1, type, type_len, type_buf) )
     98 //            if (SDP_AddServiceClassIdList(btm_sdp_handle, 1, &service_uuid))
     99             {
    100                 if ((SDP_AddAttribute(btm_sdp_handle, ATTR_ID_SERVICE_NAME,
    101                     TEXT_STR_DESC_TYPE, (UINT32)(strlen(name)+1),
    102                     (UINT8 *)name)) )
    103                 {
    104                     UINT16  list[1];
    105 
    106                     /* Make the service browseable */
    107                     list[0] = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
    108                     if ((SDP_AddUuidSequence (btm_sdp_handle,  ATTR_ID_BROWSE_GROUP_LIST,
    109                         1, list)) )
    110 
    111                         return btm_sdp_handle;
    112                 }
    113             }
    114         }
    115     }
    116 
    117     return 0;
    118 }
    119 
    120 
    121 /* Realm Character Set */
    122 #define BTA_PBS_REALM_CHARSET   0       /* ASCII */
    123 
    124 /* Specifies whether or not client's user id is required during obex authentication */
    125 #define BTA_PBS_USERID_REQ      FALSE
    126 extern const tBTA_PBS_CFG bta_pbs_cfg;
    127 const tBTA_PBS_CFG bta_pbs_cfg =
    128 {
    129     BTA_PBS_REALM_CHARSET,      /* Server only */
    130     BTA_PBS_USERID_REQ,         /* Server only */
    131     (BTA_PBS_SUPF_DOWNLOAD | BTA_PBS_SURF_BROWSE),
    132     BTA_PBS_REPOSIT_LOCAL,
    133 };
    134 
    135 static int add_pbap_sdp(const char* p_service_name, int scn)
    136 {
    137 
    138     tSDP_PROTOCOL_ELEM  protoList [3];
    139     UINT16              pbs_service = UUID_SERVCLASS_PBAP_PSE;
    140     UINT16              browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
    141     BOOLEAN             status = FALSE;
    142     UINT32              sdp_handle = 0;
    143     tBTA_PBS_CFG *p_bta_pbs_cfg = (tBTA_PBS_CFG *)&bta_pbs_cfg;
    144 
    145     APPL_TRACE_DEBUG2("scn %d, service name %s", scn, p_service_name);
    146 
    147     if ((sdp_handle = SDP_CreateRecord()) == 0)
    148     {
    149         APPL_TRACE_ERROR0("PBS SDP: Unable to register PBS Service");
    150         return sdp_handle;
    151     }
    152 
    153     /* add service class */
    154     if (SDP_AddServiceClassIdList(sdp_handle, 1, &pbs_service))
    155     {
    156         memset( protoList, 0 , 3*sizeof(tSDP_PROTOCOL_ELEM) );
    157         /* add protocol list, including RFCOMM scn */
    158         protoList[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
    159         protoList[0].num_params = 0;
    160         protoList[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
    161         protoList[1].num_params = 1;
    162         protoList[1].params[0] = scn;
    163         protoList[2].protocol_uuid = UUID_PROTOCOL_OBEX;
    164         protoList[2].num_params = 0;
    165 
    166         if (SDP_AddProtocolList(sdp_handle, 3, protoList))
    167         {
    168             status = TRUE;  /* All mandatory fields were successful */
    169 
    170             /* optional:  if name is not "", add a name entry */
    171             if (*p_service_name != '\0')
    172                 SDP_AddAttribute(sdp_handle,
    173                                  (UINT16)ATTR_ID_SERVICE_NAME,
    174                                  (UINT8)TEXT_STR_DESC_TYPE,
    175                                  (UINT32)(strlen(p_service_name) + 1),
    176                                  (UINT8 *)p_service_name);
    177 
    178             /* Add in the Bluetooth Profile Descriptor List */
    179             SDP_AddProfileDescriptorList(sdp_handle,
    180                                              UUID_SERVCLASS_PHONE_ACCESS,
    181                                              BTA_PBS_DEFAULT_VERSION);
    182 
    183         } /* end of setting mandatory protocol list */
    184     } /* end of setting mandatory service class */
    185 
    186     /* add supported feature and repositories */
    187     if (status)
    188     {
    189         SDP_AddAttribute(sdp_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE,
    190                   (UINT32)1, (UINT8*)&p_bta_pbs_cfg->supported_features);
    191         SDP_AddAttribute(sdp_handle, ATTR_ID_SUPPORTED_REPOSITORIES, UINT_DESC_TYPE,
    192                   (UINT32)1, (UINT8*)&p_bta_pbs_cfg->supported_repositories);
    193 
    194         /* Make the service browseable */
    195         SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
    196     }
    197 
    198     if (!status)
    199     {
    200         SDP_DeleteRecord(sdp_handle);
    201         sdp_handle = 0;
    202         APPL_TRACE_ERROR0("bta_pbs_sdp_register FAILED");
    203     }
    204     else
    205     {
    206         bta_sys_add_uuid(pbs_service);  /* UUID_SERVCLASS_PBAP_PSE */
    207         APPL_TRACE_DEBUG1("PBS:  SDP Registered (handle 0x%08x)", sdp_handle);
    208     }
    209 
    210     return sdp_handle;
    211 }
    212 
    213 
    214 /* object format lookup table */
    215 static const tBTA_OP_FMT bta_ops_obj_fmt[] =
    216 {
    217     BTA_OP_VCARD21_FMT,
    218     BTA_OP_VCARD30_FMT,
    219     BTA_OP_VCAL_FMT,
    220     BTA_OP_ICAL_FMT,
    221     BTA_OP_VNOTE_FMT,
    222     BTA_OP_VMSG_FMT,
    223     BTA_OP_OTHER_FMT
    224 };
    225 
    226 #define BTA_OPS_NUM_FMTS        7
    227 #define BTA_OPS_PROTOCOL_COUNT  3
    228 
    229 #ifndef BTUI_OPS_FORMATS
    230 #define BTUI_OPS_FORMATS            (BTA_OP_VCARD21_MASK | BTA_OP_VCARD30_MASK | \
    231                                          BTA_OP_VCAL_MASK | BTA_OP_ICAL_MASK | \
    232                                          BTA_OP_VNOTE_MASK | BTA_OP_VMSG_MASK | \
    233                                          BTA_OP_ANY_MASK )
    234 #endif
    235 
    236 static int add_ops_sdp(const char *p_service_name,int scn)
    237 {
    238 
    239 
    240     tSDP_PROTOCOL_ELEM  protoList [BTA_OPS_PROTOCOL_COUNT];
    241     UINT16      servclass = UUID_SERVCLASS_OBEX_OBJECT_PUSH;
    242     int         i, j;
    243     tBTA_UTL_COD cod;
    244     UINT8       desc_type[BTA_OPS_NUM_FMTS];
    245     UINT8       type_len[BTA_OPS_NUM_FMTS];
    246     UINT8       *type_value[BTA_OPS_NUM_FMTS];
    247     UINT16      browse;
    248     UINT32 sdp_handle;
    249     tBTA_OP_FMT_MASK    formats = BTUI_OPS_FORMATS;
    250 
    251     APPL_TRACE_DEBUG2("scn %d, service name %s", scn, p_service_name);
    252 
    253     sdp_handle = SDP_CreateRecord();
    254 
    255     /* add service class */
    256     if (SDP_AddServiceClassIdList(sdp_handle, 1, &servclass))
    257     {
    258         /* add protocol list, including RFCOMM scn */
    259         protoList[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
    260         protoList[0].num_params = 0;
    261         protoList[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
    262         protoList[1].num_params = 1;
    263         protoList[1].params[0] = scn;
    264         protoList[2].protocol_uuid = UUID_PROTOCOL_OBEX;
    265         protoList[2].num_params = 0;
    266 
    267         if (SDP_AddProtocolList(sdp_handle, BTA_OPS_PROTOCOL_COUNT, protoList))
    268         {
    269             SDP_AddAttribute(sdp_handle,
    270                (UINT16)ATTR_ID_SERVICE_NAME,
    271                 (UINT8)TEXT_STR_DESC_TYPE,
    272                 (UINT32)(strlen(p_service_name) + 1),
    273                 (UINT8 *)p_service_name);
    274 
    275             SDP_AddProfileDescriptorList(sdp_handle,
    276                 UUID_SERVCLASS_OBEX_OBJECT_PUSH,
    277                 0x0100);
    278         }
    279     }
    280 
    281     /* Make the service browseable */
    282     browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
    283     SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
    284 
    285     /* add sequence for supported types */
    286     for (i = 0, j = 0; i < BTA_OPS_NUM_FMTS; i++)
    287     {
    288         if ((formats >> i) & 1)
    289         {
    290             type_value[j] = (UINT8 *) &bta_ops_obj_fmt[i];
    291             desc_type[j] = UINT_DESC_TYPE;
    292             type_len[j++] = 1;
    293         }
    294     }
    295 
    296     SDP_AddSequence(sdp_handle, (UINT16) ATTR_ID_SUPPORTED_FORMATS_LIST,
    297         (UINT8) j, desc_type, type_len, type_value);
    298 
    299     /* set class of device */
    300     cod.service = BTM_COD_SERVICE_OBJ_TRANSFER;
    301     utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
    302 
    303     bta_sys_add_uuid(servclass); /* UUID_SERVCLASS_OBEX_OBJECT_PUSH */
    304 
    305     return sdp_handle;
    306 }
    307 #define SPP_NUM_PROTO_ELEMS 2
    308 static int add_spp_sdp(const char *service_name, int scn)
    309 {
    310     UINT16 serviceclassid = UUID_SERVCLASS_SERIAL_PORT;
    311     tSDP_PROTOCOL_ELEM  proto_elem_list[SPP_NUM_PROTO_ELEMS];
    312     int              sdp_handle;
    313 
    314     APPL_TRACE_DEBUG2("scn %d, service name %s", scn, service_name);
    315 
    316     /* register the service */
    317     if ((sdp_handle = SDP_CreateRecord()) != FALSE)
    318     {
    319         /*** Fill out the protocol element sequence for SDP ***/
    320         proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
    321         proto_elem_list[0].num_params = 0;
    322         proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
    323         proto_elem_list[1].num_params = 1;
    324 
    325         proto_elem_list[1].params[0] = scn;
    326 
    327         if (SDP_AddProtocolList(sdp_handle, SPP_NUM_PROTO_ELEMS, proto_elem_list))
    328         {
    329             if (SDP_AddServiceClassIdList(sdp_handle, 1, &serviceclassid))
    330             {
    331                 if ((SDP_AddAttribute(sdp_handle, ATTR_ID_SERVICE_NAME,
    332                                 TEXT_STR_DESC_TYPE, (UINT32)(strlen(service_name)+1),
    333                                 (UINT8 *)service_name)))
    334                 {
    335                     UINT16  list[1];
    336                     /* Make the service browseable */
    337                     list[0] = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
    338                     SDP_AddUuidSequence (sdp_handle,  ATTR_ID_BROWSE_GROUP_LIST,
    339                                     1, list);
    340                 }
    341             }
    342         }
    343     }
    344     return sdp_handle;
    345 }
    346 
    347 
    348 
    349 static int add_rfc_sdp_by_uuid(const char* name, const uint8_t* uuid, int scn)
    350 {
    351     int handle = 0;
    352 
    353     APPL_TRACE_DEBUG2("name:%s, scn:%d", name, scn);
    354 
    355     /*
    356         Bluetooth Socket API relies on having preregistered bluez sdp records for HSAG, HFAG, OPP & PBAP
    357         that are mapped to rc chan 10, 11,12 & 19. Today HSAG and HFAG is routed to BRCM AG and are not
    358         using BT socket API so for now we will need to support OPP and PBAP to enable 3rd party developer
    359         apps running on BRCM Android.
    360 
    361         To do this we will check the UUID for the requested service and mimic the SDP records of bluez
    362         upon reception.  See functions add_opush() and add_pbap() in sdptool.c for actual records
    363     */
    364 
    365     /* special handling for preregistered bluez services (OPP, PBAP) that we need to mimic */
    366 
    367     int final_scn = get_reserved_rfc_channel(uuid);
    368     if (final_scn == -1)
    369     {
    370         final_scn=scn;
    371     }
    372     if (IS_UUID(UUID_OBEX_OBJECT_PUSH,uuid))
    373     {
    374         handle = add_ops_sdp(name,final_scn);
    375     }
    376     else if (IS_UUID(UUID_PBAP_PSE,uuid))
    377     {
    378         handle = add_pbap_sdp(name, final_scn); //PBAP Server is always 19
    379     }
    380     else if (IS_UUID(UUID_SPP, uuid))
    381     {
    382         handle = add_spp_sdp(name, final_scn);
    383     }
    384     else
    385     {
    386         handle = add_sdp_by_uuid(name, uuid, final_scn);
    387     }
    388     return handle;
    389 }
    390 
    391 BOOLEAN is_reserved_rfc_channel(int scn)
    392 {
    393     switch(scn)
    394     {
    395         case RESERVED_SCN_PBS:
    396         case RESERVED_SCN_OPS:
    397             return TRUE;
    398     }
    399     return FALSE;
    400 }
    401 
    402 
    403 int get_reserved_rfc_channel (const uint8_t* uuid)
    404 {
    405     if (IS_UUID(UUID_PBAP_PSE,uuid))
    406     {
    407       return RESERVED_SCN_PBS;
    408     }
    409     else if (IS_UUID(UUID_OBEX_OBJECT_PUSH,uuid))
    410     {
    411       return RESERVED_SCN_OPS;
    412     }
    413     return -1;
    414 }
    415 
    416 int add_rfc_sdp_rec(const char* name, const uint8_t* uuid, int scn)
    417 {
    418     int sdp_handle = 0;
    419     if(is_uuid_empty(uuid))
    420     {
    421         switch(scn)
    422         {
    423             case RESERVED_SCN_PBS: // PBAP Reserved port
    424                 uuid = UUID_PBAP_PSE;
    425                 break;
    426              case RESERVED_SCN_OPS:
    427                 uuid = UUID_OBEX_OBJECT_PUSH;
    428                 break;
    429             default:
    430                 uuid = UUID_SPP;
    431                 break;
    432         }
    433     }
    434     sdp_handle = add_rfc_sdp_by_uuid(name, uuid, scn);
    435     return sdp_handle;
    436 }
    437 
    438 void del_rfc_sdp_rec(int handle)
    439 {
    440     if(handle != -1 && handle != 0)
    441         SDP_DeleteRecord( handle );
    442 }
    443 
    444