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