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