1 /******************************************************************************
2  *
3  *  Copyright (C) 1999-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_btu_task"
20 
21 #include <assert.h>
22 #include <pthread.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include "bt_target.h"
28 #include "bt_trace.h"
29 #include "bt_types.h"
30 #include "bt_utils.h"
31 #include "btcore/include/module.h"
32 #include "btif_common.h"
33 #include "btm_api.h"
34 #include "btm_int.h"
35 #include "btu.h"
36 #include "gap_int.h"
37 #include "bt_common.h"
38 #include "hcimsgs.h"
39 #include "l2c_int.h"
40 #include "osi/include/alarm.h"
41 #include "osi/include/fixed_queue.h"
42 #include "osi/include/future.h"
43 #include "osi/include/hash_map.h"
44 #include "osi/include/log.h"
45 #include "osi/include/osi.h"
46 #include "osi/include/thread.h"
47 #include "port_api.h"
48 #include "port_ext.h"
49 #include "sdpint.h"
50 
51 #if (defined(BNEP_INCLUDED) && BNEP_INCLUDED == TRUE)
52 #include "bnep_int.h"
53 #endif
54 
55 #if (defined(PAN_INCLUDED) && PAN_INCLUDED == TRUE)
56 #include "pan_int.h"
57 #endif
58 
59 #if (defined(HID_HOST_INCLUDED) && HID_HOST_INCLUDED == TRUE )
60 #include "hidh_int.h"
61 #endif
62 
63 #if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE)
64 #include "avdt_int.h"
65 #else
66 extern void avdt_rcv_sync_info (BT_HDR *p_buf); /* this is for hci_test */
67 #endif
68 
69 #if (defined(MCA_INCLUDED) && MCA_INCLUDED == TRUE)
70 #include "mca_api.h"
71 #include "mca_defs.h"
72 #include "mca_int.h"
73 #endif
74 
75 #include "bta_sys.h"
76 
77 #if (BLE_INCLUDED == TRUE)
78 #include "gatt_int.h"
79 #if (SMP_INCLUDED == TRUE)
80 #include "smp_int.h"
81 #endif
82 #include "btm_ble_int.h"
83 #endif
84 
85 extern void BTE_InitStack(void);
86 
87 /* Define BTU storage area
88 */
89 uint8_t btu_trace_level = HCI_INITIAL_TRACE_LEVEL;
90 
91 // Communication queue between btu_task and bta.
92 extern fixed_queue_t *btu_bta_msg_queue;
93 
94 // Communication queue between btu_task and hci.
95 extern fixed_queue_t *btu_hci_msg_queue;
96 
97 // General timer queue.
98 extern fixed_queue_t *btu_general_alarm_queue;
99 
100 extern fixed_queue_t *event_queue;
101 extern fixed_queue_t *btif_msg_queue;
102 
103 extern thread_t *bt_workqueue_thread;
104 
105 static void btu_hci_msg_process(BT_HDR *p_msg);
106 
btu_hci_msg_ready(fixed_queue_t * queue,UNUSED_ATTR void * context)107 void btu_hci_msg_ready(fixed_queue_t *queue, UNUSED_ATTR void *context) {
108     BT_HDR *p_msg = (BT_HDR *)fixed_queue_dequeue(queue);
109     btu_hci_msg_process(p_msg);
110 }
111 
btu_bta_msg_ready(fixed_queue_t * queue,UNUSED_ATTR void * context)112 void btu_bta_msg_ready(fixed_queue_t *queue, UNUSED_ATTR void *context) {
113     BT_HDR *p_msg = (BT_HDR *)fixed_queue_dequeue(queue);
114     bta_sys_event(p_msg);
115 }
116 
btu_hci_msg_process(BT_HDR * p_msg)117 static void btu_hci_msg_process(BT_HDR *p_msg) {
118     /* Determine the input message type. */
119     switch (p_msg->event & BT_EVT_MASK)
120     {
121         case BTU_POST_TO_TASK_NO_GOOD_HORRIBLE_HACK: // TODO(zachoverflow): remove this
122             ((post_to_task_hack_t *)(&p_msg->data[0]))->callback(p_msg);
123 #if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
124             /* If the host receives events which it doesn't responsd to, */
125             /* it should start an idle timer to enter sleep mode.        */
126             btu_check_bt_sleep ();
127 #endif
128             break;
129         case BT_EVT_TO_BTU_HCI_ACL:
130             /* All Acl Data goes to L2CAP */
131             l2c_rcv_acl_data (p_msg);
132             break;
133 
134         case BT_EVT_TO_BTU_L2C_SEG_XMIT:
135             /* L2CAP segment transmit complete */
136             l2c_link_segments_xmitted (p_msg);
137             break;
138 
139         case BT_EVT_TO_BTU_HCI_SCO:
140 #if BTM_SCO_INCLUDED == TRUE
141             btm_route_sco_data (p_msg);
142             break;
143 #endif
144 
145         case BT_EVT_TO_BTU_HCI_EVT:
146             btu_hcif_process_event ((UINT8)(p_msg->event & BT_SUB_EVT_MASK), p_msg);
147             osi_free(p_msg);
148 
149 #if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
150             /* If host receives events which it doesn't response to, */
151             /* host should start idle timer to enter sleep mode.     */
152             btu_check_bt_sleep ();
153 #endif
154             break;
155 
156         case BT_EVT_TO_BTU_HCI_CMD:
157             btu_hcif_send_cmd ((UINT8)(p_msg->event & BT_SUB_EVT_MASK), p_msg);
158             break;
159 
160         default:
161             osi_free(p_msg);
162             break;
163     }
164 }
165 
btu_task_start_up(UNUSED_ATTR void * context)166 void btu_task_start_up(UNUSED_ATTR void *context) {
167   BT_TRACE(TRACE_LAYER_BTU, TRACE_TYPE_API,
168       "btu_task pending for preload complete event");
169 
170   LOG_INFO(LOG_TAG, "Bluetooth chip preload is complete");
171 
172   BT_TRACE(TRACE_LAYER_BTU, TRACE_TYPE_API,
173       "btu_task received preload complete event");
174 
175   /* Initialize the mandatory core stack control blocks
176      (BTU, BTM, L2CAP, and SDP)
177    */
178   btu_init_core();
179 
180   /* Initialize any optional stack components */
181   BTE_InitStack();
182 
183   bta_sys_init();
184 
185   /* Initialise platform trace levels at this point as BTE_InitStack() and bta_sys_init()
186    * reset the control blocks and preset the trace level with XXX_INITIAL_TRACE_LEVEL
187    */
188 #if ( BT_USE_TRACES==TRUE )
189   module_init(get_module(BTE_LOGMSG_MODULE));
190 #endif
191 
192   // Inform the bt jni thread initialization is ok.
193   btif_transfer_context(btif_init_ok, 0, NULL, 0, NULL);
194 
195   fixed_queue_register_dequeue(btu_bta_msg_queue,
196       thread_get_reactor(bt_workqueue_thread),
197       btu_bta_msg_ready,
198       NULL);
199 
200   fixed_queue_register_dequeue(btu_hci_msg_queue,
201       thread_get_reactor(bt_workqueue_thread),
202       btu_hci_msg_ready,
203       NULL);
204 
205   alarm_register_processing_queue(btu_general_alarm_queue, bt_workqueue_thread);
206 }
207 
btu_task_shut_down(UNUSED_ATTR void * context)208 void btu_task_shut_down(UNUSED_ATTR void *context) {
209   fixed_queue_unregister_dequeue(btu_bta_msg_queue);
210   fixed_queue_unregister_dequeue(btu_hci_msg_queue);
211   alarm_unregister_processing_queue(btu_general_alarm_queue);
212 
213 #if ( BT_USE_TRACES==TRUE )
214   module_clean_up(get_module(BTE_LOGMSG_MODULE));
215 #endif
216 
217   bta_sys_free();
218   btu_free_core();
219 }
220 
221 #if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
222 /*******************************************************************************
223 **
224 ** Function         btu_check_bt_sleep
225 **
226 ** Description      This function is called to check if controller can go to sleep.
227 **
228 ** Returns          void
229 **
230 *******************************************************************************/
btu_check_bt_sleep(void)231 void btu_check_bt_sleep (void)
232 {
233     // TODO(zachoverflow) take pending commands into account?
234     if (l2cb.controller_xmit_window == l2cb.num_lm_acl_bufs)
235     {
236         bte_main_lpm_allow_bt_device_sleep();
237     }
238 }
239 #endif
240