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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 417 const bt_interface_t* bluetooth__get_bluetooth_interface () 418 { 419 /* fixme -- add property to disable bt interface ? */ 420 421 return &bluetoothInterface; 422 } 423 424 static int close_bluetooth_stack(struct hw_device_t* device) 425 { 426 cleanup(); 427 return 0; 428 } 429 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