1 /*
2  * Copyright 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "bt_gd_shim"
18 
19 #include "main/shim/stack.h"
20 
21 #include <bluetooth/log.h>
22 #include <fcntl.h>
23 #include <unistd.h>
24 
25 #include <string>
26 
27 #include "common/init_flags.h"
28 #include "common/strings.h"
29 #include "hal/hci_hal.h"
30 #include "hci/acl_manager.h"
31 #include "hci/acl_manager/acl_scheduler.h"
32 #include "hci/controller.h"
33 #include "hci/controller_interface.h"
34 #include "hci/distance_measurement_manager.h"
35 #include "hci/hci_layer.h"
36 #include "hci/le_advertising_manager.h"
37 #include "hci/le_scanning_manager.h"
38 #if TARGET_FLOSS
39 #include "hci/msft.h"
40 #endif
41 #include "hci/remote_name_request.h"
42 #include "main/shim/acl.h"
43 #include "main/shim/acl_legacy_interface.h"
44 #include "main/shim/distance_measurement_manager.h"
45 #include "main/shim/entry.h"
46 #include "main/shim/hci_layer.h"
47 #include "main/shim/le_advertising_manager.h"
48 #include "main/shim/le_scanning_manager.h"
49 #include "metrics/counter_metrics.h"
50 #include "os/log.h"
51 #include "shim/dumpsys.h"
52 #include "storage/storage_module.h"
53 #if TARGET_FLOSS
54 #include "sysprops/sysprops_module.h"
55 #endif
56 
57 namespace bluetooth {
58 namespace shim {
59 
60 using ::bluetooth::common::InitFlags;
61 using ::bluetooth::common::StringFormat;
62 
63 struct Stack::impl {
64   legacy::Acl* acl_ = nullptr;
65 };
66 
Stack()67 Stack::Stack() { pimpl_ = std::make_shared<Stack::impl>(); }
68 
GetInstance()69 Stack* Stack::GetInstance() {
70   static Stack instance;
71   return &instance;
72 }
73 
StartEverything()74 void Stack::StartEverything() {
75   std::lock_guard<std::recursive_mutex> lock(mutex_);
76   log::assert_that(!is_running_, "Gd stack already running");
77   log::info("Starting Gd stack");
78   ModuleList modules;
79 
80   modules.add<metrics::CounterMetrics>();
81   modules.add<hal::HciHal>();
82   modules.add<hci::HciLayer>();
83   modules.add<storage::StorageModule>();
84   modules.add<shim::Dumpsys>();
85 #if TARGET_FLOSS
86   modules.add<sysprops::SyspropsModule>();
87 #endif
88 
89   modules.add<hci::Controller>();
90   modules.add<hci::acl_manager::AclScheduler>();
91   modules.add<hci::AclManager>();
92   modules.add<hci::RemoteNameRequestModule>();
93   modules.add<hci::LeAdvertisingManager>();
94 #if TARGET_FLOSS
95   modules.add<hci::MsftExtensionManager>();
96 #endif
97   modules.add<hci::LeScanningManager>();
98   modules.add<hci::DistanceMeasurementManager>();
99   Start(&modules);
100   is_running_ = true;
101   // Make sure the leaf modules are started
102   log::assert_that(
103       stack_manager_.GetInstance<storage::StorageModule>() != nullptr,
104       "assert failed: stack_manager_.GetInstance<storage::StorageModule>() != "
105       "nullptr");
106   log::assert_that(
107       stack_manager_.GetInstance<shim::Dumpsys>() != nullptr,
108       "assert failed: stack_manager_.GetInstance<shim::Dumpsys>() != nullptr");
109   if (stack_manager_.IsStarted<hci::Controller>()) {
110     pimpl_->acl_ = new legacy::Acl(stack_handler_, legacy::GetAclInterface(),
111                                    GetController()->GetLeFilterAcceptListSize(),
112                                    GetController()->GetLeResolvingListSize());
113   } else {
114     log::error("Unable to create shim ACL layer as Controller has not started");
115   }
116 
117   bluetooth::shim::hci_on_reset_complete();
118   bluetooth::shim::init_advertising_manager();
119   bluetooth::shim::init_scanning_manager();
120   bluetooth::shim::init_distance_measurement_manager();
121 }
122 
StartModuleStack(const ModuleList * modules,const os::Thread * thread)123 void Stack::StartModuleStack(const ModuleList* modules,
124                              const os::Thread* thread) {
125   std::lock_guard<std::recursive_mutex> lock(mutex_);
126   log::assert_that(!is_running_, "Gd stack already running");
127   stack_thread_ = const_cast<os::Thread*>(thread);
128   log::info("Starting Gd stack");
129 
130   stack_manager_.StartUp(const_cast<ModuleList*>(modules), stack_thread_);
131   stack_handler_ = new os::Handler(stack_thread_);
132 
133   num_modules_ = modules->NumModules();
134   is_running_ = true;
135 }
136 
Start(ModuleList * modules)137 void Stack::Start(ModuleList* modules) {
138   log::assert_that(!is_running_, "Gd stack already running");
139   log::info("Starting Gd stack");
140 
141   stack_thread_ =
142       new os::Thread("gd_stack_thread", os::Thread::Priority::REAL_TIME);
143   stack_manager_.StartUp(modules, stack_thread_);
144 
145   stack_handler_ = new os::Handler(stack_thread_);
146 
147   log::info("Successfully toggled Gd stack");
148 }
149 
Stop()150 void Stack::Stop() {
151   std::lock_guard<std::recursive_mutex> lock(mutex_);
152   bluetooth::shim::hci_on_shutting_down();
153 
154   // Make sure gd acl flag is enabled and we started it up
155   if (pimpl_->acl_ != nullptr) {
156     pimpl_->acl_->FinalShutdown();
157     delete pimpl_->acl_;
158     pimpl_->acl_ = nullptr;
159   }
160 
161   log::assert_that(is_running_, "Gd stack not running");
162   is_running_ = false;
163 
164   stack_handler_->Clear();
165 
166   stack_manager_.ShutDown();
167 
168   delete stack_handler_;
169   stack_handler_ = nullptr;
170 
171   stack_thread_->Stop();
172   delete stack_thread_;
173   stack_thread_ = nullptr;
174 
175   log::info("Successfully shut down Gd stack");
176 }
177 
IsRunning()178 bool Stack::IsRunning() {
179   std::lock_guard<std::recursive_mutex> lock(mutex_);
180   return is_running_;
181 }
182 
GetStackManager()183 StackManager* Stack::GetStackManager() {
184   std::lock_guard<std::recursive_mutex> lock(mutex_);
185   log::assert_that(is_running_, "assert failed: is_running_");
186   return &stack_manager_;
187 }
188 
GetStackManager() const189 const StackManager* Stack::GetStackManager() const {
190   std::lock_guard<std::recursive_mutex> lock(mutex_);
191   log::assert_that(is_running_, "assert failed: is_running_");
192   return &stack_manager_;
193 }
194 
GetAcl()195 legacy::Acl* Stack::GetAcl() {
196   std::lock_guard<std::recursive_mutex> lock(mutex_);
197   log::assert_that(is_running_, "assert failed: is_running_");
198   log::assert_that(pimpl_->acl_ != nullptr,
199                    "Acl shim layer has not been created");
200   return pimpl_->acl_;
201 }
202 
GetHandler()203 os::Handler* Stack::GetHandler() {
204   std::lock_guard<std::recursive_mutex> lock(mutex_);
205   log::assert_that(is_running_, "assert failed: is_running_");
206   return stack_handler_;
207 }
208 
IsDumpsysModuleStarted() const209 bool Stack::IsDumpsysModuleStarted() const {
210   std::lock_guard<std::recursive_mutex> lock(mutex_);
211   return GetStackManager()->IsStarted<Dumpsys>();
212 }
213 
LockForDumpsys(std::function<void ()> dumpsys_callback)214 bool Stack::LockForDumpsys(std::function<void()> dumpsys_callback) {
215   std::lock_guard<std::recursive_mutex> lock(mutex_);
216   if (is_running_) {
217     dumpsys_callback();
218   }
219   return is_running_;
220 }
221 
222 }  // namespace shim
223 }  // namespace bluetooth
224