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