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: bte_main.c 22 * 23 * Description: Contains BTE core stack initialization and shutdown code 24 * 25 ******************************************************************************/ 26 #include <fcntl.h> 27 #include <stdlib.h> 28 #include <assert.h> 29 30 #include "gki.h" 31 #include "bd.h" 32 #include "btu.h" 33 #include "bte.h" 34 #include "bta_api.h" 35 #include "bt_hci_lib.h" 36 37 /******************************************************************************* 38 ** Constants & Macros 39 *******************************************************************************/ 40 41 /* Run-time configuration file */ 42 #ifndef BTE_STACK_CONF_FILE 43 #define BTE_STACK_CONF_FILE "/etc/bluetooth/bt_stack.conf" 44 #endif 45 46 /* if not specified in .txt file then use this as default */ 47 #ifndef HCI_LOGGING_FILENAME 48 #define HCI_LOGGING_FILENAME "/data/misc/bluedroid/btsnoop_hci.log" 49 #endif 50 51 /******************************************************************************* 52 ** Local type definitions 53 *******************************************************************************/ 54 55 /****************************************************************************** 56 ** Variables 57 ******************************************************************************/ 58 BOOLEAN hci_logging_enabled = FALSE; /* by default, turn hci log off */ 59 char hci_logfile[256] = HCI_LOGGING_FILENAME; 60 61 62 /******************************************************************************* 63 ** Static variables 64 *******************************************************************************/ 65 static bt_hc_interface_t *bt_hc_if=NULL; 66 static const bt_hc_callbacks_t hc_callbacks; 67 static BOOLEAN lpm_enabled = FALSE; 68 69 /******************************************************************************* 70 ** Static functions 71 *******************************************************************************/ 72 static void bte_main_in_hw_init(void); 73 74 /******************************************************************************* 75 ** Externs 76 *******************************************************************************/ 77 BTU_API extern UINT32 btu_task (UINT32 param); 78 BTU_API extern void BTE_Init (void); 79 BT_API extern void BTE_LoadStack(void); 80 BT_API void BTE_UnloadStack(void); 81 extern void scru_flip_bda (BD_ADDR dst, const BD_ADDR src); 82 extern void bte_load_conf(const char *p_path); 83 84 85 /******************************************************************************* 86 ** System Task Configuration 87 *******************************************************************************/ 88 89 /* bluetooth protocol stack (BTU) task */ 90 #ifndef BTE_BTU_STACK_SIZE 91 #define BTE_BTU_STACK_SIZE 0//0x2000 /* In bytes */ 92 #endif 93 #define BTE_BTU_TASK_STR ((INT8 *) "BTU") 94 UINT32 bte_btu_stack[(BTE_BTU_STACK_SIZE + 3) / 4]; 95 96 /****************************************************************************** 97 ** 98 ** Function bte_main_in_hw_init 99 ** 100 ** Description Internal helper function for chip hardware init 101 ** 102 ** Returns None 103 ** 104 ******************************************************************************/ 105 void bte_main_in_hw_init(void) 106 { 107 if ( (bt_hc_if = (bt_hc_interface_t *) bt_hc_get_interface()) \ 108 == NULL) 109 { 110 APPL_TRACE_ERROR0("!!! Failed to get BtHostControllerInterface !!!"); 111 } 112 } 113 114 /****************************************************************************** 115 ** 116 ** Function bte_main_boot_entry 117 ** 118 ** Description BTE MAIN API - Entry point for BTE chip/stack initialization 119 ** 120 ** Returns None 121 ** 122 ******************************************************************************/ 123 void bte_main_boot_entry(void) 124 { 125 /* initialize OS */ 126 GKI_init(); 127 128 bte_main_in_hw_init(); 129 130 bte_load_conf(BTE_STACK_CONF_FILE); 131 132 #if (BTTRC_INCLUDED == TRUE) 133 /* Initialize trace feature */ 134 BTTRC_TraceInit(MAX_TRACE_RAM_SIZE, &BTE_TraceLogBuf[0], BTTRC_METHOD_RAM); 135 #endif 136 } 137 138 /****************************************************************************** 139 ** 140 ** Function bte_main_shutdown 141 ** 142 ** Description BTE MAIN API - Shutdown code for BTE chip/stack 143 ** 144 ** Returns None 145 ** 146 ******************************************************************************/ 147 void bte_main_shutdown() 148 { 149 GKI_shutdown(); 150 } 151 152 /****************************************************************************** 153 ** 154 ** Function bte_main_enable 155 ** 156 ** Description BTE MAIN API - Creates all the BTE tasks. Should be called 157 ** part of the Bluetooth stack enable sequence 158 ** 159 ** Returns None 160 ** 161 ******************************************************************************/ 162 void bte_main_enable(uint8_t *local_addr) 163 { 164 APPL_TRACE_DEBUG1("%s", __FUNCTION__); 165 166 /* Initialize BTE control block */ 167 BTE_Init(); 168 169 lpm_enabled = FALSE; 170 171 if (bt_hc_if) 172 { 173 int result = bt_hc_if->init(&hc_callbacks, local_addr); 174 APPL_TRACE_EVENT1("libbt-hci init returns %d", result); 175 176 assert(result == BT_HC_STATUS_SUCCESS); 177 178 if (hci_logging_enabled == TRUE) 179 bt_hc_if->logging(BT_HC_LOGGING_ON, hci_logfile); 180 181 #if (defined (BT_CLEAN_TURN_ON_DISABLED) && BT_CLEAN_TURN_ON_DISABLED == TRUE) 182 APPL_TRACE_DEBUG1("%s Not Turninig Off the BT before Turninig ON", __FUNCTION__); 183 184 /* Do not power off the chip before powering on if BT_CLEAN_TURN_ON_DISABLED flag 185 is defined and set to TRUE to avoid below mentioned issue. 186 187 Wingray kernel driver maintains a combined counter to keep track of 188 BT-Wifi state. Invoking set_power(BT_HC_CHIP_PWR_OFF) when the BT is already 189 in OFF state causes this counter to be incorrectly decremented and results in undesired 190 behavior of the chip. 191 192 This is only a workaround and when the issue is fixed in the kernel this work around 193 should be removed. */ 194 #else 195 /* toggle chip power to ensure we will reset chip in case 196 a previous stack shutdown wasn't completed gracefully */ 197 bt_hc_if->set_power(BT_HC_CHIP_PWR_OFF); 198 #endif 199 bt_hc_if->set_power(BT_HC_CHIP_PWR_ON); 200 201 bt_hc_if->preload(NULL); 202 } 203 204 GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR, 205 (UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE), 206 sizeof(bte_btu_stack)); 207 208 GKI_run(0); 209 } 210 211 /****************************************************************************** 212 ** 213 ** Function bte_main_disable 214 ** 215 ** Description BTE MAIN API - Destroys all the BTE tasks. Should be called 216 ** part of the Bluetooth stack disable sequence 217 ** 218 ** Returns None 219 ** 220 ******************************************************************************/ 221 void bte_main_disable(void) 222 { 223 APPL_TRACE_DEBUG1("%s", __FUNCTION__); 224 225 if (bt_hc_if) 226 { 227 bt_hc_if->cleanup(); 228 bt_hc_if->set_power(BT_HC_CHIP_PWR_OFF); 229 } 230 231 GKI_destroy_task(BTU_TASK); 232 233 GKI_freeze(); 234 } 235 236 /****************************************************************************** 237 ** 238 ** Function bte_main_postload_cfg 239 ** 240 ** Description BTE MAIN API - Stack postload configuration 241 ** 242 ** Returns None 243 ** 244 ******************************************************************************/ 245 void bte_main_postload_cfg(void) 246 { 247 if (bt_hc_if) 248 bt_hc_if->postload(NULL); 249 } 250 251 #if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE) 252 /****************************************************************************** 253 ** 254 ** Function bte_main_enable_lpm 255 ** 256 ** Description BTE MAIN API - Enable/Disable low power mode operation 257 ** 258 ** Returns None 259 ** 260 ******************************************************************************/ 261 void bte_main_enable_lpm(BOOLEAN enable) 262 { 263 int result = -1; 264 265 if (bt_hc_if) 266 result = bt_hc_if->lpm( \ 267 (enable == TRUE) ? BT_HC_LPM_ENABLE : BT_HC_LPM_DISABLE \ 268 ); 269 270 APPL_TRACE_EVENT2("HC lib lpm enable=%d return %d", enable, result); 271 } 272 273 /****************************************************************************** 274 ** 275 ** Function bte_main_lpm_allow_bt_device_sleep 276 ** 277 ** Description BTE MAIN API - Allow BT controller goest to sleep 278 ** 279 ** Returns None 280 ** 281 ******************************************************************************/ 282 void bte_main_lpm_allow_bt_device_sleep() 283 { 284 int result = -1; 285 286 if ((bt_hc_if) && (lpm_enabled == TRUE)) 287 result = bt_hc_if->lpm(BT_HC_LPM_WAKE_DEASSERT); 288 289 APPL_TRACE_DEBUG1("HC lib lpm deassertion return %d", result); 290 } 291 292 /****************************************************************************** 293 ** 294 ** Function bte_main_lpm_wake_bt_device 295 ** 296 ** Description BTE MAIN API - Wake BT controller up if it is in sleep mode 297 ** 298 ** Returns None 299 ** 300 ******************************************************************************/ 301 void bte_main_lpm_wake_bt_device() 302 { 303 int result = -1; 304 305 if ((bt_hc_if) && (lpm_enabled == TRUE)) 306 result = bt_hc_if->lpm(BT_HC_LPM_WAKE_ASSERT); 307 308 APPL_TRACE_DEBUG1("HC lib lpm assertion return %d", result); 309 } 310 #endif // HCILP_INCLUDED 311 312 /****************************************************************************** 313 ** 314 ** Function bte_main_hci_send 315 ** 316 ** Description BTE MAIN API - This function is called by the upper stack to 317 ** send an HCI message. The function displays a protocol trace 318 ** message (if enabled), and then calls the 'transmit' function 319 ** associated with the currently selected HCI transport 320 ** 321 ** Returns None 322 ** 323 ******************************************************************************/ 324 void bte_main_hci_send (BT_HDR *p_msg, UINT16 event) 325 { 326 UINT16 sub_event = event & BT_SUB_EVT_MASK; /* local controller ID */ 327 328 p_msg->event = event; 329 330 331 if((sub_event == LOCAL_BR_EDR_CONTROLLER_ID) || \ 332 (sub_event == LOCAL_BLE_CONTROLLER_ID)) 333 { 334 if (bt_hc_if) 335 bt_hc_if->transmit_buf((TRANSAC)p_msg, \ 336 (char *) (p_msg + 1), \ 337 p_msg->len); 338 else 339 GKI_freebuf(p_msg); 340 } 341 else 342 { 343 APPL_TRACE_ERROR0("Invalid Controller ID. Discarding message."); 344 GKI_freebuf(p_msg); 345 } 346 } 347 348 /****************************************************************************** 349 ** 350 ** Function bte_main_post_reset_init 351 ** 352 ** Description BTE MAIN API - This function is mapped to BTM_APP_DEV_INIT 353 ** and shall be automatically called from BTE after HCI_Reset 354 ** 355 ** Returns None 356 ** 357 ******************************************************************************/ 358 void bte_main_post_reset_init() 359 { 360 BTM_ContinueReset(); 361 } 362 363 /***************************************************************************** 364 ** 365 ** libbt-hci Callback Functions 366 ** 367 *****************************************************************************/ 368 369 /****************************************************************************** 370 ** 371 ** Function preload_cb 372 ** 373 ** Description HOST/CONTROLLER LIB CALLBACK API - This function is called 374 ** when the libbt-hci completed stack preload process 375 ** 376 ** Returns None 377 ** 378 ******************************************************************************/ 379 static void preload_cb(TRANSAC transac, bt_hc_preload_result_t result) 380 { 381 APPL_TRACE_EVENT1("HC preload_cb %d [0:SUCCESS 1:FAIL]", result); 382 383 /* notify BTU task that libbt-hci is ready */ 384 /* even if PRELOAD process failed */ 385 GKI_send_event(BTU_TASK, TASK_MBOX_0_EVT_MASK); 386 } 387 388 /****************************************************************************** 389 ** 390 ** Function postload_cb 391 ** 392 ** Description HOST/CONTROLLER LIB CALLBACK API - This function is called 393 ** when the libbt-hci lib completed stack postload process 394 ** 395 ** Returns None 396 ** 397 ******************************************************************************/ 398 static void postload_cb(TRANSAC transac, bt_hc_postload_result_t result) 399 { 400 APPL_TRACE_EVENT1("HC postload_cb %d", result); 401 } 402 403 /****************************************************************************** 404 ** 405 ** Function lpm_cb 406 ** 407 ** Description HOST/CONTROLLER LIB CALLBACK API - This function is called 408 ** back from the libbt-hci to indicate the current LPM state 409 ** 410 ** Returns None 411 ** 412 ******************************************************************************/ 413 static void lpm_cb(bt_hc_lpm_request_result_t result) 414 { 415 APPL_TRACE_EVENT1("HC lpm_result_cb %d", result); 416 lpm_enabled = (result == BT_HC_LPM_ENABLED) ? TRUE : FALSE; 417 } 418 419 /****************************************************************************** 420 ** 421 ** Function hostwake_ind 422 ** 423 ** Description HOST/CONTROLLER LIB CALLOUT API - This function is called 424 ** from the libbt-hci to indicate the HostWake event 425 ** 426 ** Returns None 427 ** 428 ******************************************************************************/ 429 static void hostwake_ind(bt_hc_low_power_event_t event) 430 { 431 APPL_TRACE_EVENT1("HC hostwake_ind %d", event); 432 } 433 434 /****************************************************************************** 435 ** 436 ** Function alloc 437 ** 438 ** Description HOST/CONTROLLER LIB CALLOUT API - This function is called 439 ** from the libbt-hci to request for data buffer allocation 440 ** 441 ** Returns NULL / pointer to allocated buffer 442 ** 443 ******************************************************************************/ 444 static char *alloc(int size) 445 { 446 BT_HDR *p_hdr = NULL; 447 448 /* 449 APPL_TRACE_DEBUG1("HC alloc size=%d", size); 450 */ 451 452 p_hdr = (BT_HDR *) GKI_getbuf ((UINT16) size); 453 454 if (p_hdr == NULL) 455 { 456 APPL_TRACE_WARNING0("alloc returns NO BUFFER!"); 457 } 458 459 return ((char *) p_hdr); 460 } 461 462 /****************************************************************************** 463 ** 464 ** Function dealloc 465 ** 466 ** Description HOST/CONTROLLER LIB CALLOUT API - This function is called 467 ** from the libbt-hci to release the data buffer allocated 468 ** through the alloc call earlier 469 ** 470 ** Bluedroid libbt-hci library uses 'transac' parameter to 471 ** pass data-path buffer/packet across bt_hci_lib interface 472 ** boundary. The 'p_buf' is not intended to be used here 473 ** but might point to data portion of data-path buffer. 474 ** 475 ** Returns bt_hc_status_t 476 ** 477 ******************************************************************************/ 478 static int dealloc(TRANSAC transac, char *p_buf) 479 { 480 GKI_freebuf(transac); 481 return BT_HC_STATUS_SUCCESS; 482 } 483 484 /****************************************************************************** 485 ** 486 ** Function data_ind 487 ** 488 ** Description HOST/CONTROLLER LIB CALLOUT API - This function is called 489 ** from the libbt-hci to pass in the received HCI packets 490 ** 491 ** The core stack is responsible for releasing the data buffer 492 ** passed in from the libbt-hci once the core stack has done 493 ** with it. 494 ** 495 ** Bluedroid libbt-hci library uses 'transac' parameter to 496 ** pass data-path buffer/packet across bt_hci_lib interface 497 ** boundary. The 'p_buf' and 'len' parameters are not intended 498 ** to be used here but might point to data portion in data- 499 ** path buffer and length of valid data respectively. 500 ** 501 ** Returns bt_hc_status_t 502 ** 503 ******************************************************************************/ 504 static int data_ind(TRANSAC transac, char *p_buf, int len) 505 { 506 BT_HDR *p_msg = (BT_HDR *) transac; 507 508 /* 509 APPL_TRACE_DEBUG2("HC data_ind event=0x%04X (len=%d)", p_msg->event, len); 510 */ 511 512 GKI_send_msg (BTU_TASK, BTU_HCI_RCV_MBOX, transac); 513 return BT_HC_STATUS_SUCCESS; 514 } 515 516 /****************************************************************************** 517 ** 518 ** Function tx_result 519 ** 520 ** Description HOST/CONTROLLER LIB CALLBACK API - This function is called 521 ** from the libbt-hci once it has processed/sent the prior data 522 ** buffer which core stack passed to it through transmit_buf 523 ** call earlier. 524 ** 525 ** The core stack is responsible for releasing the data buffer 526 ** if it has been completedly processed. 527 ** 528 ** Bluedroid libbt-hci library uses 'transac' parameter to 529 ** pass data-path buffer/packet across bt_hci_lib interface 530 ** boundary. The 'p_buf' is not intended to be used here 531 ** but might point to data portion in data-path buffer. 532 ** 533 ** Returns bt_hc_status_t 534 ** 535 ******************************************************************************/ 536 static int tx_result(TRANSAC transac, char *p_buf, \ 537 bt_hc_transmit_result_t result) 538 { 539 /* 540 APPL_TRACE_DEBUG2("HC tx_result %d (event=%04X)", result, \ 541 ((BT_HDR *)transac)->event); 542 */ 543 544 if (result == BT_HC_TX_FRAGMENT) 545 { 546 GKI_send_msg (BTU_TASK, BTU_HCI_RCV_MBOX, transac); 547 } 548 else 549 { 550 GKI_freebuf(transac); 551 } 552 553 return BT_HC_STATUS_SUCCESS; 554 } 555 556 /***************************************************************************** 557 ** The libbt-hci Callback Functions Table 558 *****************************************************************************/ 559 static const bt_hc_callbacks_t hc_callbacks = { 560 sizeof(bt_hc_callbacks_t), 561 preload_cb, 562 postload_cb, 563 lpm_cb, 564 hostwake_ind, 565 alloc, 566 dealloc, 567 data_ind, 568 tx_result 569 }; 570 571