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