OSDN Git Service

am ba2f6d99: (-s ours) Revert "anthias:17614185:Bluetooth: Getbuf returning invalid...
[android-x86/system-bt.git] / btif / src / btif_sock_sdp.c
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