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
add_sdp_by_uuid(const char * name,const uint8_t * service_uuid,UINT16 channel)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
add_pbap_sdp(const char * p_service_name,int scn)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
add_maps_sdp(const char * p_service_name,int scn)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
add_ops_sdp(const char * p_service_name,int scn)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
add_spp_sdp(const char * service_name,int scn)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
add_rfc_sdp_by_uuid(const char * name,const uint8_t * uuid,int scn)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
is_reserved_rfc_channel(int scn)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
get_reserved_rfc_channel(const uint8_t * uuid)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
add_rfc_sdp_rec(const char * name,const uint8_t * uuid,int scn)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
del_rfc_sdp_rec(int handle)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