1 /*
2  * Copyright 2024 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 #include <bluetooth/log.h>
18 
19 #include <future>
20 #include <mutex>
21 
22 #include "common/stop_watch.h"
23 #include "common/strings.h"
24 #include "hal/hci_backend.h"
25 #include "hal/hci_hal.h"
26 #include "hal/link_clocker.h"
27 #include "hal/snoop_logger.h"
28 #include "os/mgmt.h"
29 
30 namespace bluetooth::hal {
31 
32 template <class VecType>
GetTimerText(const char * func_name,VecType vec)33 std::string GetTimerText(const char* func_name, VecType vec) {
34   return common::StringFormat(
35           "%s: len %zu, 1st 5 bytes '%s'", func_name, vec.size(),
36           common::ToHexString(vec.begin(), std::min(vec.end(), vec.begin() + 5)).c_str());
37 }
38 
39 class HciCallbacksImpl : public HciBackendCallbacks {
40   class : public HciHalCallbacks {
41   public:
hciEventReceived(HciPacket)42     void hciEventReceived(HciPacket) override {
43       log::warn("Dropping HCI Event, since callback is not set");
44     }
aclDataReceived(HciPacket)45     void aclDataReceived(HciPacket) override {
46       log::warn("Dropping ACL Data, since callback is not set");
47     }
scoDataReceived(HciPacket)48     void scoDataReceived(HciPacket) override {
49       log::warn("Dropping SCO Data, since callback is not set");
50     }
isoDataReceived(HciPacket)51     void isoDataReceived(HciPacket) override {
52       log::warn("Dropping ISO Data, since callback is not set");
53     }
54   } kNullCallbacks;
55 
56 public:
57   std::promise<void>* const init_promise = &init_promise_;
58 
HciCallbacksImpl(SnoopLogger * btsnoop_logger,LinkClocker * link_clocker)59   HciCallbacksImpl(SnoopLogger* btsnoop_logger, LinkClocker* link_clocker)
60       : link_clocker_(link_clocker), btsnoop_logger_(btsnoop_logger) {}
61 
SetCallback(HciHalCallbacks * callback)62   void SetCallback(HciHalCallbacks* callback) {
63     log::assert_that(callback_ == &kNullCallbacks, "callbacks already set");
64     log::assert_that(callback != nullptr, "callback != nullptr");
65     std::lock_guard<std::mutex> lock(mutex_);
66     callback_ = callback;
67   }
68 
ResetCallback()69   void ResetCallback() {
70     std::lock_guard<std::mutex> lock(mutex_);
71     log::info("callbacks have been reset!");
72     callback_ = &kNullCallbacks;
73   }
74 
initializationComplete()75   void initializationComplete() override {
76     common::StopWatch stop_watch(__func__);
77     init_promise_.set_value();
78   }
79 
hciEventReceived(const std::vector<uint8_t> & packet)80   void hciEventReceived(const std::vector<uint8_t>& packet) override {
81     common::StopWatch stop_watch(GetTimerText(__func__, packet));
82     link_clocker_->OnHciEvent(packet);
83     btsnoop_logger_->Capture(packet, SnoopLogger::Direction::INCOMING,
84                              SnoopLogger::PacketType::EVT);
85     {
86       std::lock_guard<std::mutex> lock(mutex_);
87       callback_->hciEventReceived(packet);
88     }
89   }
90 
aclDataReceived(const std::vector<uint8_t> & packet)91   void aclDataReceived(const std::vector<uint8_t>& packet) override {
92     common::StopWatch stop_watch(GetTimerText(__func__, packet));
93     btsnoop_logger_->Capture(packet, SnoopLogger::Direction::INCOMING,
94                              SnoopLogger::PacketType::ACL);
95     {
96       std::lock_guard<std::mutex> lock(mutex_);
97       callback_->aclDataReceived(packet);
98     }
99   }
100 
scoDataReceived(const std::vector<uint8_t> & packet)101   void scoDataReceived(const std::vector<uint8_t>& packet) override {
102     common::StopWatch stop_watch(GetTimerText(__func__, packet));
103     btsnoop_logger_->Capture(packet, SnoopLogger::Direction::INCOMING,
104                              SnoopLogger::PacketType::SCO);
105     {
106       std::lock_guard<std::mutex> lock(mutex_);
107       callback_->scoDataReceived(packet);
108     }
109   }
110 
isoDataReceived(const std::vector<uint8_t> & packet)111   void isoDataReceived(const std::vector<uint8_t>& packet) override {
112     common::StopWatch stop_watch(GetTimerText(__func__, packet));
113     btsnoop_logger_->Capture(packet, SnoopLogger::Direction::INCOMING,
114                              SnoopLogger::PacketType::ISO);
115     {
116       std::lock_guard<std::mutex> lock(mutex_);
117       callback_->isoDataReceived(packet);
118     }
119   }
120 
121 private:
122   std::mutex mutex_;
123   std::promise<void> init_promise_;
124   HciHalCallbacks* callback_ = &kNullCallbacks;
125   LinkClocker* link_clocker_;
126   SnoopLogger* btsnoop_logger_;
127 };
128 
129 class HciHalImpl : public HciHal {
130 public:
registerIncomingPacketCallback(HciHalCallbacks * callback)131   void registerIncomingPacketCallback(HciHalCallbacks* callback) override {
132     callbacks_->SetCallback(callback);
133   }
134 
unregisterIncomingPacketCallback()135   void unregisterIncomingPacketCallback() override { callbacks_->ResetCallback(); }
136 
sendHciCommand(HciPacket packet)137   void sendHciCommand(HciPacket packet) override {
138     btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
139                              SnoopLogger::PacketType::CMD);
140     backend_->sendHciCommand(packet);
141   }
142 
sendAclData(HciPacket packet)143   void sendAclData(HciPacket packet) override {
144     btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
145                              SnoopLogger::PacketType::ACL);
146     backend_->sendAclData(packet);
147   }
148 
sendScoData(HciPacket packet)149   void sendScoData(HciPacket packet) override {
150     btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
151                              SnoopLogger::PacketType::SCO);
152     backend_->sendScoData(packet);
153   }
154 
sendIsoData(HciPacket packet)155   void sendIsoData(HciPacket packet) override {
156     btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
157                              SnoopLogger::PacketType::ISO);
158     backend_->sendIsoData(packet);
159   }
160 
getMsftOpcode()161   uint16_t getMsftOpcode() override {
162     return os::Management::getInstance().getVendorSpecificCode(MGMT_VS_OPCODE_MSFT);
163   }
164 
165 protected:
ListDependencies(ModuleList * list) const166   void ListDependencies(ModuleList* list) const override {
167     list->add<LinkClocker>();
168     list->add<SnoopLogger>();
169   }
170 
Start()171   void Start() override {
172     common::StopWatch stop_watch(__func__);
173     log::assert_that(backend_ == nullptr,
174                      "Start can't be called more than once before Stop is called.");
175 
176     link_clocker_ = GetDependency<LinkClocker>();
177     btsnoop_logger_ = GetDependency<SnoopLogger>();
178 
179     backend_ = HciBackend::CreateAidl();
180     if (!backend_) {
181       backend_ = HciBackend::CreateHidl(GetHandler());
182     }
183 
184     log::assert_that(backend_ != nullptr, "No backend available");
185 
186     callbacks_ = std::make_shared<HciCallbacksImpl>(btsnoop_logger_, link_clocker_);
187 
188     backend_->initialize(callbacks_);
189     callbacks_->init_promise->get_future().wait();
190   }
191 
Stop()192   void Stop() override {
193     backend_.reset();
194     callbacks_.reset();
195     btsnoop_logger_ = nullptr;
196     link_clocker_ = nullptr;
197   }
198 
ToString() const199   std::string ToString() const override { return std::string("HciHal"); }
200 
201 private:
202   std::shared_ptr<HciCallbacksImpl> callbacks_;
203   std::shared_ptr<HciBackend> backend_;
204   SnoopLogger* btsnoop_logger_ = nullptr;
205   LinkClocker* link_clocker_ = nullptr;
206 };
207 
__anonf51f5ffe0202() 208 const ModuleFactory HciHal::Factory = ModuleFactory([]() { return new HciHalImpl(); });
209 
210 }  // namespace bluetooth::hal
211