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