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 ******************************************************************************/
btu_init_core(void)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 ******************************************************************************/
btu_free_core(void)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 ******************************************************************************/
BTU_StartUp(void)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
BTU_ShutDown(void)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 ******************************************************************************/
BTU_BleAclPktSize(void)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 *******************************************************************************/
btu_uipc_rx_cback(BT_HDR * p_msg)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