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 */ 79char hci_logfile[256] = HCI_LOGGING_FILENAME; 80 81 82/******************************************************************************* 83** Static variables 84*******************************************************************************/ 85static bt_hc_interface_t *bt_hc_if=NULL; 86static const bt_hc_callbacks_t hc_callbacks; 87static BOOLEAN lpm_enabled = FALSE; 88static bt_preload_retry_cb_t preload_retry_cb; 89 90/******************************************************************************* 91** Static functions 92*******************************************************************************/ 93static void bte_main_in_hw_init(void); 94static void bte_hci_enable(void); 95static void bte_hci_disable(void); 96static void preload_start_wait_timer(void); 97static void preload_stop_wait_timer(void); 98 99/******************************************************************************* 100** Externs 101*******************************************************************************/ 102BTU_API extern UINT32 btu_task (UINT32 param); 103BTU_API extern void BTE_Init (void); 104BT_API extern void BTE_LoadStack(void); 105BT_API void BTE_UnloadStack(void); 106extern void scru_flip_bda (BD_ADDR dst, const BD_ADDR src); 107extern void bte_load_conf(const char *p_path); 108extern 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") 120UINT32 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******************************************************************************/ 131static 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******************************************************************************/ 151void 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******************************************************************************/ 175void 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******************************************************************************/ 190void 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******************************************************************************/ 218void 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******************************************************************************/ 237static 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******************************************************************************/ 286static 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*******************************************************************************/ 308static 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*******************************************************************************/ 336static 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*******************************************************************************/ 378static 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******************************************************************************/ 396void 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******************************************************************************/ 412void 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******************************************************************************/ 433void 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******************************************************************************/ 452void 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******************************************************************************/ 475void 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******************************************************************************/ 509void 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******************************************************************************/ 530static 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******************************************************************************/ 554static 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******************************************************************************/ 569static 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******************************************************************************/ 585static 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******************************************************************************/ 600static 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******************************************************************************/ 634static 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******************************************************************************/ 660static 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******************************************************************************/ 692static 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*****************************************************************************/ 715static 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