OSDN Git Service

00671a0e2cff735672888cb44fd8688ee58c47fc
[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 <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_ERROR("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_DEBUG("add_pbap_sdd:scn %d, service name %s", scn, p_service_name);
147
148     if ((sdp_handle = SDP_CreateRecord()) == 0)
149     {
150         APPL_TRACE_ERROR("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_ERROR("bta_pbs_sdp_register FAILED");
202     }
203     else
204     {
205         bta_sys_add_uuid(pbs_service);  /* UUID_SERVCLASS_PBAP_PSE */
206         APPL_TRACE_DEBUG("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_DEBUG("add_maps_sdd:scn %d, service name %s", scn, p_service_name);
252
253     if ((sdp_handle = SDP_CreateRecord()) == 0)
254     {
255         APPL_TRACE_ERROR("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_ERROR("bta_mass_sdp_register FAILED");
308     }
309     else
310     {
311         bta_sys_add_uuid(service);  /* UUID_SERVCLASS_MESSAGE_ACCESS */
312         APPL_TRACE_DEBUG("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_DEBUG("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_DEBUG("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 static int add_rfc_sdp_by_uuid(const char* name, const uint8_t* uuid, int scn)
454 {
455     int handle = 0;
456
457     APPL_TRACE_DEBUG("name:%s, scn:%d", name, scn);
458
459     /*
460         Bluetooth Socket API relies on having preregistered bluez sdp records for HSAG, HFAG, OPP & PBAP
461         that are mapped to rc chan 10, 11,12 & 19. Today HSAG and HFAG is routed to BRCM AG and are not
462         using BT socket API so for now we will need to support OPP and PBAP to enable 3rd party developer
463         apps running on BRCM Android.
464
465         To do this we will check the UUID for the requested service and mimic the SDP records of bluez
466         upon reception.  See functions add_opush() and add_pbap() in sdptool.c for actual records
467     */
468
469     /* special handling for preregistered bluez services (OPP, PBAP) that we need to mimic */
470
471     int final_scn = get_reserved_rfc_channel(uuid);
472     if (final_scn == -1)
473     {
474         final_scn=scn;
475     }
476     if (IS_UUID(UUID_OBEX_OBJECT_PUSH,uuid))
477     {
478         handle = add_ops_sdp(name,final_scn);
479     }
480     else if (IS_UUID(UUID_PBAP_PSE,uuid))
481     {
482         handle = add_pbap_sdp(name, final_scn); //PBAP Server is always 19
483     }
484     else if (IS_UUID(UUID_MAPS_MAS,uuid))
485     {
486         handle = add_maps_sdp(name, final_scn); //MAP Server is always 19
487     }
488     else if (IS_UUID(UUID_SPP, uuid))
489     {
490         handle = add_spp_sdp(name, final_scn);
491     }
492     else
493     {
494         handle = add_sdp_by_uuid(name, uuid, final_scn);
495     }
496     return handle;
497 }
498
499 BOOLEAN is_reserved_rfc_channel(int scn)
500 {
501     switch(scn)
502     {
503         case RESERVED_SCN_PBS:
504         case RESERVED_SCN_OPS:
505             return TRUE;
506     }
507     return FALSE;
508 }
509
510
511 int get_reserved_rfc_channel (const uint8_t* uuid)
512 {
513     if (IS_UUID(UUID_PBAP_PSE,uuid))
514     {
515       return RESERVED_SCN_PBS;
516     }
517     else if (IS_UUID(UUID_OBEX_OBJECT_PUSH,uuid))
518     {
519       return RESERVED_SCN_OPS;
520     }
521     return -1;
522 }
523
524 int add_rfc_sdp_rec(const char* name, const uint8_t* uuid, int scn)
525 {
526     int sdp_handle = 0;
527     if(is_uuid_empty(uuid))
528     {
529         switch(scn)
530         {
531             case RESERVED_SCN_PBS: // PBAP Reserved port
532                 uuid = UUID_PBAP_PSE;
533                 break;
534              case RESERVED_SCN_OPS:
535                 uuid = UUID_OBEX_OBJECT_PUSH;
536                 break;
537             default:
538                 uuid = UUID_SPP;
539                 break;
540         }
541     }
542     sdp_handle = add_rfc_sdp_by_uuid(name, uuid, scn);
543     return sdp_handle;
544 }
545
546 void del_rfc_sdp_rec(int handle)
547 {
548     APPL_TRACE_DEBUG("del_rfc_sdp_rec: handle:0x%x", handle);
549     if(handle != -1 && handle != 0)
550         BTA_JvDeleteRecord( handle );
551 }
552