1 /******************************************************************************
2  *
3  *  Copyright 2014 Google, Inc.
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 #define LOG_TAG "bt_btif_sock_sdp"
20 
21 #include "btif/include/btif_sock_sdp.h"
22 
23 #include <bluetooth/log.h>
24 
25 #include "bta/include/bta_jv_api.h"
26 #include "bta/include/bta_op_api.h"
27 #include "bta/include/utl.h"
28 #include "bta/pb/bta_pbs_int.h"
29 #include "bta/sys/bta_sys.h"
30 #include "internal_include/bt_target.h"
31 #include "stack/include/bt_types.h"
32 #include "stack/include/bt_uuid16.h"
33 #include "stack/include/sdp_api.h"
34 #include "stack/include/sdpdefs.h"
35 #include "types/bluetooth/uuid.h"
36 
37 using namespace bluetooth::legacy::stack::sdp;
38 using namespace bluetooth;
39 
40 using bluetooth::Uuid;
41 
42 // This module provides an abstraction on top of the lower-level SDP database
43 // code for registration and discovery of various bluetooth sockets.
44 //
45 // This code also provides for on-demand registration of "pre-registered"
46 // services as a backwards compatibility function to third-party applications
47 // expecting a bluez stack.
48 
49 // Realm Character Set -- 0 is ASCII
50 #define BTA_PBS_REALM_CHARSET 0
51 
52 // Specifies whether or not client's user id is required during obex
53 // authentication
54 #define BTA_PBS_USERID_REQ FALSE
55 
56 static const tBTA_PBS_CFG bta_pbs_cfg = {
57         BTA_PBS_REALM_CHARSET,                          // realm_charset: Server only
58         BTA_PBS_USERID_REQ,                             // userid_req: Server only
59         (BTA_PBS_SUPF_DOWNLOAD | BTA_PBS_SURF_BROWSE),  // supported_features
60         BTA_PBS_REPOSIT_LOCAL,                          // supported_repositories
61 };
62 
63 // object format lookup table
64 #define OBEX_PUSH_NUM_FORMATS 7
65 
66 static const tBTA_OP_FMT bta_ops_obj_fmt[OBEX_PUSH_NUM_FORMATS] = {
67         BTA_OP_VCARD21_FMT, BTA_OP_VCARD30_FMT, BTA_OP_VCAL_FMT, BTA_OP_ICAL_FMT,
68         BTA_OP_VNOTE_FMT,   BTA_OP_VMSG_FMT,    BTA_OP_OTHER_FMT};
69 
70 // TODO(jtgans): Figure out if we actually need this define. This is ifndef
71 // defined in bt_target.h, but nowhere else, so right now, unless something
72 // overrides this before bt_target.h sets it, it will always be bt_target.h's
73 // version.
74 #ifndef BTUI_OPS_FORMATS
75 #define BTUI_OPS_FORMATS                                                             \
76   (BTA_OP_VCARD21_MASK | BTA_OP_VCARD30_MASK | BTA_OP_VCAL_MASK | BTA_OP_ICAL_MASK | \
77    BTA_OP_VNOTE_MASK | BTA_OP_VMSG_MASK | BTA_OP_ANY_MASK)
78 #endif
79 
80 #define RESERVED_SCN_PBS 19
81 #define RESERVED_SCN_OPS 12
82 
83 #define UUID_MAX_LENGTH 16
84 
85 #define SPP_PROFILE_VERSION 0x0102
86 
87 // Adds a protocol list and service name (if provided) to an SDP record given by
88 // |sdp_handle|, and marks it as browseable. This is a shortcut for defining a
89 // set of protocols that includes L2CAP, RFCOMM, and optionally OBEX. If
90 // |with_obex| is |true|, then an additional OBEX protocol UUID will be included
91 // at the end of the protocol list.
92 //
93 // Returns true if successful, otherwise false.
create_base_record(const uint32_t sdp_handle,const char * name,const uint16_t channel,const bool with_obex)94 static bool create_base_record(const uint32_t sdp_handle, const char* name, const uint16_t channel,
95                                const bool with_obex) {
96   log::verbose("create_base_record: scn: {}, name: {}, with_obex: {}", channel, name, with_obex);
97 
98   // Setup the protocol list and add it.
99   tSDP_PROTOCOL_ELEM proto_list[SDP_MAX_LIST_ELEMS];
100   int num_proto_elements = with_obex ? 3 : 2;
101 
102   memset(proto_list, 0, num_proto_elements * sizeof(tSDP_PROTOCOL_ELEM));
103 
104   proto_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
105   proto_list[0].num_params = 0;
106   proto_list[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
107   proto_list[1].num_params = 1;
108   proto_list[1].params[0] = channel;
109 
110   if (with_obex) {
111     proto_list[2].protocol_uuid = UUID_PROTOCOL_OBEX;
112     proto_list[2].num_params = 0;
113   }
114 
115   // Mark the service as browseable.
116   uint16_t list = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
117 
118   const char* stage = "protocol_list";
119   if (!get_legacy_stack_sdp_api()->handle.SDP_AddProtocolList(sdp_handle, num_proto_elements,
120                                                               proto_list)) {
121     goto error;
122   }
123 
124   // Add the name to the SDP record.
125   if (name[0] != '\0') {
126     stage = "service_name";
127     if (!get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
128                 sdp_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE, (uint32_t)strlen(name),
129                 (uint8_t*)name)) {
130       goto error;
131     }
132   }
133 
134   stage = "browseable";
135   if (!get_legacy_stack_sdp_api()->handle.SDP_AddUuidSequence(sdp_handle, ATTR_ID_BROWSE_GROUP_LIST,
136                                                               1, &list)) {
137     goto error;
138   }
139 
140   log::verbose(
141           "create_base_record: successfully created base service record, handle: "
142           "0x{:08x}, scn: {}, name: {}, with_obex: {}",
143           sdp_handle, channel, name, with_obex);
144   return true;
145 
146 error:
147   log::error(
148           "create_base_record: failed to create base service record, stage: {}, "
149           "scn: {}, name: {}, with_obex: {}",
150           stage, channel, name, with_obex);
151   return false;
152 }
153 
154 // Registers a service with the given |name|, |uuid|, and |channel| in the SDP
155 // database as a generic L2CAP RFCOMM protocol, storing its |uuid| as a service
156 // class sequence.
add_sdp_by_uuid(const char * name,const Uuid & uuid,const uint16_t channel)157 static int add_sdp_by_uuid(const char* name, const Uuid& uuid, const uint16_t channel) {
158   log::verbose("uuid: {}, scn: {}, service_name: {}", uuid.ToString(), channel, name);
159 
160   uint32_t handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
161   if (handle == 0) {
162     log::error("failed to create sdp record, scn: {}, service_name: {}", channel, name);
163     return 0;
164   }
165 
166   // Convert the |uuid| into a big-endian representation and add it as a
167   // sequence.
168   uint8_t type = UUID_DESC_TYPE;
169   uint8_t type_len = UUID_MAX_LENGTH;
170   uint8_t type_buf[48];
171   // Store the address of type buf in a pointer on the stack, so we can pass
172   // a double pointer to SDP_AddSequence
173   uint8_t* type_buf_ptr = type_buf;
174   uint8_t* tmp = type_buf;
175 
176   // Create the base SDP record.
177   const char* stage = "create_base_record";
178   if (!create_base_record(handle, name, channel, false /* with_obex */)) {
179     goto error;
180   }
181 
182   // Do the conversion to big-endian -- tmp is only used to iterate through the
183   // UUID array in the macro and serves no other purpose as the conversion
184   // macros are not hygenic.
185 
186   { ARRAY_TO_BE_STREAM(tmp, uuid.To128BitBE().data(), UUID_MAX_LENGTH); }
187 
188   stage = "service_class_sequence";
189   if (!get_legacy_stack_sdp_api()->handle.SDP_AddSequence(handle,
190                                                           (uint16_t)ATTR_ID_SERVICE_CLASS_ID_LIST,
191                                                           1, &type, &type_len, &type_buf_ptr)) {
192     goto error;
193   }
194 
195   log::verbose("service registered successfully, service_name: {}, handle: 0x{:08x}", name, handle);
196 
197   {
198     // Write the custom 128-bit UUID to EIR
199     tBTA_CUSTOM_UUID curr = {uuid, handle};
200     bta_sys_add_cust_uuid(curr);
201   }
202 
203   return handle;
204 
205 error:
206   if (get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(handle)) {
207     log::warn("Unable to delete SDP record handle:{}", handle);
208   }
209   log::error("failed to register service stage: {}, service_name: {}", stage, name);
210   return 0;
211 }
212 
213 // Registers a service with the given |name| and |channel| in the SDP
214 // database as a PBAP protocol.
add_pbap_sdp(const char * name,const int channel)215 static int add_pbap_sdp(const char* name, const int channel) {
216   log::verbose("add_pbap_sdp: scn {}, service_name {}", channel, name);
217 
218   uint32_t handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
219   if (handle == 0) {
220     log::error("add_pbap_sdp: failed to create sdp record, service_name: {}", name);
221     return 0;
222   }
223 
224   uint16_t service = UUID_SERVCLASS_PBAP_PSE;
225 
226   // Create the base SDP record.
227   const char* stage = "create_base_record";
228   if (!create_base_record(handle, name, channel, true /* with_obex */)) {
229     goto error;
230   }
231 
232   // Add service class
233   stage = "service_class";
234   if (!get_legacy_stack_sdp_api()->handle.SDP_AddServiceClassIdList(handle, 1, &service)) {
235     goto error;
236   }
237 
238   // Add in the phone access descriptor
239   stage = "profile_descriptor_list";
240   if (!get_legacy_stack_sdp_api()->handle.SDP_AddProfileDescriptorList(
241               handle, UUID_SERVCLASS_PHONE_ACCESS, BTA_PBS_DEFAULT_VERSION)) {
242     goto error;
243   }
244 
245   // Set up our supported repositories
246   stage = "supported_repositories";
247   if (!get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
248               handle, ATTR_ID_SUPPORTED_REPOSITORIES, UINT_DESC_TYPE, 1,
249               (uint8_t*)&bta_pbs_cfg.supported_repositories)) {
250     goto error;
251   }
252 
253   // Notify the system that we've got a new service class UUID.
254   bta_sys_add_uuid(UUID_SERVCLASS_PBAP_PSE);
255   log::verbose(
256           "add_pbap_sdp: service registered successfully, service_name: {}, "
257           "handle: 0x{:08x}",
258           name, handle);
259 
260   return handle;
261 
262 error:
263   if (get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(handle)) {
264     log::warn("Unable to delete SDP record handle:{}", handle);
265   }
266   log::error(
267           "add_pbap_sdp: failed to register PBAP service, stage: {}, service_name: "
268           "{}",
269           stage, name);
270   return 0;
271 }
272 // Registers a service with the given |name| and |channel| as an OBEX Push
273 // protocol.
add_ops_sdp(const char * name,const int channel)274 static int add_ops_sdp(const char* name, const int channel) {
275   log::verbose("add_ops_sdp: scn {}, service_name {}", channel, name);
276 
277   uint32_t handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
278   if (handle == 0) {
279     log::error("add_ops_sdp: failed to create sdp record, service_name: {}", name);
280     return 0;
281   }
282 
283   // Add sequence for supported types.
284   uint8_t desc_type[OBEX_PUSH_NUM_FORMATS];
285   uint8_t type_len[OBEX_PUSH_NUM_FORMATS];
286   uint8_t* type_value[OBEX_PUSH_NUM_FORMATS];
287   uint8_t j = 0;
288 
289   uint16_t service = UUID_SERVCLASS_OBEX_OBJECT_PUSH;
290   tBTA_UTL_COD cod;
291 
292   // Create the base SDP record.
293   const char* stage = "create_base_record";
294   if (!create_base_record(handle, name, channel, true /* with_obex */)) {
295     goto error;
296   }
297 
298   // Add service class.
299   stage = "service_class";
300   if (!get_legacy_stack_sdp_api()->handle.SDP_AddServiceClassIdList(handle, 1, &service)) {
301     goto error;
302   }
303 
304   // Add the OBEX push profile descriptor.
305   stage = "profile_descriptor_list";
306   if (!get_legacy_stack_sdp_api()->handle.SDP_AddProfileDescriptorList(
307               handle, UUID_SERVCLASS_OBEX_OBJECT_PUSH, 0x0100)) {
308     goto error;
309   }
310 
311   for (int i = 0; i < OBEX_PUSH_NUM_FORMATS; i++) {
312     if ((BTUI_OPS_FORMATS >> i) & 1) {
313       type_value[j] = (uint8_t*)(&bta_ops_obj_fmt[i]);
314       desc_type[j] = UINT_DESC_TYPE;
315       type_len[j++] = 1;
316     }
317   }
318 
319   stage = "supported_types";
320   if (!get_legacy_stack_sdp_api()->handle.SDP_AddSequence(handle,
321                                                           (uint16_t)ATTR_ID_SUPPORTED_FORMATS_LIST,
322                                                           j, desc_type, type_len, type_value)) {
323     goto error;
324   }
325 
326   // Set class of device.
327   cod.service = BTM_COD_SERVICE_OBJ_TRANSFER;
328   stage = "class_of_device";
329   if (!utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS)) {
330     goto error;
331   }
332 
333   // Notify the system that we've got a new service class UUID.
334   bta_sys_add_uuid(UUID_SERVCLASS_OBEX_OBJECT_PUSH);
335   log::verbose(
336           "ad_maps_sdp: service registered successfully, service_name: {}, handle "
337           "0x{:08x})",
338           name, handle);
339 
340   return handle;
341 
342 error:
343   if (get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(handle)) {
344     log::warn("Unable to delete SDP record handle:{}", handle);
345   }
346   log::error(
347           "add_ops_sdp: failed to register OPS service, stage: {}, service_name: "
348           "{}",
349           stage, name);
350   return 0;
351 }
352 
353 // Registers a service with the given |name| and |channel| as a serial port
354 // profile protocol.
add_spp_sdp(const char * name,const int channel)355 static int add_spp_sdp(const char* name, const int channel) {
356   log::verbose("add_spp_sdp: scn {}, service_name {}", channel, name);
357 
358   int handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
359   if (handle == 0) {
360     log::error("add_spp_sdp: failed to create sdp record, service_name: {}", name);
361     return 0;
362   }
363 
364   // Create the base SDP record.
365   const char* stage = "create_base_record";
366   uint16_t service = UUID_SERVCLASS_SERIAL_PORT;
367 
368   if (!create_base_record(handle, name, channel, false /* with_obex */)) {
369     goto error;
370   }
371 
372   stage = "service_class";
373   if (!get_legacy_stack_sdp_api()->handle.SDP_AddServiceClassIdList(handle, 1, &service)) {
374     goto error;
375   }
376 
377   stage = "profile_descriptor_list";
378   if (!get_legacy_stack_sdp_api()->handle.SDP_AddProfileDescriptorList(
379               handle, UUID_SERVCLASS_SERIAL_PORT, SPP_PROFILE_VERSION)) {
380     goto error;
381   }
382 
383   log::verbose(
384           "add_spp_sdp: service registered successfully, service_name: {}, handle "
385           "0x{:08x})",
386           name, handle);
387 
388   return handle;
389 
390 error:
391   if (get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(handle)) {
392     log::warn("Unable to delete SDP record handle:{}", handle);
393   }
394   log::error(
395           "add_spp_sdp: failed to register SPP service, stage: {}, service_name: "
396           "{}",
397           stage, name);
398   return 0;
399 }
400 
401 // Adds an RFCOMM SDP record for a service with the given |name|, |uuid|, and
402 // |channel|. This function attempts to identify the type of the service based
403 // upon its |uuid|, and will override the |channel| with a reserved channel
404 // number if the |uuid| matches one of the preregistered bluez SDP records.
add_rfc_sdp_by_uuid(const char * name,const Uuid & uuid,const int channel)405 static int add_rfc_sdp_by_uuid(const char* name, const Uuid& uuid, const int channel) {
406   log::verbose("uuid: {}, service_name: {}, channel: {}", uuid.ToString(), name, channel);
407 
408   /*
409    * Bluetooth Socket API relies on having preregistered bluez sdp records for
410    * HSAG, HFAG, OPP & PBAP that are mapped to rc chan 10, 11,12 & 19. Today
411    * HSAG and HFAG is routed to BRCM AG and are not using BT socket API so for
412    * now we will need to support OPP and PBAP to enable 3rd party developer apps
413    * running on BRCM Android.
414    *
415    * To do this we will check the UUID for the requested service and mimic the
416    * SDP records of bluez upon reception.  See functions add_opush() and
417    * add_pbap() in sdptool.c for actual records.
418    */
419 
420   int final_channel = get_reserved_rfc_channel(uuid);
421 
422   if (final_channel == -1) {
423     final_channel = channel;
424   }
425 
426   int handle = 0;
427 
428   if (uuid == UUID_OBEX_OBJECT_PUSH) {
429     handle = add_ops_sdp(name, final_channel);
430   } else if (uuid == UUID_PBAP_PSE) {
431     // PBAP Server is always channel 19
432     handle = add_pbap_sdp(name, final_channel);
433   } else if (uuid == UUID_SPP) {
434     handle = add_spp_sdp(name, final_channel);
435   } else if (uuid == UUID_MAP_MAS) {
436     // Record created by new SDP create record interface
437     handle = 0xff;
438   } else {
439     handle = add_sdp_by_uuid(name, uuid, final_channel);
440   }
441 
442   return handle;
443 }
444 
is_reserved_rfc_channel(const int channel)445 bool is_reserved_rfc_channel(const int channel) {
446   switch (channel) {
447     case RESERVED_SCN_PBS:
448     case RESERVED_SCN_OPS:
449       return true;
450   }
451 
452   return false;
453 }
454 
get_reserved_rfc_channel(const bluetooth::Uuid & uuid)455 int get_reserved_rfc_channel(const bluetooth::Uuid& uuid) {
456   if (uuid == UUID_PBAP_PSE) {
457     return RESERVED_SCN_PBS;
458   } else if (uuid == UUID_OBEX_OBJECT_PUSH) {
459     return RESERVED_SCN_OPS;
460   }
461 
462   return -1;
463 }
464 
465 // Adds an SDP record to the SDP database using the given |name|, |uuid|, and
466 // |channel|. Note that if the |uuid| is empty, the |uuid| will be set based
467 // upon the |channel| passed in.
add_rfc_sdp_rec(const char * name,Uuid uuid,const int channel)468 int add_rfc_sdp_rec(const char* name, Uuid uuid, const int channel) {
469   if (uuid.IsEmpty()) {
470     switch (channel) {
471       case RESERVED_SCN_PBS:  // PBAP Reserved port
472         uuid = UUID_PBAP_PSE;
473         break;
474 
475       case RESERVED_SCN_OPS:
476         uuid = UUID_OBEX_OBJECT_PUSH;
477         break;
478 
479       default:
480         uuid = UUID_SPP;
481         break;
482     }
483   }
484 
485   return add_rfc_sdp_by_uuid(name, uuid, channel);
486 }
487 
488 // Deletes an SDP record with the given |handle|.
del_rfc_sdp_rec(int handle)489 void del_rfc_sdp_rec(int handle) {
490   log::verbose("del_rfc_sdp_rec: handle:0x{:x}", handle);
491 
492   if ((handle != -1) && (handle != 0)) {
493     // Remove the custom 128-bit UUID from EIR
494     const tBTA_CUSTOM_UUID curr = {Uuid::kEmpty, (uint32_t)handle};
495     bta_sys_remove_cust_uuid(curr);
496 
497     BTA_JvDeleteRecord(handle);
498   }
499 }
500