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
52 extern fixed_queue_t *btif_msg_queue;
53
54 // Communication queue from bta thread to bt_workqueue.
55 fixed_queue_t *btu_bta_msg_queue;
56
57 // Communication queue from hci thread to bt_workqueue.
58 extern fixed_queue_t *btu_hci_msg_queue;
59
60 // General timer queue.
61 fixed_queue_t *btu_general_alarm_queue;
62 hash_map_t *btu_general_alarm_hash_map;
63 pthread_mutex_t btu_general_alarm_lock;
64 static const size_t BTU_GENERAL_ALARM_HASH_MAP_SIZE = 17;
65
66 // Oneshot timer queue.
67 fixed_queue_t *btu_oneshot_alarm_queue;
68 hash_map_t *btu_oneshot_alarm_hash_map;
69 pthread_mutex_t btu_oneshot_alarm_lock;
70 static const size_t BTU_ONESHOT_ALARM_HASH_MAP_SIZE = 17;
71
72 // l2cap timer queue.
73 fixed_queue_t *btu_l2cap_alarm_queue;
74 hash_map_t *btu_l2cap_alarm_hash_map;
75 pthread_mutex_t btu_l2cap_alarm_lock;
76 static const size_t BTU_L2CAP_ALARM_HASH_MAP_SIZE = 17;
77
78 thread_t *bt_workqueue_thread;
79 static const char *BT_WORKQUEUE_NAME = "bt_workqueue";
80
81 extern 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
86 const BD_ADDR BT_BD_ANY = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
87
88 void btu_task_start_up(void *context);
89 void 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 ******************************************************************************/
btu_init_core(void)101 void 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 ******************************************************************************/
btu_free_core(void)129 void 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 ******************************************************************************/
BTU_StartUp(void)151 void 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
BTU_ShutDown(void)211 void 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 ******************************************************************************/
BTU_BleAclPktSize(void)253 UINT16 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 *******************************************************************************/
btu_uipc_rx_cback(BT_HDR * p_msg)272 void 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