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 #include <signal.h> 30 #include <time.h> 31 #include <hardware/bluetooth.h> 32 33 #include "gki.h" 34 #include "bd.h" 35 #include "btu.h" 36 #include "bte.h" 37 #include "bta_api.h" 38 #include "bt_hci_lib.h" 39 40 /******************************************************************************* 41 ** Constants & Macros 42 *******************************************************************************/ 43 44 /* Run-time configuration file */ 45 #ifndef BTE_STACK_CONF_FILE 46 #define BTE_STACK_CONF_FILE "/etc/bluetooth/bt_stack.conf" 47 #endif 48 49 /* if not specified in .txt file then use this as default */ 50 #ifndef HCI_LOGGING_FILENAME 51 #define HCI_LOGGING_FILENAME "/data/misc/bluedroid/btsnoop_hci.log" 52 #endif 53 54 /* Stack preload process timeout period */ 55 #ifndef PRELOAD_START_TIMEOUT_MS 56 #define PRELOAD_START_TIMEOUT_MS 3000 // 3 seconds 57 #endif 58 59 /* Stack preload process maximum retry attempts */ 60 #ifndef PRELOAD_MAX_RETRY_ATTEMPTS 61 #define PRELOAD_MAX_RETRY_ATTEMPTS 0 62 #endif 63 64 /******************************************************************************* 65 ** Local type definitions 66 *******************************************************************************/ 67 /* Preload retry control block */ 68 typedef struct 69 { 70 int retry_counts; 71 BOOLEAN timer_created; 72 timer_t timer_id; 73 } bt_preload_retry_cb_t; 74 75 /****************************************************************************** 76 ** Variables 77 ******************************************************************************/ 78 BOOLEAN hci_logging_enabled = FALSE; /* by default, turn hci log off */ 79 char hci_logfile[256] = HCI_LOGGING_FILENAME; 80 81 82 /******************************************************************************* 83 ** Static variables 84 *******************************************************************************/ 85 static bt_hc_interface_t *bt_hc_if=NULL; 86 static const bt_hc_callbacks_t hc_callbacks; 87 static BOOLEAN lpm_enabled = FALSE; 88 static bt_preload_retry_cb_t preload_retry_cb; 89 90 /******************************************************************************* 91 ** Static functions 92 *******************************************************************************/ 93 static void bte_main_in_hw_init(void); 94 static void bte_hci_enable(void); 95 static void bte_hci_disable(void); 96 static void preload_start_wait_timer(void); 97 static void preload_stop_wait_timer(void); 98 99 /******************************************************************************* 100 ** Externs 101 *******************************************************************************/ 102 BTU_API extern UINT32 btu_task (UINT32 param); 103 BTU_API extern void BTE_Init (void); 104 BT_API extern void BTE_LoadStack(void); 105 BT_API void BTE_UnloadStack(void); 106 extern void scru_flip_bda (BD_ADDR dst, const BD_ADDR src); 107 extern void bte_load_conf(const char *p_path); 108 extern bt_bdaddr_t btif_local_bd_addr; 109 110 111 /******************************************************************************* 112 ** System Task Configuration 113 *******************************************************************************/ 114 115 /* bluetooth protocol stack (BTU) task */ 116 #ifndef BTE_BTU_STACK_SIZE 117 #define BTE_BTU_STACK_SIZE 0//0x2000 /* In bytes */ 118 #endif 119 #define BTE_BTU_TASK_STR ((INT8 *) "BTU") 120 UINT32 bte_btu_stack[(BTE_BTU_STACK_SIZE + 3) / 4]; 121 122 /****************************************************************************** 123 ** 124 ** Function bte_main_in_hw_init 125 ** 126 ** Description Internal helper function for chip hardware init 127 ** 128 ** Returns None 129 ** 130 ******************************************************************************/ 131 static void bte_main_in_hw_init(void) 132 { 133 if ( (bt_hc_if = (bt_hc_interface_t *) bt_hc_get_interface()) \ 134 == NULL) 135 { 136 APPL_TRACE_ERROR0("!!! Failed to get BtHostControllerInterface !!!"); 137 } 138 139 memset(&preload_retry_cb, 0, sizeof(bt_preload_retry_cb_t)); 140 } 141 142 /****************************************************************************** 143 ** 144 ** Function bte_main_boot_entry 145 ** 146 ** Description BTE MAIN API - Entry point for BTE chip/stack initialization 147 ** 148 ** Returns None 149 ** 150 ******************************************************************************/ 151 void bte_main_boot_entry(void) 152 { 153 /* initialize OS */ 154 GKI_init(); 155 156 bte_main_in_hw_init(); 157 158 bte_load_conf(BTE_STACK_CONF_FILE); 159 160 #if (BTTRC_INCLUDED == TRUE) 161 /* Initialize trace feature */ 162 BTTRC_TraceInit(MAX_TRACE_RAM_SIZE, &BTE_TraceLogBuf[0], BTTRC_METHOD_RAM); 163 #endif 164 } 165 166 /****************************************************************************** 167 ** 168 ** Function bte_main_shutdown 169 ** 170 ** Description BTE MAIN API - Shutdown code for BTE chip/stack 171 ** 172 ** Returns None 173 ** 174 ******************************************************************************/ 175 void bte_main_shutdown() 176 { 177 GKI_shutdown(); 178 } 179 180 /****************************************************************************** 181 ** 182 ** Function bte_main_enable 183 ** 184 ** Description BTE MAIN API - Creates all the BTE tasks. Should be called 185 ** part of the Bluetooth stack enable sequence 186 ** 187 ** Returns None 188 ** 189 ******************************************************************************/ 190 void bte_main_enable() 191 { 192 APPL_TRACE_DEBUG1("%s", __FUNCTION__); 193 194 /* Initialize BTE control block */ 195 BTE_Init(); 196 197 lpm_enabled = FALSE; 198 199 bte_hci_enable(); 200 201 GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR, 202 (UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE), 203 sizeof(bte_btu_stack)); 204 205 GKI_run(0); 206 } 207 208 /****************************************************************************** 209 ** 210 ** Function bte_main_disable 211 ** 212 ** Description BTE MAIN API - Destroys all the BTE tasks. Should be called 213 ** part of the Bluetooth stack disable sequence 214 ** 215 ** Returns None 216 ** 217 ******************************************************************************/ 218 void bte_main_disable(void) 219 { 220 APPL_TRACE_DEBUG1("%s", __FUNCTION__); 221 222 preload_stop_wait_timer(); 223 bte_hci_disable(); 224 GKI_destroy_task(BTU_TASK); 225 GKI_freeze(); 226 } 227 228 /****************************************************************************** 229 ** 230 ** Function bte_hci_enable 231 ** 232 ** Description Enable HCI & Vendor modules 233 ** 234 ** Returns None 235 ** 236 ******************************************************************************/ 237 static void bte_hci_enable(void) 238 { 239 APPL_TRACE_DEBUG1("%s", __FUNCTION__); 240 241 preload_start_wait_timer(); 242 243 if (bt_hc_if) 244 { 245 int result = bt_hc_if->init(&hc_callbacks, btif_local_bd_addr.address); 246 APPL_TRACE_EVENT1("libbt-hci init returns %d", result); 247 248 assert(result == BT_HC_STATUS_SUCCESS); 249 250 if (hci_logging_enabled == TRUE) 251 bt_hc_if->logging(BT_HC_LOGGING_ON, hci_logfile); 252 253 #if (defined (BT_CLEAN_TURN_ON_DISABLED) && BT_CLEAN_TURN_ON_DISABLED == TRUE) 254 APPL_TRACE_DEBUG1("%s Not Turninig Off the BT before Turninig ON", __FUNCTION__); 255 256 /* Do not power off the chip before powering on if BT_CLEAN_TURN_ON_DISABLED flag 257 is defined and set to TRUE to avoid below mentioned issue. 258 259 Wingray kernel driver maintains a combined counter to keep track of 260 BT-Wifi state. Invoking set_power(BT_HC_CHIP_PWR_OFF) when the BT is already 261 in OFF state causes this counter to be incorrectly decremented and results in undesired 262 behavior of the chip. 263 264 This is only a workaround and when the issue is fixed in the kernel this work around 265 should be removed. */ 266 #else 267 /* toggle chip power to ensure we will reset chip in case 268 a previous stack shutdown wasn't completed gracefully */ 269 bt_hc_if->set_power(BT_HC_CHIP_PWR_OFF); 270 #endif 271 bt_hc_if->set_power(BT_HC_CHIP_PWR_ON); 272 273 bt_hc_if->preload(NULL); 274 } 275 } 276 277 /****************************************************************************** 278 ** 279 ** Function bte_hci_disable 280 ** 281 ** Description Disable HCI & Vendor modules 282 ** 283 ** Returns None 284 ** 285 ******************************************************************************/ 286 static void bte_hci_disable(void) 287 { 288 APPL_TRACE_DEBUG1("%s", __FUNCTION__); 289 290 if (bt_hc_if) 291 { 292 bt_hc_if->cleanup(); 293 bt_hc_if->set_power(BT_HC_CHIP_PWR_OFF); 294 if (hci_logging_enabled == TRUE) 295 bt_hc_if->logging(BT_HC_LOGGING_OFF, hci_logfile); 296 } 297 } 298 299 /******************************************************************************* 300 ** 301 ** Function preload_wait_timeout 302 ** 303 ** Description Timeout thread of preload watchdog timer 304 ** 305 ** Returns None 306 ** 307 *******************************************************************************/ 308 static void preload_wait_timeout(union sigval arg) 309 { 310 APPL_TRACE_ERROR2("...preload_wait_timeout (retried:%d/max-retry:%d)...", 311 preload_retry_cb.retry_counts, 312 PRELOAD_MAX_RETRY_ATTEMPTS); 313 314 if (preload_retry_cb.retry_counts++ < PRELOAD_MAX_RETRY_ATTEMPTS) 315 { 316 bte_hci_disable(); 317 GKI_delay(100); 318 bte_hci_enable(); 319 } 320 else 321 { 322 /* Notify BTIF_TASK that the init procedure had failed*/ 323 GKI_send_event(BTIF_TASK, BT_EVT_HARDWARE_INIT_FAIL); 324 } 325 } 326 327 /******************************************************************************* 328 ** 329 ** Function preload_start_wait_timer 330 ** 331 ** Description Launch startup watchdog timer 332 ** 333 ** Returns None 334 ** 335 *******************************************************************************/ 336 static void preload_start_wait_timer(void) 337 { 338 int status; 339 struct itimerspec ts; 340 struct sigevent se; 341 UINT32 timeout_ms = PRELOAD_START_TIMEOUT_MS; 342 343 if (preload_retry_cb.timer_created == FALSE) 344 { 345 se.sigev_notify = SIGEV_THREAD; 346 se.sigev_value.sival_ptr = &preload_retry_cb.timer_id; 347 se.sigev_notify_function = preload_wait_timeout; 348 se.sigev_notify_attributes = NULL; 349 350 status = timer_create(CLOCK_MONOTONIC, &se, &preload_retry_cb.timer_id); 351 352 if (status == 0) 353 preload_retry_cb.timer_created = TRUE; 354 } 355 356 if (preload_retry_cb.timer_created == TRUE) 357 { 358 ts.it_value.tv_sec = timeout_ms/1000; 359 ts.it_value.tv_nsec = 1000000*(timeout_ms%1000); 360 ts.it_interval.tv_sec = 0; 361 ts.it_interval.tv_nsec = 0; 362 363 status = timer_settime(preload_retry_cb.timer_id, 0, &ts, 0); 364 if (status == -1) 365 APPL_TRACE_ERROR0("Failed to fire preload watchdog timer"); 366 } 367 } 368 369 /******************************************************************************* 370 ** 371 ** Function preload_stop_wait_timer 372 ** 373 ** Description Stop preload watchdog timer 374 ** 375 ** Returns None 376 ** 377 *******************************************************************************/ 378 static void preload_stop_wait_timer(void) 379 { 380 if (preload_retry_cb.timer_created == TRUE) 381 { 382 timer_delete(preload_retry_cb.timer_id); 383 preload_retry_cb.timer_created = FALSE; 384 } 385 } 386 387 /****************************************************************************** 388 ** 389 ** Function bte_main_postload_cfg 390 ** 391 ** Description BTE MAIN API - Stack postload configuration 392 ** 393 ** Returns None 394 ** 395 ******************************************************************************/ 396 void bte_main_postload_cfg(void) 397 { 398 if (bt_hc_if) 399 bt_hc_if->postload(NULL); 400 } 401 402 #if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE) 403 /****************************************************************************** 404 ** 405 ** Function bte_main_enable_lpm 406 ** 407 ** Description BTE MAIN API - Enable/Disable low power mode operation 408 ** 409 ** Returns None 410 ** 411 ******************************************************************************/ 412 void bte_main_enable_lpm(BOOLEAN enable) 413 { 414 int result = -1; 415 416 if (bt_hc_if) 417 result = bt_hc_if->lpm( \ 418 (enable == TRUE) ? BT_HC_LPM_ENABLE : BT_HC_LPM_DISABLE \ 419 ); 420 421 APPL_TRACE_EVENT2("HC lib lpm enable=%d return %d", enable, result); 422 } 423 424 /****************************************************************************** 425 ** 426 ** Function bte_main_lpm_allow_bt_device_sleep 427 ** 428 ** Description BTE MAIN API - Allow BT controller goest to sleep 429 ** 430 ** Returns None 431 ** 432 ******************************************************************************/ 433 void bte_main_lpm_allow_bt_device_sleep() 434 { 435 int result = -1; 436 437 if ((bt_hc_if) && (lpm_enabled == TRUE)) 438 result = bt_hc_if->lpm(BT_HC_LPM_WAKE_DEASSERT); 439 440 APPL_TRACE_DEBUG1("HC lib lpm deassertion return %d", result); 441 } 442 443 /****************************************************************************** 444 ** 445 ** Function bte_main_lpm_wake_bt_device 446 ** 447 ** Description BTE MAIN API - Wake BT controller up if it is in sleep mode 448 ** 449 ** Returns None 450 ** 451 ******************************************************************************/ 452 void bte_main_lpm_wake_bt_device() 453 { 454 int result = -1; 455 456 if ((bt_hc_if) && (lpm_enabled == TRUE)) 457 result = bt_hc_if->lpm(BT_HC_LPM_WAKE_ASSERT); 458 459 APPL_TRACE_DEBUG1("HC lib lpm assertion return %d", result); 460 } 461 #endif // HCILP_INCLUDED 462 463 /****************************************************************************** 464 ** 465 ** Function bte_main_hci_send 466 ** 467 ** Description BTE MAIN API - This function is called by the upper stack to 468 ** send an HCI message. The function displays a protocol trace 469 ** message (if enabled), and then calls the 'transmit' function 470 ** associated with the currently selected HCI transport 471 ** 472 ** Returns None 473 ** 474 ******************************************************************************/ 475 void bte_main_hci_send (BT_HDR *p_msg, UINT16 event) 476 { 477 UINT16 sub_event = event & BT_SUB_EVT_MASK; /* local controller ID */ 478 479 p_msg->event = event; 480 481 482 if((sub_event == LOCAL_BR_EDR_CONTROLLER_ID) || \ 483 (sub_event == LOCAL_BLE_CONTROLLER_ID)) 484 { 485 if (bt_hc_if) 486 bt_hc_if->transmit_buf((TRANSAC)p_msg, \ 487 (char *) (p_msg + 1), \ 488 p_msg->len); 489 else 490 GKI_freebuf(p_msg); 491 } 492 else 493 { 494 APPL_TRACE_ERROR0("Invalid Controller ID. Discarding message."); 495 GKI_freebuf(p_msg); 496 } 497 } 498 499 /****************************************************************************** 500 ** 501 ** Function bte_main_post_reset_init 502 ** 503 ** Description BTE MAIN API - This function is mapped to BTM_APP_DEV_INIT 504 ** and shall be automatically called from BTE after HCI_Reset 505 ** 506 ** Returns None 507 ** 508 ******************************************************************************/ 509 void bte_main_post_reset_init() 510 { 511 BTM_ContinueReset(); 512 } 513 514 /***************************************************************************** 515 ** 516 ** libbt-hci Callback Functions 517 ** 518 *****************************************************************************/ 519 520 /****************************************************************************** 521 ** 522 ** Function preload_cb 523 ** 524 ** Description HOST/CONTROLLER LIB CALLBACK API - This function is called 525 ** when the libbt-hci completed stack preload process 526 ** 527 ** Returns None 528 ** 529 ******************************************************************************/ 530 static void preload_cb(TRANSAC transac, bt_hc_preload_result_t result) 531 { 532 APPL_TRACE_EVENT1("HC preload_cb %d [0:SUCCESS 1:FAIL]", result); 533 534 535 if (result == BT_HC_PRELOAD_SUCCESS) 536 { 537 preload_stop_wait_timer(); 538 539 /* notify BTU task that libbt-hci is ready */ 540 GKI_send_event(BTU_TASK, BT_EVT_PRELOAD_CMPL); 541 } 542 } 543 544 /****************************************************************************** 545 ** 546 ** Function postload_cb 547 ** 548 ** Description HOST/CONTROLLER LIB CALLBACK API - This function is called 549 ** when the libbt-hci lib completed stack postload process 550 ** 551 ** Returns None 552 ** 553 ******************************************************************************/ 554 static void postload_cb(TRANSAC transac, bt_hc_postload_result_t result) 555 { 556 APPL_TRACE_EVENT1("HC postload_cb %d", result); 557 } 558 559 /****************************************************************************** 560 ** 561 ** Function lpm_cb 562 ** 563 ** Description HOST/CONTROLLER LIB CALLBACK API - This function is called 564 ** back from the libbt-hci to indicate the current LPM state 565 ** 566 ** Returns None 567 ** 568 ******************************************************************************/ 569 static void lpm_cb(bt_hc_lpm_request_result_t result) 570 { 571 APPL_TRACE_EVENT1("HC lpm_result_cb %d", result); 572 lpm_enabled = (result == BT_HC_LPM_ENABLED) ? TRUE : FALSE; 573 } 574 575 /****************************************************************************** 576 ** 577 ** Function hostwake_ind 578 ** 579 ** Description HOST/CONTROLLER LIB CALLOUT API - This function is called 580 ** from the libbt-hci to indicate the HostWake event 581 ** 582 ** Returns None 583 ** 584 ******************************************************************************/ 585 static void hostwake_ind(bt_hc_low_power_event_t event) 586 { 587 APPL_TRACE_EVENT1("HC hostwake_ind %d", event); 588 } 589 590 /****************************************************************************** 591 ** 592 ** Function alloc 593 ** 594 ** Description HOST/CONTROLLER LIB CALLOUT API - This function is called 595 ** from the libbt-hci to request for data buffer allocation 596 ** 597 ** Returns NULL / pointer to allocated buffer 598 ** 599 ******************************************************************************/ 600 static char *alloc(int size) 601 { 602 BT_HDR *p_hdr = NULL; 603 604 /* 605 APPL_TRACE_DEBUG1("HC alloc size=%d", size); 606 */ 607 608 p_hdr = (BT_HDR *) GKI_getbuf ((UINT16) size); 609 610 if (p_hdr == NULL) 611 { 612 APPL_TRACE_WARNING0("alloc returns NO BUFFER!"); 613 } 614 615 return ((char *) p_hdr); 616 } 617 618 /****************************************************************************** 619 ** 620 ** Function dealloc 621 ** 622 ** Description HOST/CONTROLLER LIB CALLOUT API - This function is called 623 ** from the libbt-hci to release the data buffer allocated 624 ** through the alloc call earlier 625 ** 626 ** Bluedroid libbt-hci library uses 'transac' parameter to 627 ** pass data-path buffer/packet across bt_hci_lib interface 628 ** boundary. The 'p_buf' is not intended to be used here 629 ** but might point to data portion of data-path buffer. 630 ** 631 ** Returns bt_hc_status_t 632 ** 633 ******************************************************************************/ 634 static int dealloc(TRANSAC transac, char *p_buf) 635 { 636 GKI_freebuf(transac); 637 return BT_HC_STATUS_SUCCESS; 638 } 639 640 /****************************************************************************** 641 ** 642 ** Function data_ind 643 ** 644 ** Description HOST/CONTROLLER LIB CALLOUT API - This function is called 645 ** from the libbt-hci to pass in the received HCI packets 646 ** 647 ** The core stack is responsible for releasing the data buffer 648 ** passed in from the libbt-hci once the core stack has done 649 ** with it. 650 ** 651 ** Bluedroid libbt-hci library uses 'transac' parameter to 652 ** pass data-path buffer/packet across bt_hci_lib interface 653 ** boundary. The 'p_buf' and 'len' parameters are not intended 654 ** to be used here but might point to data portion in data- 655 ** path buffer and length of valid data respectively. 656 ** 657 ** Returns bt_hc_status_t 658 ** 659 ******************************************************************************/ 660 static int data_ind(TRANSAC transac, char *p_buf, int len) 661 { 662 BT_HDR *p_msg = (BT_HDR *) transac; 663 664 /* 665 APPL_TRACE_DEBUG2("HC data_ind event=0x%04X (len=%d)", p_msg->event, len); 666 */ 667 668 GKI_send_msg (BTU_TASK, BTU_HCI_RCV_MBOX, transac); 669 return BT_HC_STATUS_SUCCESS; 670 } 671 672 /****************************************************************************** 673 ** 674 ** Function tx_result 675 ** 676 ** Description HOST/CONTROLLER LIB CALLBACK API - This function is called 677 ** from the libbt-hci once it has processed/sent the prior data 678 ** buffer which core stack passed to it through transmit_buf 679 ** call earlier. 680 ** 681 ** The core stack is responsible for releasing the data buffer 682 ** if it has been completedly processed. 683 ** 684 ** Bluedroid libbt-hci library uses 'transac' parameter to 685 ** pass data-path buffer/packet across bt_hci_lib interface 686 ** boundary. The 'p_buf' is not intended to be used here 687 ** but might point to data portion in data-path buffer. 688 ** 689 ** Returns bt_hc_status_t 690 ** 691 ******************************************************************************/ 692 static int tx_result(TRANSAC transac, char *p_buf, \ 693 bt_hc_transmit_result_t result) 694 { 695 /* 696 APPL_TRACE_DEBUG2("HC tx_result %d (event=%04X)", result, \ 697 ((BT_HDR *)transac)->event); 698 */ 699 700 if (result == BT_HC_TX_FRAGMENT) 701 { 702 GKI_send_msg (BTU_TASK, BTU_HCI_RCV_MBOX, transac); 703 } 704 else 705 { 706 GKI_freebuf(transac); 707 } 708 709 return BT_HC_STATUS_SUCCESS; 710 } 711 712 /***************************************************************************** 713 ** The libbt-hci Callback Functions Table 714 *****************************************************************************/ 715 static const bt_hc_callbacks_t hc_callbacks = { 716 sizeof(bt_hc_callbacks_t), 717 preload_cb, 718 postload_cb, 719 lpm_cb, 720 hostwake_ind, 721 alloc, 722 dealloc, 723 data_ind, 724 tx_result 725 }; 726 727