Home | History | Annotate | Download | only in btu
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2000-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 #define LOG_TAG "bt_task"
     20 
     21 #include <assert.h>
     22 
     23 #include "bt_target.h"
     24 #include <pthread.h>
     25 #include <string.h>
     26 #include "dyn_mem.h"
     27 
     28 #include "osi/include/alarm.h"
     29 #include "device/include/controller.h"
     30 #include "osi/include/fixed_queue.h"
     31 #include "osi/include/hash_map.h"
     32 #include "btu.h"
     33 #include "btm_int.h"
     34 #include "osi/include/hash_functions.h"
     35 #include "sdpint.h"
     36 #include "osi/include/thread.h"
     37 #include "l2c_int.h"
     38 #include "osi/include/log.h"
     39 
     40 #if (BLE_INCLUDED == TRUE)
     41 #include "gatt_api.h"
     42 #include "gatt_int.h"
     43 #if SMP_INCLUDED == TRUE
     44 #include "smp_int.h"
     45 #endif
     46 #endif
     47 
     48 extern fixed_queue_t *btif_msg_queue;
     49 
     50 // Communication queue from bta thread to bt_workqueue.
     51 fixed_queue_t *btu_bta_msg_queue;
     52 
     53 // Communication queue from hci thread to bt_workqueue.
     54 extern fixed_queue_t *btu_hci_msg_queue;
     55 
     56 // General timer queue.
     57 fixed_queue_t *btu_general_alarm_queue;
     58 hash_map_t *btu_general_alarm_hash_map;
     59 pthread_mutex_t btu_general_alarm_lock;
     60 static const size_t BTU_GENERAL_ALARM_HASH_MAP_SIZE = 17;
     61 
     62 // Oneshot timer queue.
     63 fixed_queue_t *btu_oneshot_alarm_queue;
     64 hash_map_t *btu_oneshot_alarm_hash_map;
     65 pthread_mutex_t btu_oneshot_alarm_lock;
     66 static const size_t BTU_ONESHOT_ALARM_HASH_MAP_SIZE = 17;
     67 
     68 // l2cap timer queue.
     69 fixed_queue_t *btu_l2cap_alarm_queue;
     70 hash_map_t *btu_l2cap_alarm_hash_map;
     71 pthread_mutex_t btu_l2cap_alarm_lock;
     72 static const size_t BTU_L2CAP_ALARM_HASH_MAP_SIZE = 17;
     73 
     74 thread_t *bt_workqueue_thread;
     75 static const char *BT_WORKQUEUE_NAME = "bt_workqueue";
     76 
     77 extern void PLATFORM_DisableHciTransport(UINT8 bDisable);
     78 /*****************************************************************************
     79 **                          V A R I A B L E S                                *
     80 ******************************************************************************/
     81 // TODO(cmanton) Move this out of this file
     82 const BD_ADDR   BT_BD_ANY = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
     83 
     84 void btu_task_start_up(void *context);
     85 void btu_task_shut_down(void *context);
     86 
     87 /*****************************************************************************
     88 **
     89 ** Function         btu_init_core
     90 **
     91 ** Description      Initialize control block memory for each core component.
     92 **
     93 **
     94 ** Returns          void
     95 **
     96 ******************************************************************************/
     97 void btu_init_core(void)
     98 {
     99     /* Initialize the mandatory core stack components */
    100     btm_init();
    101 
    102     l2c_init();
    103 
    104     sdp_init();
    105 
    106 #if BLE_INCLUDED == TRUE
    107     gatt_init();
    108 #if (defined(SMP_INCLUDED) && SMP_INCLUDED == TRUE)
    109     SMP_Init();
    110 #endif
    111     btm_ble_init();
    112 #endif
    113 }
    114 
    115 /*****************************************************************************
    116 **
    117 ** Function         btu_free_core
    118 **
    119 ** Description      Releases control block memory for each core component.
    120 **
    121 **
    122 ** Returns          void
    123 **
    124 ******************************************************************************/
    125 void btu_free_core(void)
    126 {
    127       /* Free the mandatory core stack components */
    128       l2c_free();
    129 
    130 #if BLE_INCLUDED == TRUE
    131       gatt_free();
    132 #endif
    133 }
    134 
    135 /*****************************************************************************
    136 **
    137 ** Function         BTU_StartUp
    138 **
    139 ** Description      Initializes the BTU control block.
    140 **
    141 **                  NOTE: Must be called before creating any tasks
    142 **                      (RPC, BTU, HCIT, APPL, etc.)
    143 **
    144 ** Returns          void
    145 **
    146 ******************************************************************************/
    147 void BTU_StartUp(void)
    148 {
    149     memset (&btu_cb, 0, sizeof (tBTU_CB));
    150     btu_cb.trace_level = HCI_INITIAL_TRACE_LEVEL;
    151 
    152     btu_bta_msg_queue = fixed_queue_new(SIZE_MAX);
    153     if (btu_bta_msg_queue == NULL)
    154         goto error_exit;
    155 
    156     btu_general_alarm_hash_map = hash_map_new(BTU_GENERAL_ALARM_HASH_MAP_SIZE,
    157             hash_function_pointer, NULL, (data_free_fn)alarm_free, NULL);
    158     if (btu_general_alarm_hash_map == NULL)
    159         goto error_exit;
    160 
    161     if (pthread_mutex_init(&btu_general_alarm_lock, NULL))
    162         goto error_exit;
    163 
    164     btu_general_alarm_queue = fixed_queue_new(SIZE_MAX);
    165     if (btu_general_alarm_queue == NULL)
    166         goto error_exit;
    167 
    168     btu_oneshot_alarm_hash_map = hash_map_new(BTU_ONESHOT_ALARM_HASH_MAP_SIZE,
    169             hash_function_pointer, NULL, (data_free_fn)alarm_free, NULL);
    170     if (btu_oneshot_alarm_hash_map == NULL)
    171         goto error_exit;
    172 
    173     if (pthread_mutex_init(&btu_oneshot_alarm_lock, NULL))
    174         goto error_exit;
    175 
    176     btu_oneshot_alarm_queue = fixed_queue_new(SIZE_MAX);
    177     if (btu_oneshot_alarm_queue == NULL)
    178         goto error_exit;
    179 
    180     btu_l2cap_alarm_hash_map = hash_map_new(BTU_L2CAP_ALARM_HASH_MAP_SIZE,
    181             hash_function_pointer, NULL, (data_free_fn)alarm_free, NULL);
    182     if (btu_l2cap_alarm_hash_map == NULL)
    183         goto error_exit;
    184 
    185     if (pthread_mutex_init(&btu_l2cap_alarm_lock, NULL))
    186         goto error_exit;
    187 
    188     btu_l2cap_alarm_queue = fixed_queue_new(SIZE_MAX);
    189     if (btu_l2cap_alarm_queue == NULL)
    190          goto error_exit;
    191 
    192     bt_workqueue_thread = thread_new(BT_WORKQUEUE_NAME);
    193     if (bt_workqueue_thread == NULL)
    194         goto error_exit;
    195 
    196     // Continue startup on bt workqueue thread.
    197     thread_post(bt_workqueue_thread, btu_task_start_up, NULL);
    198     return;
    199 
    200   error_exit:;
    201     LOG_ERROR("%s Unable to allocate resources for bt_workqueue", __func__);
    202     BTU_ShutDown();
    203 }
    204 
    205 void BTU_ShutDown(void) {
    206   btu_task_shut_down(NULL);
    207 
    208   fixed_queue_free(btu_bta_msg_queue, NULL);
    209 
    210   hash_map_free(btu_general_alarm_hash_map);
    211   pthread_mutex_destroy(&btu_general_alarm_lock);
    212   fixed_queue_free(btu_general_alarm_queue, NULL);
    213 
    214   hash_map_free(btu_oneshot_alarm_hash_map);
    215   pthread_mutex_destroy(&btu_oneshot_alarm_lock);
    216   fixed_queue_free(btu_oneshot_alarm_queue, NULL);
    217 
    218   hash_map_free(btu_l2cap_alarm_hash_map);
    219   pthread_mutex_destroy(&btu_l2cap_alarm_lock);
    220   fixed_queue_free(btu_l2cap_alarm_queue, NULL);
    221 
    222   thread_free(bt_workqueue_thread);
    223 
    224   btu_bta_msg_queue = NULL;
    225 
    226   btu_general_alarm_hash_map = NULL;
    227   btu_general_alarm_queue = NULL;
    228 
    229   btu_oneshot_alarm_hash_map = NULL;
    230   btu_oneshot_alarm_queue = NULL;
    231 
    232   btu_l2cap_alarm_hash_map = NULL;
    233   btu_l2cap_alarm_queue = NULL;
    234 
    235   bt_workqueue_thread = NULL;
    236 }
    237 
    238 /*****************************************************************************
    239 **
    240 ** Function         BTU_BleAclPktSize
    241 **
    242 ** Description      export the BLE ACL packet size.
    243 **
    244 ** Returns          UINT16
    245 **
    246 ******************************************************************************/
    247 UINT16 BTU_BleAclPktSize(void)
    248 {
    249 #if BLE_INCLUDED == TRUE
    250     return controller_get_interface()->get_acl_packet_size_ble();
    251 #else
    252     return 0;
    253 #endif
    254 }
    255 
    256 /*******************************************************************************
    257 **
    258 ** Function         btu_uipc_rx_cback
    259 **
    260 ** Description
    261 **
    262 **
    263 ** Returns          void
    264 **
    265 *******************************************************************************/
    266 void btu_uipc_rx_cback(BT_HDR *p_msg) {
    267   assert(p_msg != NULL);
    268   BT_TRACE(TRACE_LAYER_BTM, TRACE_TYPE_DEBUG, "btu_uipc_rx_cback event 0x%x,"
    269       " len %d, offset %d", p_msg->event, p_msg->len, p_msg->offset);
    270   fixed_queue_enqueue(btu_hci_msg_queue, p_msg);
    271 }
    272