bluetooth.c revision 5a79e080ef667e7c623ef46da6086915087c7488
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
159    /* hal callbacks reset upon shutdown complete callback */
160
161    return;
162}
163
164static int get_adapter_properties(void)
165{
166    /* sanity check */
167    if (interface_ready() == FALSE)
168        return BT_STATUS_NOT_READY;
169
170    return btif_get_adapter_properties();
171}
172
173static int get_adapter_property(bt_property_type_t type)
174{
175    /* sanity check */
176    if (interface_ready() == FALSE)
177        return BT_STATUS_NOT_READY;
178
179    return btif_get_adapter_property(type);
180}
181
182static int set_adapter_property(const bt_property_t *property)
183{
184    /* sanity check */
185    if (interface_ready() == FALSE)
186        return BT_STATUS_NOT_READY;
187
188    return btif_set_adapter_property(property);
189}
190
191int get_remote_device_properties(bt_bdaddr_t *remote_addr)
192{
193    /* sanity check */
194    if (interface_ready() == FALSE)
195        return BT_STATUS_NOT_READY;
196
197    return btif_get_remote_device_properties(remote_addr);
198}
199
200int get_remote_device_property(bt_bdaddr_t *remote_addr, bt_property_type_t type)
201{
202    /* sanity check */
203    if (interface_ready() == FALSE)
204        return BT_STATUS_NOT_READY;
205
206    return btif_get_remote_device_property(remote_addr, type);
207}
208
209int set_remote_device_property(bt_bdaddr_t *remote_addr, const bt_property_t *property)
210{
211    /* sanity check */
212    if (interface_ready() == FALSE)
213        return BT_STATUS_NOT_READY;
214
215    return btif_set_remote_device_property(remote_addr, property);
216}
217
218int get_remote_service_record(bt_bdaddr_t *remote_addr, bt_uuid_t *uuid)
219{
220    /* sanity check */
221    if (interface_ready() == FALSE)
222        return BT_STATUS_NOT_READY;
223
224    return btif_get_remote_service_record(remote_addr, uuid);
225}
226
227int get_remote_services(bt_bdaddr_t *remote_addr)
228{
229    /* sanity check */
230    if (interface_ready() == FALSE)
231        return BT_STATUS_NOT_READY;
232
233    return btif_dm_get_remote_services(remote_addr);
234}
235
236static int start_discovery(void)
237{
238    /* sanity check */
239    if (interface_ready() == FALSE)
240        return BT_STATUS_NOT_READY;
241
242    return btif_dm_start_discovery();
243}
244
245static int cancel_discovery(void)
246{
247    /* sanity check */
248    if (interface_ready() == FALSE)
249        return BT_STATUS_NOT_READY;
250
251    return btif_dm_cancel_discovery();
252}
253
254static int create_bond(const bt_bdaddr_t *bd_addr)
255{
256    /* sanity check */
257    if (interface_ready() == FALSE)
258        return BT_STATUS_NOT_READY;
259
260    return btif_dm_create_bond(bd_addr);
261}
262
263static int cancel_bond(const bt_bdaddr_t *bd_addr)
264{
265    /* sanity check */
266    if (interface_ready() == FALSE)
267        return BT_STATUS_NOT_READY;
268
269    return btif_dm_cancel_bond(bd_addr);
270}
271
272static int remove_bond(const bt_bdaddr_t *bd_addr)
273{
274    /* sanity check */
275    if (interface_ready() == FALSE)
276        return BT_STATUS_NOT_READY;
277
278    return btif_dm_remove_bond(bd_addr);
279}
280
281static int pin_reply(const bt_bdaddr_t *bd_addr, uint8_t accept,
282                 uint8_t pin_len, bt_pin_code_t *pin_code)
283{
284    /* sanity check */
285    if (interface_ready() == FALSE)
286        return BT_STATUS_NOT_READY;
287
288    return btif_dm_pin_reply(bd_addr, accept, pin_len, pin_code);
289}
290
291static int ssp_reply(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant,
292                       uint8_t accept, uint32_t passkey)
293{
294    /* sanity check */
295    if (interface_ready() == FALSE)
296        return BT_STATUS_NOT_READY;
297
298    return btif_dm_ssp_reply(bd_addr, variant, accept, passkey);
299}
300
301static const void* get_profile_interface (const char *profile_id)
302{
303    ALOGI("get_profile_interface %s", profile_id);
304
305    /* sanity check */
306    if (interface_ready() == FALSE)
307        return NULL;
308
309    /* check for supported profile interfaces */
310    if (is_profile(profile_id, BT_PROFILE_HANDSFREE_ID))
311        return btif_hf_get_interface();
312
313    if (is_profile(profile_id, BT_PROFILE_SOCKETS_ID))
314        return btif_sock_get_interface();
315
316    if (is_profile(profile_id, BT_PROFILE_PAN_ID))
317        return btif_pan_get_interface();
318
319    if (is_profile(profile_id, BT_PROFILE_ADVANCED_AUDIO_ID))
320        return btif_av_get_interface();
321
322    if (is_profile(profile_id, BT_PROFILE_HIDHOST_ID))
323        return btif_hh_get_interface();
324
325    if (is_profile(profile_id, BT_PROFILE_HEALTH_ID))
326        return btif_hl_get_interface();
327
328#if BTA_GATT_INCLUDED == TRUE
329    if (is_profile(profile_id, BT_PROFILE_GATT_ID))
330        return btif_gatt_get_interface();
331#endif
332
333    if (is_profile(profile_id, BT_PROFILE_AV_RC_ID))
334        return btif_rc_get_interface();
335
336    return NULL;
337}
338
339int dut_mode_configure(uint8_t enable)
340{
341    ALOGI("dut_mode_configure");
342
343    /* sanity check */
344    if (interface_ready() == FALSE)
345        return BT_STATUS_NOT_READY;
346
347    return btif_dut_mode_configure(enable);
348}
349
350int dut_mode_send(uint16_t opcode, uint8_t* buf, uint8_t len)
351{
352    ALOGI("dut_mode_send");
353
354    /* sanity check */
355    if (interface_ready() == FALSE)
356        return BT_STATUS_NOT_READY;
357
358    return btif_dut_mode_send(opcode, buf, len);
359}
360
361#if BLE_INCLUDED == TRUE
362int le_test_mode(uint16_t opcode, uint8_t* buf, uint8_t len)
363{
364    ALOGI("le_test_mode");
365
366    /* sanity check */
367    if (interface_ready() == FALSE)
368        return BT_STATUS_NOT_READY;
369
370    return btif_le_test_mode(opcode, buf, len);
371}
372#endif
373
374int config_hci_snoop_log(uint8_t enable)
375{
376    ALOGI("config_hci_snoop_log");
377
378    /* sanity check */
379    if (interface_ready() == FALSE)
380        return BT_STATUS_NOT_READY;
381
382    return btif_config_hci_snoop_log(enable);
383}
384
385static const bt_interface_t bluetoothInterface = {
386    sizeof(bluetoothInterface),
387    init,
388    enable,
389    disable,
390    cleanup,
391    get_adapter_properties,
392    get_adapter_property,
393    set_adapter_property,
394    get_remote_device_properties,
395    get_remote_device_property,
396    set_remote_device_property,
397    get_remote_service_record,
398    get_remote_services,
399    start_discovery,
400    cancel_discovery,
401    create_bond,
402    remove_bond,
403    cancel_bond,
404    pin_reply,
405    ssp_reply,
406    get_profile_interface,
407    dut_mode_configure,
408    dut_mode_send,
409#if BLE_INCLUDED == TRUE
410    le_test_mode,
411#else
412    NULL,
413#endif
414    config_hci_snoop_log
415};
416
417const bt_interface_t* bluetooth__get_bluetooth_interface ()
418{
419    /* fixme -- add property to disable bt interface ? */
420
421    return &bluetoothInterface;
422}
423
424static int close_bluetooth_stack(struct hw_device_t* device)
425{
426    cleanup();
427    return 0;
428}
429
430static int open_bluetooth_stack (const struct hw_module_t* module, char const* name,
431struct hw_device_t** abstraction)
432{
433    bluetooth_device_t *stack = malloc(sizeof(bluetooth_device_t) );
434    memset(stack, 0, sizeof(bluetooth_device_t) );
435    stack->common.tag = HARDWARE_DEVICE_TAG;
436    stack->common.version = 0;
437    stack->common.module = (struct hw_module_t*)module;
438    stack->common.close = close_bluetooth_stack;
439    stack->get_bluetooth_interface = bluetooth__get_bluetooth_interface;
440    *abstraction = (struct hw_device_t*)stack;
441    return 0;
442}
443
444
445static struct hw_module_methods_t bt_stack_module_methods = {
446    .open = open_bluetooth_stack,
447};
448
449struct hw_module_t HAL_MODULE_INFO_SYM = {
450    .tag = HARDWARE_MODULE_TAG,
451    .version_major = 1,
452    .version_minor = 0,
453    .id = BT_HARDWARE_MODULE_ID,
454    .name = "Bluetooth Stack",
455    .author = "The Android Open Source Project",
456    .methods = &bt_stack_module_methods
457};
458
459