1 /******************************************************************************
3 * Copyright (C) 2009-2012 Broadcom Corporation
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ******************************************************************************/
19 /******************************************************************************
21 * Filename: bte_main.c
23 * Description: Contains BTE core stack initialization and shutdown code
25 ******************************************************************************/
32 #include <hardware/bluetooth.h>
40 #include "bt_hci_bdroid.h"
42 /*******************************************************************************
44 *******************************************************************************/
46 /* Run-time configuration file */
47 #ifndef BTE_STACK_CONF_FILE
48 #define BTE_STACK_CONF_FILE "/etc/bluetooth/bt_stack.conf"
50 /* Run-time configuration file for BLE*/
51 #ifndef BTE_BLE_STACK_CONF_FILE
52 #define BTE_BLE_STACK_CONF_FILE "/etc/bluetooth/ble_stack.conf"
55 /* if not specified in .txt file then use this as default */
56 #ifndef HCI_LOGGING_FILENAME
57 #define HCI_LOGGING_FILENAME "/data/misc/bluedroid/btsnoop_hci.log"
60 /* Stack preload process timeout period */
61 #ifndef PRELOAD_START_TIMEOUT_MS
62 #define PRELOAD_START_TIMEOUT_MS 3000 // 3 seconds
65 /* Stack preload process maximum retry attempts */
66 #ifndef PRELOAD_MAX_RETRY_ATTEMPTS
67 #define PRELOAD_MAX_RETRY_ATTEMPTS 0
70 /*******************************************************************************
71 ** Local type definitions
72 *******************************************************************************/
73 /* Preload retry control block */
77 BOOLEAN timer_created;
79 } bt_preload_retry_cb_t;
81 /******************************************************************************
83 ******************************************************************************/
84 BOOLEAN hci_logging_enabled = FALSE; /* by default, turn hci log off */
85 BOOLEAN hci_logging_config = FALSE; /* configured from bluetooth framework */
86 BOOLEAN hci_save_log = FALSE; /* save a copy of the log before starting again */
87 char hci_logfile[256] = HCI_LOGGING_FILENAME;
89 /*******************************************************************************
91 *******************************************************************************/
92 static bt_hc_interface_t *bt_hc_if=NULL;
93 static const bt_hc_callbacks_t hc_callbacks;
94 static BOOLEAN lpm_enabled = FALSE;
95 static bt_preload_retry_cb_t preload_retry_cb;
96 // Lock to serialize cleanup requests from upper layer.
97 static pthread_mutex_t cleanup_lock;
99 /*******************************************************************************
101 *******************************************************************************/
102 static void bte_main_in_hw_init(void);
103 static void bte_hci_enable(void);
104 static void bte_hci_disable(void);
105 static void preload_start_wait_timer(void);
106 static void preload_stop_wait_timer(void);
108 /*******************************************************************************
110 *******************************************************************************/
111 BTU_API extern UINT32 btu_task (UINT32 param);
112 BTU_API extern void BTE_Init (void);
113 BT_API extern void BTE_LoadStack(void);
114 BT_API void BTE_UnloadStack(void);
115 extern void scru_flip_bda (BD_ADDR dst, const BD_ADDR src);
116 extern void bte_load_conf(const char *p_path);
117 extern void bte_load_ble_conf(const char *p_path);
118 extern bt_bdaddr_t btif_local_bd_addr;
121 /*******************************************************************************
122 ** System Task Configuration
123 *******************************************************************************/
125 /* bluetooth protocol stack (BTU) task */
126 #ifndef BTE_BTU_STACK_SIZE
127 #define BTE_BTU_STACK_SIZE 0//0x2000 /* In bytes */
129 #define BTE_BTU_TASK_STR ((INT8 *) "BTU")
130 UINT32 bte_btu_stack[(BTE_BTU_STACK_SIZE + 3) / 4];
132 /******************************************************************************
134 ** Function bte_main_in_hw_init
136 ** Description Internal helper function for chip hardware init
140 ******************************************************************************/
141 static void bte_main_in_hw_init(void)
143 if ( (bt_hc_if = (bt_hc_interface_t *) bt_hc_get_interface()) \
146 APPL_TRACE_ERROR("!!! Failed to get BtHostControllerInterface !!!");
149 memset(&preload_retry_cb, 0, sizeof(bt_preload_retry_cb_t));
152 /******************************************************************************
154 ** Function bte_main_boot_entry
156 ** Description BTE MAIN API - Entry point for BTE chip/stack initialization
160 ******************************************************************************/
161 void bte_main_boot_entry(void)
166 bte_main_in_hw_init();
168 bte_load_conf(BTE_STACK_CONF_FILE);
169 #if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
170 bte_load_ble_conf(BTE_BLE_STACK_CONF_FILE);
173 #if (BTTRC_INCLUDED == TRUE)
174 /* Initialize trace feature */
175 BTTRC_TraceInit(MAX_TRACE_RAM_SIZE, &BTE_TraceLogBuf[0], BTTRC_METHOD_RAM);
178 pthread_mutex_init(&cleanup_lock, NULL);
182 /******************************************************************************
184 ** Function bte_main_shutdown
186 ** Description BTE MAIN API - Shutdown code for BTE chip/stack
190 ******************************************************************************/
191 void bte_main_shutdown()
193 pthread_mutex_destroy(&cleanup_lock);
198 /******************************************************************************
200 ** Function bte_main_enable
202 ** Description BTE MAIN API - Creates all the BTE tasks. Should be called
203 ** part of the Bluetooth stack enable sequence
207 ******************************************************************************/
208 void bte_main_enable()
210 APPL_TRACE_DEBUG("%s", __FUNCTION__);
212 /* Initialize BTE control block */
217 GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR,
218 (UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE),
219 sizeof(bte_btu_stack));
226 /******************************************************************************
228 ** Function bte_main_disable
230 ** Description BTE MAIN API - Destroys all the BTE tasks. Should be called
231 ** part of the Bluetooth stack disable sequence
235 ******************************************************************************/
236 void bte_main_disable(void)
238 APPL_TRACE_DEBUG("%s", __FUNCTION__);
240 preload_stop_wait_timer();
242 GKI_destroy_task(BTU_TASK);
245 /******************************************************************************
247 ** Function bte_main_config_hci_logging
249 ** Description enable or disable HIC snoop logging
253 ******************************************************************************/
254 void bte_main_config_hci_logging(BOOLEAN enable, BOOLEAN bt_disabled)
256 int old = (hci_logging_enabled == TRUE) || (hci_logging_config == TRUE);
260 hci_logging_config = TRUE;
262 hci_logging_config = FALSE;
265 new = (hci_logging_enabled == TRUE) || (hci_logging_config == TRUE);
267 if ((old == new) || bt_disabled || (bt_hc_if == NULL)) {
271 bt_hc_if->logging(new ? BT_HC_LOGGING_ON : BT_HC_LOGGING_OFF, hci_logfile, hci_save_log);
274 /******************************************************************************
276 ** Function bte_hci_enable
278 ** Description Enable HCI & Vendor modules
282 ******************************************************************************/
283 static void bte_hci_enable(void)
285 APPL_TRACE_DEBUG("%s", __FUNCTION__);
287 preload_start_wait_timer();
291 int result = bt_hc_if->init(&hc_callbacks, btif_local_bd_addr.address);
292 APPL_TRACE_EVENT("libbt-hci init returns %d", result);
294 assert(result == BT_HC_STATUS_SUCCESS);
296 if (hci_logging_enabled == TRUE || hci_logging_config == TRUE)
297 bt_hc_if->logging(BT_HC_LOGGING_ON, hci_logfile, hci_save_log);
299 #if (defined (BT_CLEAN_TURN_ON_DISABLED) && BT_CLEAN_TURN_ON_DISABLED == TRUE)
300 APPL_TRACE_DEBUG("%s Not Turninig Off the BT before Turninig ON", __FUNCTION__);
302 /* Do not power off the chip before powering on if BT_CLEAN_TURN_ON_DISABLED flag
303 is defined and set to TRUE to avoid below mentioned issue.
305 Wingray kernel driver maintains a combined counter to keep track of
306 BT-Wifi state. Invoking set_power(BT_HC_CHIP_PWR_OFF) when the BT is already
307 in OFF state causes this counter to be incorrectly decremented and results in undesired
308 behavior of the chip.
310 This is only a workaround and when the issue is fixed in the kernel this work around
311 should be removed. */
313 /* toggle chip power to ensure we will reset chip in case
314 a previous stack shutdown wasn't completed gracefully */
315 bt_hc_if->set_power(BT_HC_CHIP_PWR_OFF);
317 bt_hc_if->set_power(BT_HC_CHIP_PWR_ON);
319 bt_hc_if->preload(NULL);
323 /******************************************************************************
325 ** Function bte_hci_disable
327 ** Description Disable HCI & Vendor modules
331 ******************************************************************************/
332 static void bte_hci_disable(void)
334 APPL_TRACE_DEBUG("%s", __FUNCTION__);
339 // Cleanup is not thread safe and must be protected.
340 pthread_mutex_lock(&cleanup_lock);
342 if (hci_logging_enabled == TRUE || hci_logging_config == TRUE)
343 bt_hc_if->logging(BT_HC_LOGGING_OFF, hci_logfile, hci_save_log);
346 pthread_mutex_unlock(&cleanup_lock);
349 /*******************************************************************************
351 ** Function preload_wait_timeout
353 ** Description Timeout thread of preload watchdog timer
357 *******************************************************************************/
358 static void preload_wait_timeout(union sigval arg)
362 APPL_TRACE_ERROR("...preload_wait_timeout (retried:%d/max-retry:%d)...",
363 preload_retry_cb.retry_counts,
364 PRELOAD_MAX_RETRY_ATTEMPTS);
366 if (preload_retry_cb.retry_counts++ < PRELOAD_MAX_RETRY_ATTEMPTS)
374 /* Notify BTIF_TASK that the init procedure had failed*/
375 GKI_send_event(BTIF_TASK, BT_EVT_HARDWARE_INIT_FAIL);
379 /*******************************************************************************
381 ** Function preload_start_wait_timer
383 ** Description Launch startup watchdog timer
387 *******************************************************************************/
388 static void preload_start_wait_timer(void)
391 struct itimerspec ts;
393 UINT32 timeout_ms = PRELOAD_START_TIMEOUT_MS;
395 if (preload_retry_cb.timer_created == FALSE)
397 se.sigev_notify = SIGEV_THREAD;
398 se.sigev_value.sival_ptr = &preload_retry_cb.timer_id;
399 se.sigev_notify_function = preload_wait_timeout;
400 se.sigev_notify_attributes = NULL;
402 status = timer_create(CLOCK_MONOTONIC, &se, &preload_retry_cb.timer_id);
405 preload_retry_cb.timer_created = TRUE;
408 if (preload_retry_cb.timer_created == TRUE)
410 ts.it_value.tv_sec = timeout_ms/1000;
411 ts.it_value.tv_nsec = 1000000*(timeout_ms%1000);
412 ts.it_interval.tv_sec = 0;
413 ts.it_interval.tv_nsec = 0;
415 status = timer_settime(preload_retry_cb.timer_id, 0, &ts, 0);
417 APPL_TRACE_ERROR("Failed to fire preload watchdog timer");
421 /*******************************************************************************
423 ** Function preload_stop_wait_timer
425 ** Description Stop preload watchdog timer
429 *******************************************************************************/
430 static void preload_stop_wait_timer(void)
432 if (preload_retry_cb.timer_created == TRUE)
434 timer_delete(preload_retry_cb.timer_id);
435 preload_retry_cb.timer_created = FALSE;
439 /******************************************************************************
441 ** Function bte_main_postload_cfg
443 ** Description BTE MAIN API - Stack postload configuration
447 ******************************************************************************/
448 void bte_main_postload_cfg(void)
451 bt_hc_if->postload(NULL);
454 #if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
455 /******************************************************************************
457 ** Function bte_main_enable_lpm
459 ** Description BTE MAIN API - Enable/Disable low power mode operation
463 ******************************************************************************/
464 void bte_main_enable_lpm(BOOLEAN enable)
469 result = bt_hc_if->lpm( \
470 (enable == TRUE) ? BT_HC_LPM_ENABLE : BT_HC_LPM_DISABLE \
473 APPL_TRACE_EVENT("HC lib lpm enable=%d return %d", enable, result);
476 /******************************************************************************
478 ** Function bte_main_lpm_allow_bt_device_sleep
480 ** Description BTE MAIN API - Allow BT controller goest to sleep
484 ******************************************************************************/
485 void bte_main_lpm_allow_bt_device_sleep()
489 if ((bt_hc_if) && (lpm_enabled == TRUE))
490 result = bt_hc_if->lpm(BT_HC_LPM_WAKE_DEASSERT);
492 APPL_TRACE_DEBUG("HC lib lpm deassertion return %d", result);
495 /******************************************************************************
497 ** Function bte_main_lpm_wake_bt_device
499 ** Description BTE MAIN API - Wake BT controller up if it is in sleep mode
503 ******************************************************************************/
504 void bte_main_lpm_wake_bt_device()
508 if ((bt_hc_if) && (lpm_enabled == TRUE))
509 result = bt_hc_if->lpm(BT_HC_LPM_WAKE_ASSERT);
511 APPL_TRACE_DEBUG("HC lib lpm assertion return %d", result);
513 #endif // HCILP_INCLUDED
517 * Definitions for audio state structure, this type needs to match to
518 * the bt_vendor_op_audio_state_t type defined in bt_vendor_lib.h
524 } bt_hc_audio_state_t;
526 struct bt_audio_state_tag {
528 bt_hc_audio_state_t audio;
531 /******************************************************************************
533 ** Function set_audio_state
535 ** Description Sets audio state on controller state for SCO (PCM, WBS, FM)
537 ** Parameters handle: codec related handle for SCO: sco cb idx, unused for
538 ** codec: BTA_AG_CODEC_MSBC, BTA_AG_CODEC_CSVD or FM codec
539 ** state: codec state, eg. BTA_AG_CO_AUD_STATE_SETUP
540 ** param: future extensions, e.g. call-in structure/event.
544 ******************************************************************************/
545 int set_audio_state(UINT16 handle, UINT16 codec, UINT8 state, void *param)
547 struct bt_audio_state_tag *p_msg;
550 APPL_TRACE_API("set_audio_state(handle: %d, codec: 0x%x, state: %d)", handle,
553 APPL_TRACE_WARNING("set_audio_state() non-null param not supported");
554 p_msg = (struct bt_audio_state_tag *)GKI_getbuf(sizeof(*p_msg));
557 p_msg->audio.handle = handle;
558 p_msg->audio.peer_codec = codec;
559 p_msg->audio.state = state;
561 p_msg->hdr.event = MSG_CTRL_TO_HC_CMD | (MSG_SUB_EVT_MASK & BT_HC_AUDIO_STATE);
562 p_msg->hdr.len = sizeof(p_msg->audio);
563 p_msg->hdr.offset = 0;
564 /* layer_specific shall contain return path event! for BTA events!
565 * 0 means no return message is expected. */
566 p_msg->hdr.layer_specific = 0;
569 bt_hc_if->tx_cmd((TRANSAC)p_msg, (char *)(&p_msg->audio), sizeof(*p_msg));
575 /******************************************************************************
577 ** Function bte_main_hci_send
579 ** Description BTE MAIN API - This function is called by the upper stack to
580 ** send an HCI message. The function displays a protocol trace
581 ** message (if enabled), and then calls the 'transmit' function
582 ** associated with the currently selected HCI transport
586 ******************************************************************************/
587 void bte_main_hci_send (BT_HDR *p_msg, UINT16 event)
589 UINT16 sub_event = event & BT_SUB_EVT_MASK; /* local controller ID */
591 p_msg->event = event;
594 if((sub_event == LOCAL_BR_EDR_CONTROLLER_ID) || \
595 (sub_event == LOCAL_BLE_CONTROLLER_ID))
598 bt_hc_if->transmit_buf((TRANSAC)p_msg, \
599 (char *) (p_msg + 1), \
606 APPL_TRACE_ERROR("Invalid Controller ID. Discarding message.");
611 /******************************************************************************
613 ** Function bte_main_post_reset_init
615 ** Description BTE MAIN API - This function is mapped to BTM_APP_DEV_INIT
616 ** and shall be automatically called from BTE after HCI_Reset
620 ******************************************************************************/
621 void bte_main_post_reset_init()
626 /*****************************************************************************
628 ** libbt-hci Callback Functions
630 *****************************************************************************/
632 /******************************************************************************
634 ** Function preload_cb
636 ** Description HOST/CONTROLLER LIB CALLBACK API - This function is called
637 ** when the libbt-hci completed stack preload process
641 ******************************************************************************/
642 static void preload_cb(TRANSAC transac, bt_hc_preload_result_t result)
646 APPL_TRACE_EVENT("HC preload_cb %d [0:SUCCESS 1:FAIL]", result);
648 if (result == BT_HC_PRELOAD_SUCCESS)
650 preload_stop_wait_timer();
652 /* notify BTU task that libbt-hci is ready */
653 GKI_send_event(BTU_TASK, BT_EVT_PRELOAD_CMPL);
657 /******************************************************************************
659 ** Function postload_cb
661 ** Description HOST/CONTROLLER LIB CALLBACK API - This function is called
662 ** when the libbt-hci lib completed stack postload process
666 ******************************************************************************/
667 static void postload_cb(TRANSAC transac, bt_hc_postload_result_t result)
671 APPL_TRACE_EVENT("HC postload_cb %d", result);
674 /******************************************************************************
678 ** Description HOST/CONTROLLER LIB CALLBACK API - This function is called
679 ** back from the libbt-hci to indicate the current LPM state
683 ******************************************************************************/
684 static void lpm_cb(bt_hc_lpm_request_result_t result)
686 APPL_TRACE_EVENT("HC lpm_result_cb %d", result);
687 lpm_enabled = (result == BT_HC_LPM_ENABLED) ? TRUE : FALSE;
690 /******************************************************************************
692 ** Function hostwake_ind
694 ** Description HOST/CONTROLLER LIB CALLOUT API - This function is called
695 ** from the libbt-hci to indicate the HostWake event
699 ******************************************************************************/
700 static void hostwake_ind(bt_hc_low_power_event_t event)
702 APPL_TRACE_EVENT("HC hostwake_ind %d", event);
705 /******************************************************************************
709 ** Description HOST/CONTROLLER LIB CALLOUT API - This function is called
710 ** from the libbt-hci to request for data buffer allocation
712 ** Returns NULL / pointer to allocated buffer
714 ******************************************************************************/
715 static char *alloc(int size)
717 BT_HDR *p_hdr = NULL;
720 APPL_TRACE_DEBUG("HC alloc size=%d", size);
723 /* Requested buffer size cannot exceed GKI_MAX_BUF_SIZE. */
724 if (size > GKI_MAX_BUF_SIZE)
726 APPL_TRACE_ERROR("HCI DATA SIZE %d greater than MAX %d",
727 size, GKI_MAX_BUF_SIZE);
731 p_hdr = (BT_HDR *) GKI_getbuf ((UINT16) size);
735 APPL_TRACE_WARNING("alloc returns NO BUFFER! (sz %d)", size);
738 return ((char *) p_hdr);
741 /******************************************************************************
745 ** Description HOST/CONTROLLER LIB CALLOUT API - This function is called
746 ** from the libbt-hci to release the data buffer allocated
747 ** through the alloc call earlier
749 ** Bluedroid libbt-hci library uses 'transac' parameter to
750 ** pass data-path buffer/packet across bt_hci_lib interface
753 ******************************************************************************/
754 static void dealloc(TRANSAC transac)
756 GKI_freebuf(transac);
759 /******************************************************************************
763 ** Description HOST/CONTROLLER LIB CALLOUT API - This function is called
764 ** from the libbt-hci to pass in the received HCI packets
766 ** The core stack is responsible for releasing the data buffer
767 ** passed in from the libbt-hci once the core stack has done
770 ** Bluedroid libbt-hci library uses 'transac' parameter to
771 ** pass data-path buffer/packet across bt_hci_lib interface
772 ** boundary. The 'p_buf' and 'len' parameters are not intended
773 ** to be used here but might point to data portion in data-
774 ** path buffer and length of valid data respectively.
776 ** Returns bt_hc_status_t
778 ******************************************************************************/
779 static int data_ind(TRANSAC transac, char *p_buf, int len)
785 APPL_TRACE_DEBUG("HC data_ind event=0x%04X (len=%d)", p_msg->event, len);
788 GKI_send_msg (BTU_TASK, BTU_HCI_RCV_MBOX, transac);
789 return BT_HC_STATUS_SUCCESS;
792 /******************************************************************************
794 ** Function tx_result
796 ** Description HOST/CONTROLLER LIB CALLBACK API - This function is called
797 ** from the libbt-hci once it has processed/sent the prior data
798 ** buffer which core stack passed to it through transmit_buf
801 ** The core stack is responsible for releasing the data buffer
802 ** if it has been completedly processed.
804 ** Bluedroid libbt-hci library uses 'transac' parameter to
805 ** pass data-path buffer/packet across bt_hci_lib interface
806 ** boundary. The 'p_buf' is not intended to be used here
807 ** but might point to data portion in data-path buffer.
809 ** Returns bt_hc_status_t
811 ******************************************************************************/
812 static int tx_result(TRANSAC transac, char *p_buf, bt_hc_transmit_result_t result)
816 APPL_TRACE_DEBUG("HC tx_result %d (event=%04X)", result, \
817 ((BT_HDR *)transac)->event);
820 if (result == BT_HC_TX_FRAGMENT)
822 GKI_send_msg (BTU_TASK, BTU_HCI_RCV_MBOX, transac);
826 GKI_freebuf(transac);
829 return BT_HC_STATUS_SUCCESS;
832 /*****************************************************************************
833 ** The libbt-hci Callback Functions Table
834 *****************************************************************************/
835 static const bt_hc_callbacks_t hc_callbacks = {
836 sizeof(bt_hc_callbacks_t),