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