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
61 bt_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 */
74 extern bthf_interface_t *btif_hf_get_interface();
75 /* advanced audio profile */
76 extern btav_interface_t *btif_av_get_interface();
77 /*rfc l2cap*/
78 extern btsock_interface_t *btif_sock_get_interface();
79 /* hid host profile */
80 extern bthh_interface_t *btif_hh_get_interface();
81 /* health device profile */
82 extern bthl_interface_t *btif_hl_get_interface();
83 /*pan*/
84 extern btpan_interface_t *btif_pan_get_interface();
85 /* gatt */
86 extern btgatt_interface_t *btif_gatt_get_interface();
87 /* avrc */
88 extern btrc_interface_t *btif_rc_get_interface();
89
90 /************************************************************************************
91 ** Functions
92 ************************************************************************************/
93
interface_ready(void)94 static 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
init(bt_callbacks_t * callbacks)110 static 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
enable(void)131 static 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
disable(void)142 static 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
cleanup(void)151 static 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
get_adapter_properties(void)164 static 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
get_adapter_property(bt_property_type_t type)173 static 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
set_adapter_property(const bt_property_t * property)182 static 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
get_remote_device_properties(bt_bdaddr_t * remote_addr)191 int 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
get_remote_device_property(bt_bdaddr_t * remote_addr,bt_property_type_t type)200 int 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
set_remote_device_property(bt_bdaddr_t * remote_addr,const bt_property_t * property)209 int 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
get_remote_service_record(bt_bdaddr_t * remote_addr,bt_uuid_t * uuid)218 int 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
get_remote_services(bt_bdaddr_t * remote_addr)227 int 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
start_discovery(void)236 static 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
cancel_discovery(void)245 static 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
create_bond(const bt_bdaddr_t * bd_addr)254 static 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
cancel_bond(const bt_bdaddr_t * bd_addr)263 static 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
remove_bond(const bt_bdaddr_t * bd_addr)272 static 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
pin_reply(const bt_bdaddr_t * bd_addr,uint8_t accept,uint8_t pin_len,bt_pin_code_t * pin_code)281 static 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
ssp_reply(const bt_bdaddr_t * bd_addr,bt_ssp_variant_t variant,uint8_t accept,uint32_t passkey)291 static 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
get_profile_interface(const char * profile_id)301 static 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
dut_mode_configure(uint8_t enable)339 int 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
dut_mode_send(uint16_t opcode,uint8_t * buf,uint8_t len)350 int 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
le_test_mode(uint16_t opcode,uint8_t * buf,uint8_t len)362 int 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
config_hci_snoop_log(uint8_t enable)374 int 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
385 static 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
bluetooth__get_bluetooth_interface()417 const bt_interface_t* bluetooth__get_bluetooth_interface ()
418 {
419 /* fixme -- add property to disable bt interface ? */
420
421 return &bluetoothInterface;
422 }
423
close_bluetooth_stack(struct hw_device_t * device)424 static int close_bluetooth_stack(struct hw_device_t* device)
425 {
426 cleanup();
427 return 0;
428 }
429
open_bluetooth_stack(const struct hw_module_t * module,char const * name,struct hw_device_t ** abstraction)430 static int open_bluetooth_stack (const struct hw_module_t* module, char const* name,
431 struct 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
445 static struct hw_module_methods_t bt_stack_module_methods = {
446 .open = open_bluetooth_stack,
447 };
448
449 struct 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