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