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