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