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