Home | History | Annotate | Download | only in main
      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 
     30 #include "gki.h"
     31 #include "bd.h"
     32 #include "btu.h"
     33 #include "bte.h"
     34 #include "bta_api.h"
     35 #include "bt_hci_lib.h"
     36 
     37 /*******************************************************************************
     38 **  Constants & Macros
     39 *******************************************************************************/
     40 
     41 /* Run-time configuration file */
     42 #ifndef BTE_STACK_CONF_FILE
     43 #define BTE_STACK_CONF_FILE "/etc/bluetooth/bt_stack.conf"
     44 #endif
     45 
     46 /* if not specified in .txt file then use this as default  */
     47 #ifndef HCI_LOGGING_FILENAME
     48 #define HCI_LOGGING_FILENAME  "/data/misc/bluedroid/btsnoop_hci.log"
     49 #endif
     50 
     51 /*******************************************************************************
     52 **  Local type definitions
     53 *******************************************************************************/
     54 
     55 /******************************************************************************
     56 **  Variables
     57 ******************************************************************************/
     58 BOOLEAN hci_logging_enabled = FALSE;    /* by default, turn hci log off */
     59 char hci_logfile[256] = HCI_LOGGING_FILENAME;
     60 
     61 
     62 /*******************************************************************************
     63 **  Static variables
     64 *******************************************************************************/
     65 static bt_hc_interface_t *bt_hc_if=NULL;
     66 static const bt_hc_callbacks_t hc_callbacks;
     67 static BOOLEAN lpm_enabled = FALSE;
     68 
     69 /*******************************************************************************
     70 **  Static functions
     71 *******************************************************************************/
     72 static void bte_main_in_hw_init(void);
     73 
     74 /*******************************************************************************
     75 **  Externs
     76 *******************************************************************************/
     77 BTU_API extern UINT32 btu_task (UINT32 param);
     78 BTU_API extern void BTE_Init (void);
     79 BT_API extern void BTE_LoadStack(void);
     80 BT_API void BTE_UnloadStack(void);
     81 extern void scru_flip_bda (BD_ADDR dst, const BD_ADDR src);
     82 extern void bte_load_conf(const char *p_path);
     83 
     84 
     85 /*******************************************************************************
     86 **                        System Task Configuration
     87 *******************************************************************************/
     88 
     89 /* bluetooth protocol stack (BTU) task */
     90 #ifndef BTE_BTU_STACK_SIZE
     91 #define BTE_BTU_STACK_SIZE       0//0x2000         /* In bytes */
     92 #endif
     93 #define BTE_BTU_TASK_STR        ((INT8 *) "BTU")
     94 UINT32 bte_btu_stack[(BTE_BTU_STACK_SIZE + 3) / 4];
     95 
     96 /******************************************************************************
     97 **
     98 ** Function         bte_main_in_hw_init
     99 **
    100 ** Description      Internal helper function for chip hardware init
    101 **
    102 ** Returns          None
    103 **
    104 ******************************************************************************/
    105 void bte_main_in_hw_init(void)
    106 {
    107     if ( (bt_hc_if = (bt_hc_interface_t *) bt_hc_get_interface()) \
    108          == NULL)
    109     {
    110         APPL_TRACE_ERROR0("!!! Failed to get BtHostControllerInterface !!!");
    111     }
    112 }
    113 
    114 /******************************************************************************
    115 **
    116 ** Function         bte_main_boot_entry
    117 **
    118 ** Description      BTE MAIN API - Entry point for BTE chip/stack initialization
    119 **
    120 ** Returns          None
    121 **
    122 ******************************************************************************/
    123 void bte_main_boot_entry(void)
    124 {
    125     /* initialize OS */
    126     GKI_init();
    127 
    128     bte_main_in_hw_init();
    129 
    130     bte_load_conf(BTE_STACK_CONF_FILE);
    131 
    132 #if (BTTRC_INCLUDED == TRUE)
    133     /* Initialize trace feature */
    134     BTTRC_TraceInit(MAX_TRACE_RAM_SIZE, &BTE_TraceLogBuf[0], BTTRC_METHOD_RAM);
    135 #endif
    136 }
    137 
    138 /******************************************************************************
    139 **
    140 ** Function         bte_main_shutdown
    141 **
    142 ** Description      BTE MAIN API - Shutdown code for BTE chip/stack
    143 **
    144 ** Returns          None
    145 **
    146 ******************************************************************************/
    147 void bte_main_shutdown()
    148 {
    149     GKI_shutdown();
    150 }
    151 
    152 /******************************************************************************
    153 **
    154 ** Function         bte_main_enable
    155 **
    156 ** Description      BTE MAIN API - Creates all the BTE tasks. Should be called
    157 **                  part of the Bluetooth stack enable sequence
    158 **
    159 ** Returns          None
    160 **
    161 ******************************************************************************/
    162 void bte_main_enable(uint8_t *local_addr)
    163 {
    164     APPL_TRACE_DEBUG1("%s", __FUNCTION__);
    165 
    166     /* Initialize BTE control block */
    167     BTE_Init();
    168 
    169     lpm_enabled = FALSE;
    170 
    171     if (bt_hc_if)
    172     {
    173         int result = bt_hc_if->init(&hc_callbacks, local_addr);
    174         APPL_TRACE_EVENT1("libbt-hci init returns %d", result);
    175 
    176         assert(result == BT_HC_STATUS_SUCCESS);
    177 
    178         if (hci_logging_enabled == TRUE)
    179             bt_hc_if->logging(BT_HC_LOGGING_ON, hci_logfile);
    180 
    181 #if (defined (BT_CLEAN_TURN_ON_DISABLED) && BT_CLEAN_TURN_ON_DISABLED == TRUE)
    182         APPL_TRACE_DEBUG1("%s  Not Turninig Off the BT before Turninig ON", __FUNCTION__);
    183 
    184         /* Do not power off the chip before powering on  if BT_CLEAN_TURN_ON_DISABLED flag
    185          is defined and set to TRUE to avoid below mentioned issue.
    186 
    187          Wingray kernel driver maintains a combined  counter to keep track of
    188          BT-Wifi state. Invoking  set_power(BT_HC_CHIP_PWR_OFF) when the BT is already
    189          in OFF state causes this counter to be incorrectly decremented and results in undesired
    190          behavior of the chip.
    191 
    192          This is only a workaround and when the issue is fixed in the kernel this work around
    193          should be removed. */
    194 #else
    195         /* toggle chip power to ensure we will reset chip in case
    196            a previous stack shutdown wasn't completed gracefully */
    197         bt_hc_if->set_power(BT_HC_CHIP_PWR_OFF);
    198 #endif
    199         bt_hc_if->set_power(BT_HC_CHIP_PWR_ON);
    200 
    201         bt_hc_if->preload(NULL);
    202     }
    203 
    204     GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR,
    205                     (UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE),
    206                     sizeof(bte_btu_stack));
    207 
    208     GKI_run(0);
    209 }
    210 
    211 /******************************************************************************
    212 **
    213 ** Function         bte_main_disable
    214 **
    215 ** Description      BTE MAIN API - Destroys all the BTE tasks. Should be called
    216 **                  part of the Bluetooth stack disable sequence
    217 **
    218 ** Returns          None
    219 **
    220 ******************************************************************************/
    221 void bte_main_disable(void)
    222 {
    223     APPL_TRACE_DEBUG1("%s", __FUNCTION__);
    224 
    225     if (bt_hc_if)
    226     {
    227         bt_hc_if->cleanup();
    228         bt_hc_if->set_power(BT_HC_CHIP_PWR_OFF);
    229     }
    230 
    231     GKI_destroy_task(BTU_TASK);
    232 
    233     GKI_freeze();
    234 }
    235 
    236 /******************************************************************************
    237 **
    238 ** Function         bte_main_postload_cfg
    239 **
    240 ** Description      BTE MAIN API - Stack postload configuration
    241 **
    242 ** Returns          None
    243 **
    244 ******************************************************************************/
    245 void bte_main_postload_cfg(void)
    246 {
    247     if (bt_hc_if)
    248         bt_hc_if->postload(NULL);
    249 }
    250 
    251 #if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
    252 /******************************************************************************
    253 **
    254 ** Function         bte_main_enable_lpm
    255 **
    256 ** Description      BTE MAIN API - Enable/Disable low power mode operation
    257 **
    258 ** Returns          None
    259 **
    260 ******************************************************************************/
    261 void bte_main_enable_lpm(BOOLEAN enable)
    262 {
    263     int result = -1;
    264 
    265     if (bt_hc_if)
    266         result = bt_hc_if->lpm( \
    267         (enable == TRUE) ? BT_HC_LPM_ENABLE : BT_HC_LPM_DISABLE \
    268         );
    269 
    270     APPL_TRACE_EVENT2("HC lib lpm enable=%d return %d", enable, result);
    271 }
    272 
    273 /******************************************************************************
    274 **
    275 ** Function         bte_main_lpm_allow_bt_device_sleep
    276 **
    277 ** Description      BTE MAIN API - Allow BT controller goest to sleep
    278 **
    279 ** Returns          None
    280 **
    281 ******************************************************************************/
    282 void bte_main_lpm_allow_bt_device_sleep()
    283 {
    284     int result = -1;
    285 
    286     if ((bt_hc_if) && (lpm_enabled == TRUE))
    287         result = bt_hc_if->lpm(BT_HC_LPM_WAKE_DEASSERT);
    288 
    289     APPL_TRACE_DEBUG1("HC lib lpm deassertion return %d", result);
    290 }
    291 
    292 /******************************************************************************
    293 **
    294 ** Function         bte_main_lpm_wake_bt_device
    295 **
    296 ** Description      BTE MAIN API - Wake BT controller up if it is in sleep mode
    297 **
    298 ** Returns          None
    299 **
    300 ******************************************************************************/
    301 void bte_main_lpm_wake_bt_device()
    302 {
    303     int result = -1;
    304 
    305     if ((bt_hc_if) && (lpm_enabled == TRUE))
    306         result = bt_hc_if->lpm(BT_HC_LPM_WAKE_ASSERT);
    307 
    308     APPL_TRACE_DEBUG1("HC lib lpm assertion return %d", result);
    309 }
    310 #endif  // HCILP_INCLUDED
    311 
    312 /******************************************************************************
    313 **
    314 ** Function         bte_main_hci_send
    315 **
    316 ** Description      BTE MAIN API - This function is called by the upper stack to
    317 **                  send an HCI message. The function displays a protocol trace
    318 **                  message (if enabled), and then calls the 'transmit' function
    319 **                  associated with the currently selected HCI transport
    320 **
    321 ** Returns          None
    322 **
    323 ******************************************************************************/
    324 void bte_main_hci_send (BT_HDR *p_msg, UINT16 event)
    325 {
    326     UINT16 sub_event = event & BT_SUB_EVT_MASK;  /* local controller ID */
    327 
    328     p_msg->event = event;
    329 
    330 
    331     if((sub_event == LOCAL_BR_EDR_CONTROLLER_ID) || \
    332        (sub_event == LOCAL_BLE_CONTROLLER_ID))
    333     {
    334         if (bt_hc_if)
    335             bt_hc_if->transmit_buf((TRANSAC)p_msg, \
    336                                        (char *) (p_msg + 1), \
    337                                         p_msg->len);
    338         else
    339             GKI_freebuf(p_msg);
    340     }
    341     else
    342     {
    343         APPL_TRACE_ERROR0("Invalid Controller ID. Discarding message.");
    344         GKI_freebuf(p_msg);
    345     }
    346 }
    347 
    348 /******************************************************************************
    349 **
    350 ** Function         bte_main_post_reset_init
    351 **
    352 ** Description      BTE MAIN API - This function is mapped to BTM_APP_DEV_INIT
    353 **                  and shall be automatically called from BTE after HCI_Reset
    354 **
    355 ** Returns          None
    356 **
    357 ******************************************************************************/
    358 void bte_main_post_reset_init()
    359 {
    360     BTM_ContinueReset();
    361 }
    362 
    363 /*****************************************************************************
    364 **
    365 **   libbt-hci Callback Functions
    366 **
    367 *****************************************************************************/
    368 
    369 /******************************************************************************
    370 **
    371 ** Function         preload_cb
    372 **
    373 ** Description      HOST/CONTROLLER LIB CALLBACK API - This function is called
    374 **                  when the libbt-hci completed stack preload process
    375 **
    376 ** Returns          None
    377 **
    378 ******************************************************************************/
    379 static void preload_cb(TRANSAC transac, bt_hc_preload_result_t result)
    380 {
    381     APPL_TRACE_EVENT1("HC preload_cb %d [0:SUCCESS 1:FAIL]", result);
    382 
    383     /* notify BTU task that libbt-hci is ready */
    384     /* even if PRELOAD process failed */
    385     GKI_send_event(BTU_TASK, TASK_MBOX_0_EVT_MASK);
    386 }
    387 
    388 /******************************************************************************
    389 **
    390 ** Function         postload_cb
    391 **
    392 ** Description      HOST/CONTROLLER LIB CALLBACK API - This function is called
    393 **                  when the libbt-hci lib completed stack postload process
    394 **
    395 ** Returns          None
    396 **
    397 ******************************************************************************/
    398 static void postload_cb(TRANSAC transac, bt_hc_postload_result_t result)
    399 {
    400     APPL_TRACE_EVENT1("HC postload_cb %d", result);
    401 }
    402 
    403 /******************************************************************************
    404 **
    405 ** Function         lpm_cb
    406 **
    407 ** Description      HOST/CONTROLLER LIB CALLBACK API - This function is called
    408 **                  back from the libbt-hci to indicate the current LPM state
    409 **
    410 ** Returns          None
    411 **
    412 ******************************************************************************/
    413 static void lpm_cb(bt_hc_lpm_request_result_t result)
    414 {
    415     APPL_TRACE_EVENT1("HC lpm_result_cb %d", result);
    416     lpm_enabled = (result == BT_HC_LPM_ENABLED) ? TRUE : FALSE;
    417 }
    418 
    419 /******************************************************************************
    420 **
    421 ** Function         hostwake_ind
    422 **
    423 ** Description      HOST/CONTROLLER LIB CALLOUT API - This function is called
    424 **                  from the libbt-hci to indicate the HostWake event
    425 **
    426 ** Returns          None
    427 **
    428 ******************************************************************************/
    429 static void hostwake_ind(bt_hc_low_power_event_t event)
    430 {
    431     APPL_TRACE_EVENT1("HC hostwake_ind %d", event);
    432 }
    433 
    434 /******************************************************************************
    435 **
    436 ** Function         alloc
    437 **
    438 ** Description      HOST/CONTROLLER LIB CALLOUT API - This function is called
    439 **                  from the libbt-hci to request for data buffer allocation
    440 **
    441 ** Returns          NULL / pointer to allocated buffer
    442 **
    443 ******************************************************************************/
    444 static char *alloc(int size)
    445 {
    446     BT_HDR *p_hdr = NULL;
    447 
    448     /*
    449     APPL_TRACE_DEBUG1("HC alloc size=%d", size);
    450     */
    451 
    452     p_hdr = (BT_HDR *) GKI_getbuf ((UINT16) size);
    453 
    454     if (p_hdr == NULL)
    455     {
    456         APPL_TRACE_WARNING0("alloc returns NO BUFFER!");
    457     }
    458 
    459     return ((char *) p_hdr);
    460 }
    461 
    462 /******************************************************************************
    463 **
    464 ** Function         dealloc
    465 **
    466 ** Description      HOST/CONTROLLER LIB CALLOUT API - This function is called
    467 **                  from the libbt-hci to release the data buffer allocated
    468 **                  through the alloc call earlier
    469 **
    470 **                  Bluedroid libbt-hci library uses 'transac' parameter to
    471 **                  pass data-path buffer/packet across bt_hci_lib interface
    472 **                  boundary. The 'p_buf' is not intended to be used here
    473 **                  but might point to data portion of data-path buffer.
    474 **
    475 ** Returns          bt_hc_status_t
    476 **
    477 ******************************************************************************/
    478 static int dealloc(TRANSAC transac, char *p_buf)
    479 {
    480     GKI_freebuf(transac);
    481     return BT_HC_STATUS_SUCCESS;
    482 }
    483 
    484 /******************************************************************************
    485 **
    486 ** Function         data_ind
    487 **
    488 ** Description      HOST/CONTROLLER LIB CALLOUT API - This function is called
    489 **                  from the libbt-hci to pass in the received HCI packets
    490 **
    491 **                  The core stack is responsible for releasing the data buffer
    492 **                  passed in from the libbt-hci once the core stack has done
    493 **                  with it.
    494 **
    495 **                  Bluedroid libbt-hci library uses 'transac' parameter to
    496 **                  pass data-path buffer/packet across bt_hci_lib interface
    497 **                  boundary. The 'p_buf' and 'len' parameters are not intended
    498 **                  to be used here but might point to data portion in data-
    499 **                  path buffer and length of valid data respectively.
    500 **
    501 ** Returns          bt_hc_status_t
    502 **
    503 ******************************************************************************/
    504 static int data_ind(TRANSAC transac, char *p_buf, int len)
    505 {
    506     BT_HDR *p_msg = (BT_HDR *) transac;
    507 
    508     /*
    509     APPL_TRACE_DEBUG2("HC data_ind event=0x%04X (len=%d)", p_msg->event, len);
    510     */
    511 
    512     GKI_send_msg (BTU_TASK, BTU_HCI_RCV_MBOX, transac);
    513     return BT_HC_STATUS_SUCCESS;
    514 }
    515 
    516 /******************************************************************************
    517 **
    518 ** Function         tx_result
    519 **
    520 ** Description      HOST/CONTROLLER LIB CALLBACK API - This function is called
    521 **                  from the libbt-hci once it has processed/sent the prior data
    522 **                  buffer which core stack passed to it through transmit_buf
    523 **                  call earlier.
    524 **
    525 **                  The core stack is responsible for releasing the data buffer
    526 **                  if it has been completedly processed.
    527 **
    528 **                  Bluedroid libbt-hci library uses 'transac' parameter to
    529 **                  pass data-path buffer/packet across bt_hci_lib interface
    530 **                  boundary. The 'p_buf' is not intended to be used here
    531 **                  but might point to data portion in data-path buffer.
    532 **
    533 ** Returns          bt_hc_status_t
    534 **
    535 ******************************************************************************/
    536 static int tx_result(TRANSAC transac, char *p_buf, \
    537                       bt_hc_transmit_result_t result)
    538 {
    539     /*
    540     APPL_TRACE_DEBUG2("HC tx_result %d (event=%04X)", result, \
    541                       ((BT_HDR *)transac)->event);
    542     */
    543 
    544     if (result == BT_HC_TX_FRAGMENT)
    545     {
    546         GKI_send_msg (BTU_TASK, BTU_HCI_RCV_MBOX, transac);
    547     }
    548     else
    549     {
    550         GKI_freebuf(transac);
    551     }
    552 
    553     return BT_HC_STATUS_SUCCESS;
    554 }
    555 
    556 /*****************************************************************************
    557 **   The libbt-hci Callback Functions Table
    558 *****************************************************************************/
    559 static const bt_hc_callbacks_t hc_callbacks = {
    560     sizeof(bt_hc_callbacks_t),
    561     preload_cb,
    562     postload_cb,
    563     lpm_cb,
    564     hostwake_ind,
    565     alloc,
    566     dealloc,
    567     data_ind,
    568     tx_result
    569 };
    570 
    571