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