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:      bluetooth.c
22 *
23 *  Description:   Bluetooth HAL implementation
24 *
25 ***********************************************************************************/
26
27#define LOG_TAG "bt_btif"
28
29#include <assert.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33#include <unistd.h>
34
35#include <hardware/bluetooth.h>
36#include <hardware/bt_av.h>
37#include <hardware/bt_gatt.h>
38#include <hardware/bt_hf.h>
39#include <hardware/bt_hf_client.h>
40#include <hardware/bt_hh.h>
41#include <hardware/bt_hl.h>
42#include <hardware/bt_mce.h>
43#include <hardware/bt_pan.h>
44#include <hardware/bt_rc.h>
45#include <hardware/bt_sdp.h>
46#include <hardware/bt_sock.h>
47
48#include "bt_utils.h"
49#include "btif_api.h"
50#include "btif_debug.h"
51#include "btsnoop.h"
52#include "btsnoop_mem.h"
53#include "device/include/interop.h"
54#include "osi/include/allocation_tracker.h"
55#include "osi/include/alarm.h"
56#include "osi/include/log.h"
57#include "osi/include/metrics.h"
58#include "osi/include/osi.h"
59#include "osi/include/wakelock.h"
60#include "stack_manager.h"
61#include "btif_config.h"
62#include "btif_storage.h"
63#include "btif/include/btif_debug_btsnoop.h"
64#include "btif/include/btif_debug_conn.h"
65#include "btif/include/btif_debug_l2c.h"
66#include "btif/include/btif_media.h"
67
68/************************************************************************************
69**  Static variables
70************************************************************************************/
71
72bt_callbacks_t *bt_hal_cbacks = NULL;
73bool restricted_mode = FALSE;
74
75/************************************************************************************
76**  Externs
77************************************************************************************/
78
79/* list all extended interfaces here */
80
81/* handsfree profile */
82extern bthf_interface_t *btif_hf_get_interface();
83/* handsfree profile - client */
84extern bthf_client_interface_t *btif_hf_client_get_interface();
85/* advanced audio profile */
86extern btav_interface_t *btif_av_get_src_interface();
87extern btav_interface_t *btif_av_get_sink_interface();
88/*rfc l2cap*/
89extern btsock_interface_t *btif_sock_get_interface();
90/* hid host profile */
91extern bthh_interface_t *btif_hh_get_interface();
92/* health device profile */
93extern bthl_interface_t *btif_hl_get_interface();
94/*pan*/
95extern btpan_interface_t *btif_pan_get_interface();
96/*map client*/
97extern btmce_interface_t *btif_mce_get_interface();
98#if BLE_INCLUDED == TRUE
99/* gatt */
100extern btgatt_interface_t *btif_gatt_get_interface();
101#endif
102/* avrc target */
103extern btrc_interface_t *btif_rc_get_interface();
104/* avrc controller */
105extern btrc_interface_t *btif_rc_ctrl_get_interface();
106/*SDP search client*/
107extern btsdp_interface_t *btif_sdp_get_interface();
108
109/************************************************************************************
110**  Functions
111************************************************************************************/
112
113static bool interface_ready(void) {
114  return bt_hal_cbacks != NULL;
115}
116
117static bool is_profile(const char *p1, const char *p2) {
118  assert(p1);
119  assert(p2);
120  return strlen(p1) == strlen(p2) && strncmp(p1, p2, strlen(p2)) == 0;
121}
122
123/*****************************************************************************
124**
125**   BLUETOOTH HAL INTERFACE FUNCTIONS
126**
127*****************************************************************************/
128
129static int init(bt_callbacks_t *callbacks) {
130  LOG_INFO(LOG_TAG, "%s", __func__);
131
132  if (interface_ready())
133    return BT_STATUS_DONE;
134
135#ifdef BLUEDROID_DEBUG
136  allocation_tracker_init();
137#endif
138
139  bt_hal_cbacks = callbacks;
140  stack_manager_get_interface()->init_stack();
141  btif_debug_init();
142  return BT_STATUS_SUCCESS;
143}
144
145static int enable(bool start_restricted) {
146  LOG_INFO(LOG_TAG, "%s: start restricted = %d", __func__, start_restricted);
147
148  restricted_mode = start_restricted;
149
150  if (!interface_ready())
151    return BT_STATUS_NOT_READY;
152
153  stack_manager_get_interface()->start_up_stack_async();
154  return BT_STATUS_SUCCESS;
155}
156
157static int disable(void) {
158  if (!interface_ready())
159    return BT_STATUS_NOT_READY;
160
161  stack_manager_get_interface()->shut_down_stack_async();
162  return BT_STATUS_SUCCESS;
163}
164
165static void cleanup(void) {
166  stack_manager_get_interface()->clean_up_stack();
167}
168
169bool is_restricted_mode() {
170  return restricted_mode;
171}
172
173static int get_adapter_properties(void)
174{
175    /* sanity check */
176    if (interface_ready() == FALSE)
177        return BT_STATUS_NOT_READY;
178
179    return btif_get_adapter_properties();
180}
181
182static int get_adapter_property(bt_property_type_t type)
183{
184    /* sanity check */
185    if (interface_ready() == FALSE)
186        return BT_STATUS_NOT_READY;
187
188    return btif_get_adapter_property(type);
189}
190
191static int set_adapter_property(const bt_property_t *property)
192{
193    /* sanity check */
194    if (interface_ready() == FALSE)
195        return BT_STATUS_NOT_READY;
196
197    return btif_set_adapter_property(property);
198}
199
200int get_remote_device_properties(bt_bdaddr_t *remote_addr)
201{
202    /* sanity check */
203    if (interface_ready() == FALSE)
204        return BT_STATUS_NOT_READY;
205
206    return btif_get_remote_device_properties(remote_addr);
207}
208
209int get_remote_device_property(bt_bdaddr_t *remote_addr, bt_property_type_t type)
210{
211    /* sanity check */
212    if (interface_ready() == FALSE)
213        return BT_STATUS_NOT_READY;
214
215    return btif_get_remote_device_property(remote_addr, type);
216}
217
218int set_remote_device_property(bt_bdaddr_t *remote_addr, const bt_property_t *property)
219{
220    /* sanity check */
221    if (interface_ready() == FALSE)
222        return BT_STATUS_NOT_READY;
223
224    return btif_set_remote_device_property(remote_addr, property);
225}
226
227int get_remote_service_record(bt_bdaddr_t *remote_addr, bt_uuid_t *uuid)
228{
229    /* sanity check */
230    if (interface_ready() == FALSE)
231        return BT_STATUS_NOT_READY;
232
233    return btif_get_remote_service_record(remote_addr, uuid);
234}
235
236int get_remote_services(bt_bdaddr_t *remote_addr)
237{
238    /* sanity check */
239    if (interface_ready() == FALSE)
240        return BT_STATUS_NOT_READY;
241
242    return btif_dm_get_remote_services(remote_addr);
243}
244
245static int start_discovery(void)
246{
247    /* sanity check */
248    if (interface_ready() == FALSE)
249        return BT_STATUS_NOT_READY;
250
251    return btif_dm_start_discovery();
252}
253
254static int cancel_discovery(void)
255{
256    /* sanity check */
257    if (interface_ready() == FALSE)
258        return BT_STATUS_NOT_READY;
259
260    return btif_dm_cancel_discovery();
261}
262
263static int create_bond(const bt_bdaddr_t *bd_addr, int transport)
264{
265    /* sanity check */
266    if (interface_ready() == FALSE)
267        return BT_STATUS_NOT_READY;
268
269    return btif_dm_create_bond(bd_addr, transport);
270}
271
272static int create_bond_out_of_band(const bt_bdaddr_t *bd_addr, int transport,
273                                   const bt_out_of_band_data_t *oob_data)
274{
275    /* sanity check */
276    if (interface_ready() == FALSE)
277        return BT_STATUS_NOT_READY;
278
279    return btif_dm_create_bond_out_of_band(bd_addr, transport, oob_data);
280}
281
282static int cancel_bond(const bt_bdaddr_t *bd_addr)
283{
284    /* sanity check */
285    if (interface_ready() == FALSE)
286        return BT_STATUS_NOT_READY;
287
288    return btif_dm_cancel_bond(bd_addr);
289}
290
291static int remove_bond(const bt_bdaddr_t *bd_addr)
292{
293    if (is_restricted_mode() && !btif_storage_is_restricted_device(bd_addr))
294        return BT_STATUS_SUCCESS;
295
296    /* sanity check */
297    if (interface_ready() == FALSE)
298        return BT_STATUS_NOT_READY;
299
300    return btif_dm_remove_bond(bd_addr);
301}
302
303static int get_connection_state(const bt_bdaddr_t *bd_addr)
304{
305    /* sanity check */
306    if (interface_ready() == FALSE)
307        return 0;
308
309    return btif_dm_get_connection_state(bd_addr);
310}
311
312static int pin_reply(const bt_bdaddr_t *bd_addr, uint8_t accept,
313                 uint8_t pin_len, bt_pin_code_t *pin_code)
314{
315    /* sanity check */
316    if (interface_ready() == FALSE)
317        return BT_STATUS_NOT_READY;
318
319    return btif_dm_pin_reply(bd_addr, accept, pin_len, pin_code);
320}
321
322static int ssp_reply(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant,
323                       uint8_t accept, uint32_t passkey)
324{
325    /* sanity check */
326    if (interface_ready() == FALSE)
327        return BT_STATUS_NOT_READY;
328
329    return btif_dm_ssp_reply(bd_addr, variant, accept, passkey);
330}
331
332static int read_energy_info()
333{
334    if (interface_ready() == FALSE)
335        return BT_STATUS_NOT_READY;
336    btif_dm_read_energy_info();
337    return BT_STATUS_SUCCESS;
338}
339
340static void dump(int fd, const char **arguments)
341{
342    if (arguments != NULL && arguments[0] != NULL) {
343      if (strncmp(arguments[0], "--proto-bin", 11) == 0) {
344        metrics_write_base64(fd, true);
345        return;
346      }
347    }
348    btif_debug_conn_dump(fd);
349    btif_debug_bond_event_dump(fd);
350    btif_debug_a2dp_dump(fd);
351    btif_debug_l2c_dump(fd);
352    btif_debug_config_dump(fd);
353    wakelock_debug_dump(fd);
354    alarm_debug_dump(fd);
355#if defined(BTSNOOP_MEM) && (BTSNOOP_MEM == TRUE)
356    btif_debug_btsnoop_dump(fd);
357#endif
358
359    close(fd);
360}
361
362static const void* get_profile_interface (const char *profile_id)
363{
364    LOG_INFO(LOG_TAG, "get_profile_interface %s", profile_id);
365
366    /* sanity check */
367    if (interface_ready() == FALSE)
368        return NULL;
369
370    /* check for supported profile interfaces */
371    if (is_profile(profile_id, BT_PROFILE_HANDSFREE_ID))
372        return btif_hf_get_interface();
373
374    if (is_profile(profile_id, BT_PROFILE_HANDSFREE_CLIENT_ID))
375        return btif_hf_client_get_interface();
376
377    if (is_profile(profile_id, BT_PROFILE_SOCKETS_ID))
378        return btif_sock_get_interface();
379
380    if (is_profile(profile_id, BT_PROFILE_PAN_ID))
381        return btif_pan_get_interface();
382
383    if (is_profile(profile_id, BT_PROFILE_ADVANCED_AUDIO_ID))
384        return btif_av_get_src_interface();
385
386    if (is_profile(profile_id, BT_PROFILE_ADVANCED_AUDIO_SINK_ID))
387        return btif_av_get_sink_interface();
388
389    if (is_profile(profile_id, BT_PROFILE_HIDHOST_ID))
390        return btif_hh_get_interface();
391
392    if (is_profile(profile_id, BT_PROFILE_HEALTH_ID))
393        return btif_hl_get_interface();
394
395    if (is_profile(profile_id, BT_PROFILE_SDP_CLIENT_ID))
396        return btif_sdp_get_interface();
397
398#if ( BTA_GATT_INCLUDED == TRUE && BLE_INCLUDED == TRUE)
399    if (is_profile(profile_id, BT_PROFILE_GATT_ID))
400        return btif_gatt_get_interface();
401#endif
402
403    if (is_profile(profile_id, BT_PROFILE_AV_RC_ID))
404        return btif_rc_get_interface();
405
406    if (is_profile(profile_id, BT_PROFILE_AV_RC_CTRL_ID))
407        return btif_rc_ctrl_get_interface();
408
409    return NULL;
410}
411
412int dut_mode_configure(uint8_t enable)
413{
414    LOG_INFO(LOG_TAG, "dut_mode_configure");
415
416    /* sanity check */
417    if (interface_ready() == FALSE)
418        return BT_STATUS_NOT_READY;
419
420    return btif_dut_mode_configure(enable);
421}
422
423int dut_mode_send(uint16_t opcode, uint8_t* buf, uint8_t len)
424{
425    LOG_INFO(LOG_TAG, "dut_mode_send");
426
427    /* sanity check */
428    if (interface_ready() == FALSE)
429        return BT_STATUS_NOT_READY;
430
431    return btif_dut_mode_send(opcode, buf, len);
432}
433
434#if BLE_INCLUDED == TRUE
435int le_test_mode(uint16_t opcode, uint8_t* buf, uint8_t len)
436{
437    LOG_INFO(LOG_TAG, "le_test_mode");
438
439    /* sanity check */
440    if (interface_ready() == FALSE)
441        return BT_STATUS_NOT_READY;
442
443    return btif_le_test_mode(opcode, buf, len);
444}
445#endif
446
447int config_hci_snoop_log(uint8_t enable)
448{
449    LOG_INFO(LOG_TAG, "config_hci_snoop_log");
450
451    if (!interface_ready())
452        return BT_STATUS_NOT_READY;
453
454    btsnoop_get_interface()->set_api_wants_to_log(enable);
455    return BT_STATUS_SUCCESS;
456}
457
458static int set_os_callouts(bt_os_callouts_t *callouts) {
459    wakelock_set_os_callouts(callouts);
460    return BT_STATUS_SUCCESS;
461}
462
463static int config_clear(void) {
464    LOG_INFO(LOG_TAG, "%s", __func__);
465    return btif_config_clear() ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
466}
467
468static const bt_interface_t bluetoothInterface = {
469    sizeof(bluetoothInterface),
470    init,
471    enable,
472    disable,
473    cleanup,
474    get_adapter_properties,
475    get_adapter_property,
476    set_adapter_property,
477    get_remote_device_properties,
478    get_remote_device_property,
479    set_remote_device_property,
480    get_remote_service_record,
481    get_remote_services,
482    start_discovery,
483    cancel_discovery,
484    create_bond,
485    create_bond_out_of_band,
486    remove_bond,
487    cancel_bond,
488    get_connection_state,
489    pin_reply,
490    ssp_reply,
491    get_profile_interface,
492    dut_mode_configure,
493    dut_mode_send,
494#if BLE_INCLUDED == TRUE
495    le_test_mode,
496#else
497    NULL,
498#endif
499    config_hci_snoop_log,
500    set_os_callouts,
501    read_energy_info,
502    dump,
503    config_clear,
504    interop_database_clear,
505    interop_database_add,
506};
507
508const bt_interface_t* bluetooth__get_bluetooth_interface ()
509{
510    /* fixme -- add property to disable bt interface ? */
511
512    return &bluetoothInterface;
513}
514
515static int close_bluetooth_stack(struct hw_device_t* device)
516{
517    UNUSED(device);
518    cleanup();
519    return 0;
520}
521
522static int open_bluetooth_stack(const struct hw_module_t *module, UNUSED_ATTR char const *name, struct hw_device_t **abstraction) {
523  static bluetooth_device_t device = {
524    .common = {
525      .tag = HARDWARE_DEVICE_TAG,
526      .version = 0,
527      .close = close_bluetooth_stack,
528    },
529    .get_bluetooth_interface = bluetooth__get_bluetooth_interface
530  };
531
532  device.common.module = (struct hw_module_t *)module;
533  *abstraction = (struct hw_device_t *)&device;
534  return 0;
535}
536
537static struct hw_module_methods_t bt_stack_module_methods = {
538    .open = open_bluetooth_stack,
539};
540
541EXPORT_SYMBOL struct hw_module_t HAL_MODULE_INFO_SYM = {
542    .tag = HARDWARE_MODULE_TAG,
543    .version_major = 1,
544    .version_minor = 0,
545    .id = BT_HARDWARE_MODULE_ID,
546    .name = "Bluetooth Stack",
547    .author = "The Android Open Source Project",
548    .methods = &bt_stack_module_methods
549};
550