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