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