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 <pthread.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <string.h> 25 26 #include <base/bind.h> 27 #include <base/logging.h> 28 #include <base/run_loop.h> 29 #include <base/threading/thread.h> 30 31 #include "bta/sys/bta_sys.h" 32 #include "btcore/include/module.h" 33 #include "bte.h" 34 #include "btif/include/btif_common.h" 35 #include "osi/include/osi.h" 36 #include "osi/include/thread.h" 37 #include "stack/btm/btm_int.h" 38 #include "stack/include/btu.h" 39 #include "stack/l2cap/l2c_int.h" 40 41 static const int THREAD_RT_PRIORITY = 1; 42 43 /* Define BTU storage area */ 44 uint8_t btu_trace_level = HCI_INITIAL_TRACE_LEVEL; 45 46 extern thread_t* bt_workqueue_thread; 47 48 static base::MessageLoop* message_loop_ = NULL; 49 static base::RunLoop* run_loop_ = NULL; 50 static thread_t* message_loop_thread_; 51 52 void btu_hci_msg_process(BT_HDR* p_msg) { 53 /* Determine the input message type. */ 54 switch (p_msg->event & BT_EVT_MASK) { 55 case BT_EVT_TO_BTU_HCI_ACL: 56 /* All Acl Data goes to L2CAP */ 57 l2c_rcv_acl_data(p_msg); 58 break; 59 60 case BT_EVT_TO_BTU_L2C_SEG_XMIT: 61 /* L2CAP segment transmit complete */ 62 l2c_link_segments_xmitted(p_msg); 63 break; 64 65 case BT_EVT_TO_BTU_HCI_SCO: 66 #if (BTM_SCO_INCLUDED == TRUE) 67 btm_route_sco_data(p_msg); 68 break; 69 #endif 70 71 case BT_EVT_TO_BTU_HCI_EVT: 72 btu_hcif_process_event((uint8_t)(p_msg->event & BT_SUB_EVT_MASK), p_msg); 73 osi_free(p_msg); 74 break; 75 76 case BT_EVT_TO_BTU_HCI_CMD: 77 btu_hcif_send_cmd((uint8_t)(p_msg->event & BT_SUB_EVT_MASK), p_msg); 78 break; 79 80 default: 81 osi_free(p_msg); 82 break; 83 } 84 } 85 86 base::MessageLoop* get_message_loop() { return message_loop_; } 87 88 void btu_message_loop_run(UNUSED_ATTR void* context) { 89 message_loop_ = new base::MessageLoop(); 90 run_loop_ = new base::RunLoop(); 91 92 // Inform the bt jni thread initialization is ok. 93 message_loop_->task_runner()->PostTask( 94 FROM_HERE, base::Bind(base::IgnoreResult(&btif_transfer_context), 95 btif_init_ok, 0, nullptr, 0, nullptr)); 96 97 run_loop_->Run(); 98 99 delete message_loop_; 100 message_loop_ = NULL; 101 102 delete run_loop_; 103 run_loop_ = NULL; 104 } 105 106 void btu_task_start_up(UNUSED_ATTR void* context) { 107 LOG(INFO) << "Bluetooth chip preload is complete"; 108 109 /* Initialize the mandatory core stack control blocks 110 (BTU, BTM, L2CAP, and SDP) 111 */ 112 btu_init_core(); 113 114 /* Initialize any optional stack components */ 115 BTE_InitStack(); 116 117 bta_sys_init(); 118 119 /* Initialise platform trace levels at this point as BTE_InitStack() and 120 * bta_sys_init() 121 * reset the control blocks and preset the trace level with 122 * XXX_INITIAL_TRACE_LEVEL 123 */ 124 module_init(get_module(BTE_LOGMSG_MODULE)); 125 126 message_loop_thread_ = thread_new("btu message loop"); 127 if (!message_loop_thread_) { 128 LOG(FATAL) << __func__ << " unable to create btu message loop thread."; 129 } 130 131 thread_set_rt_priority(message_loop_thread_, THREAD_RT_PRIORITY); 132 thread_post(message_loop_thread_, btu_message_loop_run, nullptr); 133 134 } 135 136 void btu_task_shut_down(UNUSED_ATTR void* context) { 137 // Shutdown message loop on task completed 138 if (run_loop_ && message_loop_) { 139 message_loop_->task_runner()->PostTask(FROM_HERE, run_loop_->QuitClosure()); 140 } 141 142 module_clean_up(get_module(BTE_LOGMSG_MODULE)); 143 144 bta_sys_free(); 145 btu_free_core(); 146 } 147