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