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#include <stdio.h>
28#include <stdlib.h>
29#include <unistd.h>
30
31#include <hardware/bluetooth.h>
32#include <hardware/bt_hf.h>
33#include <hardware/bt_av.h>
34#include <hardware/bt_sock.h>
35#include <hardware/bt_hh.h>
36#include <hardware/bt_hl.h>
37#include <hardware/bt_pan.h>
38#include <hardware/bt_gatt.h>
39#include <hardware/bt_rc.h>
40
41#define LOG_NDDEBUG 0
42#define LOG_TAG "bluedroid"
43
44#include "btif_api.h"
45#include "bt_utils.h"
46
47/************************************************************************************
48**  Constants & Macros
49************************************************************************************/
50
51#define is_profile(profile, str) ((strlen(str) == strlen(profile)) && strncmp((const char *)profile, str, strlen(str)) == 0)
52
53/************************************************************************************
54**  Local type definitions
55************************************************************************************/
56
57/************************************************************************************
58**  Static variables
59************************************************************************************/
60
61bt_callbacks_t *bt_hal_cbacks = NULL;
62
63/************************************************************************************
64**  Static functions
65************************************************************************************/
66
67/************************************************************************************
68**  Externs
69************************************************************************************/
70
71/* list all extended interfaces here */
72
73/* handsfree profile */
74extern bthf_interface_t *btif_hf_get_interface();
75/* advanced audio profile */
76extern btav_interface_t *btif_av_get_interface();
77/*rfc l2cap*/
78extern btsock_interface_t *btif_sock_get_interface();
79/* hid host profile */
80extern bthh_interface_t *btif_hh_get_interface();
81/* health device profile */
82extern bthl_interface_t *btif_hl_get_interface();
83/*pan*/
84extern btpan_interface_t *btif_pan_get_interface();
85/* gatt */
86extern btgatt_interface_t *btif_gatt_get_interface();
87/* avrc */
88extern btrc_interface_t *btif_rc_get_interface();
89
90/************************************************************************************
91**  Functions
92************************************************************************************/
93
94static uint8_t interface_ready(void)
95{
96    /* add checks here that would prevent API calls other than init to be executed */
97    if (bt_hal_cbacks == NULL)
98        return FALSE;
99
100    return TRUE;
101}
102
103
104/*****************************************************************************
105**
106**   BLUETOOTH HAL INTERFACE FUNCTIONS
107**
108*****************************************************************************/
109
110static int init(bt_callbacks_t* callbacks )
111{
112    ALOGI("init");
113
114    /* sanity check */
115    if (interface_ready() == TRUE)
116        return BT_STATUS_DONE;
117
118    /* store reference to user callbacks */
119    bt_hal_cbacks = callbacks;
120
121    /* add checks for individual callbacks ? */
122
123    bt_utils_init();
124
125    /* init btif */
126    btif_init_bluetooth();
127
128    return BT_STATUS_SUCCESS;
129}
130
131static int enable( void )
132{
133    ALOGI("enable");
134
135    /* sanity check */
136    if (interface_ready() == FALSE)
137        return BT_STATUS_NOT_READY;
138
139    return btif_enable_bluetooth();
140}
141
142static int disable(void)
143{
144    /* sanity check */
145    if (interface_ready() == FALSE)
146        return BT_STATUS_NOT_READY;
147
148    return btif_disable_bluetooth();
149}
150
151static void cleanup( void )
152{
153    /* sanity check */
154    if (interface_ready() == FALSE)
155        return;
156
157    btif_shutdown_bluetooth();
158    bt_utils_cleanup();
159
160    /* hal callbacks reset upon shutdown complete callback */
161
162    return;
163}
164
165static int get_adapter_properties(void)
166{
167    /* sanity check */
168    if (interface_ready() == FALSE)
169        return BT_STATUS_NOT_READY;
170
171    return btif_get_adapter_properties();
172}
173
174static int get_adapter_property(bt_property_type_t type)
175{
176    /* sanity check */
177    if (interface_ready() == FALSE)
178        return BT_STATUS_NOT_READY;
179
180    return btif_get_adapter_property(type);
181}
182
183static int set_adapter_property(const bt_property_t *property)
184{
185    /* sanity check */
186    if (interface_ready() == FALSE)
187        return BT_STATUS_NOT_READY;
188
189    return btif_set_adapter_property(property);
190}
191
192int get_remote_device_properties(bt_bdaddr_t *remote_addr)
193{
194    /* sanity check */
195    if (interface_ready() == FALSE)
196        return BT_STATUS_NOT_READY;
197
198    return btif_get_remote_device_properties(remote_addr);
199}
200
201int get_remote_device_property(bt_bdaddr_t *remote_addr, bt_property_type_t type)
202{
203    /* sanity check */
204    if (interface_ready() == FALSE)
205        return BT_STATUS_NOT_READY;
206
207    return btif_get_remote_device_property(remote_addr, type);
208}
209
210int set_remote_device_property(bt_bdaddr_t *remote_addr, const bt_property_t *property)
211{
212    /* sanity check */
213    if (interface_ready() == FALSE)
214        return BT_STATUS_NOT_READY;
215
216    return btif_set_remote_device_property(remote_addr, property);
217}
218
219int get_remote_service_record(bt_bdaddr_t *remote_addr, bt_uuid_t *uuid)
220{
221    /* sanity check */
222    if (interface_ready() == FALSE)
223        return BT_STATUS_NOT_READY;
224
225    return btif_get_remote_service_record(remote_addr, uuid);
226}
227
228int get_remote_services(bt_bdaddr_t *remote_addr)
229{
230    /* sanity check */
231    if (interface_ready() == FALSE)
232        return BT_STATUS_NOT_READY;
233
234    return btif_dm_get_remote_services(remote_addr);
235}
236
237static int start_discovery(void)
238{
239    /* sanity check */
240    if (interface_ready() == FALSE)
241        return BT_STATUS_NOT_READY;
242
243    return btif_dm_start_discovery();
244}
245
246static int cancel_discovery(void)
247{
248    /* sanity check */
249    if (interface_ready() == FALSE)
250        return BT_STATUS_NOT_READY;
251
252    return btif_dm_cancel_discovery();
253}
254
255static int create_bond(const bt_bdaddr_t *bd_addr)
256{
257    /* sanity check */
258    if (interface_ready() == FALSE)
259        return BT_STATUS_NOT_READY;
260
261    return btif_dm_create_bond(bd_addr);
262}
263
264static int cancel_bond(const bt_bdaddr_t *bd_addr)
265{
266    /* sanity check */
267    if (interface_ready() == FALSE)
268        return BT_STATUS_NOT_READY;
269
270    return btif_dm_cancel_bond(bd_addr);
271}
272
273static int remove_bond(const bt_bdaddr_t *bd_addr)
274{
275    /* sanity check */
276    if (interface_ready() == FALSE)
277        return BT_STATUS_NOT_READY;
278
279    return btif_dm_remove_bond(bd_addr);
280}
281
282static int pin_reply(const bt_bdaddr_t *bd_addr, uint8_t accept,
283                 uint8_t pin_len, bt_pin_code_t *pin_code)
284{
285    /* sanity check */
286    if (interface_ready() == FALSE)
287        return BT_STATUS_NOT_READY;
288
289    return btif_dm_pin_reply(bd_addr, accept, pin_len, pin_code);
290}
291
292static int ssp_reply(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant,
293                       uint8_t accept, uint32_t passkey)
294{
295    /* sanity check */
296    if (interface_ready() == FALSE)
297        return BT_STATUS_NOT_READY;
298
299    return btif_dm_ssp_reply(bd_addr, variant, accept, passkey);
300}
301
302static const void* get_profile_interface (const char *profile_id)
303{
304    ALOGI("get_profile_interface %s", profile_id);
305
306    /* sanity check */
307    if (interface_ready() == FALSE)
308        return NULL;
309
310    /* check for supported profile interfaces */
311    if (is_profile(profile_id, BT_PROFILE_HANDSFREE_ID))
312        return btif_hf_get_interface();
313
314    if (is_profile(profile_id, BT_PROFILE_SOCKETS_ID))
315        return btif_sock_get_interface();
316
317    if (is_profile(profile_id, BT_PROFILE_PAN_ID))
318        return btif_pan_get_interface();
319
320    if (is_profile(profile_id, BT_PROFILE_ADVANCED_AUDIO_ID))
321        return btif_av_get_interface();
322
323    if (is_profile(profile_id, BT_PROFILE_HIDHOST_ID))
324        return btif_hh_get_interface();
325
326    if (is_profile(profile_id, BT_PROFILE_HEALTH_ID))
327        return btif_hl_get_interface();
328
329#if BTA_GATT_INCLUDED == TRUE
330    if (is_profile(profile_id, BT_PROFILE_GATT_ID))
331        return btif_gatt_get_interface();
332#endif
333
334    if (is_profile(profile_id, BT_PROFILE_AV_RC_ID))
335        return btif_rc_get_interface();
336
337    return NULL;
338}
339
340int dut_mode_configure(uint8_t enable)
341{
342    ALOGI("dut_mode_configure");
343
344    /* sanity check */
345    if (interface_ready() == FALSE)
346        return BT_STATUS_NOT_READY;
347
348    return btif_dut_mode_configure(enable);
349}
350
351int dut_mode_send(uint16_t opcode, uint8_t* buf, uint8_t len)
352{
353    ALOGI("dut_mode_send");
354
355    /* sanity check */
356    if (interface_ready() == FALSE)
357        return BT_STATUS_NOT_READY;
358
359    return btif_dut_mode_send(opcode, buf, len);
360}
361
362#if BLE_INCLUDED == TRUE
363int le_test_mode(uint16_t opcode, uint8_t* buf, uint8_t len)
364{
365    ALOGI("le_test_mode");
366
367    /* sanity check */
368    if (interface_ready() == FALSE)
369        return BT_STATUS_NOT_READY;
370
371    return btif_le_test_mode(opcode, buf, len);
372}
373#endif
374
375int config_hci_snoop_log(uint8_t enable)
376{
377    ALOGI("config_hci_snoop_log");
378
379    /* sanity check */
380    if (interface_ready() == FALSE)
381        return BT_STATUS_NOT_READY;
382
383    return btif_config_hci_snoop_log(enable);
384}
385
386static const bt_interface_t bluetoothInterface = {
387    sizeof(bluetoothInterface),
388    init,
389    enable,
390    disable,
391    cleanup,
392    get_adapter_properties,
393    get_adapter_property,
394    set_adapter_property,
395    get_remote_device_properties,
396    get_remote_device_property,
397    set_remote_device_property,
398    get_remote_service_record,
399    get_remote_services,
400    start_discovery,
401    cancel_discovery,
402    create_bond,
403    remove_bond,
404    cancel_bond,
405    pin_reply,
406    ssp_reply,
407    get_profile_interface,
408    dut_mode_configure,
409    dut_mode_send,
410#if BLE_INCLUDED == TRUE
411    le_test_mode,
412#else
413    NULL,
414#endif
415    config_hci_snoop_log
416};
417
418const bt_interface_t* bluetooth__get_bluetooth_interface ()
419{
420    /* fixme -- add property to disable bt interface ? */
421
422    return &bluetoothInterface;
423}
424
425static int close_bluetooth_stack(struct hw_device_t* device)
426{
427    cleanup();
428    return 0;
429}
430
431static int open_bluetooth_stack (const struct hw_module_t* module, char const* name,
432struct hw_device_t** abstraction)
433{
434    bluetooth_device_t *stack = malloc(sizeof(bluetooth_device_t) );
435    memset(stack, 0, sizeof(bluetooth_device_t) );
436    stack->common.tag = HARDWARE_DEVICE_TAG;
437    stack->common.version = 0;
438    stack->common.module = (struct hw_module_t*)module;
439    stack->common.close = close_bluetooth_stack;
440    stack->get_bluetooth_interface = bluetooth__get_bluetooth_interface;
441    *abstraction = (struct hw_device_t*)stack;
442    return 0;
443}
444
445
446static struct hw_module_methods_t bt_stack_module_methods = {
447    .open = open_bluetooth_stack,
448};
449
450struct hw_module_t HAL_MODULE_INFO_SYM = {
451    .tag = HARDWARE_MODULE_TAG,
452    .version_major = 1,
453    .version_minor = 0,
454    .id = BT_HARDWARE_MODULE_ID,
455    .name = "Bluetooth Stack",
456    .author = "The Android Open Source Project",
457    .methods = &bt_stack_module_methods
458};
459
460