1 /*
2 * Copyright 2022 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 "hci/hci_layer_fake.h"
18
19 #include <bluetooth/log.h>
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22
23 #include <algorithm>
24 #include <chrono>
25
26 namespace bluetooth {
27 namespace hci {
28
29 using common::BidiQueue;
30 using common::BidiQueueEnd;
31 using packet::kLittleEndian;
32 using packet::PacketView;
33 using packet::RawBuilder;
34
GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet)35 PacketView<packet::kLittleEndian> GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet) {
36 auto bytes = std::make_shared<std::vector<uint8_t>>();
37 BitInserter i(*bytes);
38 bytes->reserve(packet->size());
39 packet->Serialize(i);
40 return packet::PacketView<packet::kLittleEndian>(bytes);
41 }
42
NextPayload(uint16_t handle)43 std::unique_ptr<BasePacketBuilder> NextPayload(uint16_t handle) {
44 static uint32_t packet_number = 1;
45 auto payload = std::make_unique<RawBuilder>();
46 payload->AddOctets2(6); // L2CAP PDU size
47 payload->AddOctets2(2); // L2CAP CID
48 payload->AddOctets2(handle);
49 payload->AddOctets4(packet_number++);
50 return std::move(payload);
51 }
52
NextAclPacket(uint16_t handle)53 static std::unique_ptr<AclBuilder> NextAclPacket(uint16_t handle) {
54 PacketBoundaryFlag packet_boundary_flag = PacketBoundaryFlag::FIRST_AUTOMATICALLY_FLUSHABLE;
55 BroadcastFlag broadcast_flag = BroadcastFlag::POINT_TO_POINT;
56 return AclBuilder::Create(handle, packet_boundary_flag, broadcast_flag, NextPayload(handle));
57 }
58
EnqueueCommand(std::unique_ptr<CommandBuilder> command,common::ContextualOnceCallback<void (CommandStatusView)> on_status)59 void HciLayerFake::EnqueueCommand(
60 std::unique_ptr<CommandBuilder> command,
61 common::ContextualOnceCallback<void(CommandStatusView)> on_status) {
62 std::lock_guard<std::mutex> lock(mutex_);
63
64 command_queue_.push(std::move(command));
65 command_status_callbacks.push_back(std::move(on_status));
66
67 if (command_queue_.size() == 1) {
68 // since GetCommand may replace this promise, we have to do this inside the lock
69 command_promise_.set_value();
70 }
71 }
72
EnqueueCommand(std::unique_ptr<CommandBuilder> command,common::ContextualOnceCallback<void (CommandCompleteView)> on_complete)73 void HciLayerFake::EnqueueCommand(
74 std::unique_ptr<CommandBuilder> command,
75 common::ContextualOnceCallback<void(CommandCompleteView)> on_complete) {
76 std::lock_guard<std::mutex> lock(mutex_);
77
78 command_queue_.push(std::move(command));
79 command_complete_callbacks.push_back(std::move(on_complete));
80
81 if (command_queue_.size() == 1) {
82 // since GetCommand may replace this promise, we have to do this inside the lock
83 command_promise_.set_value();
84 }
85 }
86
GetCommand()87 CommandView HciLayerFake::GetCommand() {
88 EXPECT_EQ(command_future_.wait_for(std::chrono::milliseconds(1000)), std::future_status::ready);
89
90 std::lock_guard<std::mutex> lock(mutex_);
91
92 if (command_queue_.empty()) {
93 log::error("Command queue is empty");
94 return empty_command_view_;
95 }
96
97 auto last = std::move(command_queue_.front());
98 command_queue_.pop();
99
100 if (command_queue_.empty()) {
101 command_promise_ = {};
102 command_future_ = command_promise_.get_future();
103 }
104
105 CommandView command_packet_view = CommandView::Create(GetPacketView(std::move(last)));
106 log::assert_that(command_packet_view.IsValid(), "Got invalid command");
107 return command_packet_view;
108 }
109
GetCommand(OpCode op_code)110 CommandView HciLayerFake::GetCommand(OpCode op_code) {
111 auto next_command = GetCommand();
112 while (next_command.GetOpCode() != op_code) {
113 next_command = GetCommand();
114 }
115 return next_command;
116 }
117
AssertNoQueuedCommand()118 void HciLayerFake::AssertNoQueuedCommand() {
119 EXPECT_TRUE(command_queue_.empty());
120 }
121
RegisterEventHandler(EventCode event_code,common::ContextualCallback<void (EventView)> event_handler)122 void HciLayerFake::RegisterEventHandler(
123 EventCode event_code, common::ContextualCallback<void(EventView)> event_handler) {
124 registered_events_[event_code] = event_handler;
125 }
126
UnregisterEventHandler(EventCode event_code)127 void HciLayerFake::UnregisterEventHandler(EventCode event_code) {
128 registered_events_.erase(event_code);
129 }
130
RegisterLeEventHandler(SubeventCode subevent_code,common::ContextualCallback<void (LeMetaEventView)> event_handler)131 void HciLayerFake::RegisterLeEventHandler(
132 SubeventCode subevent_code, common::ContextualCallback<void(LeMetaEventView)> event_handler) {
133 registered_le_events_[subevent_code] = event_handler;
134 }
135
UnregisterLeEventHandler(SubeventCode subevent_code)136 void HciLayerFake::UnregisterLeEventHandler(SubeventCode subevent_code) {
137 registered_le_events_.erase(subevent_code);
138 }
139
RegisterVendorSpecificEventHandler(VseSubeventCode subevent_code,common::ContextualCallback<void (VendorSpecificEventView)> event_handler)140 void HciLayerFake::RegisterVendorSpecificEventHandler(
141 VseSubeventCode subevent_code,
142 common::ContextualCallback<void(VendorSpecificEventView)> event_handler) {
143 registered_vs_events_[subevent_code] = event_handler;
144 }
145
UnregisterVendorSpecificEventHandler(VseSubeventCode subevent_code)146 void HciLayerFake::UnregisterVendorSpecificEventHandler(VseSubeventCode subevent_code) {
147 registered_vs_events_.erase(subevent_code);
148 }
149
IncomingEvent(std::unique_ptr<EventBuilder> event_builder)150 void HciLayerFake::IncomingEvent(std::unique_ptr<EventBuilder> event_builder) {
151 auto packet = GetPacketView(std::move(event_builder));
152 EventView event = EventView::Create(packet);
153 ASSERT_TRUE(event.IsValid());
154 EventCode event_code = event.GetEventCode();
155 if (event_code == EventCode::COMMAND_COMPLETE) {
156 CommandCompleteCallback(event);
157 } else if (event_code == EventCode::COMMAND_STATUS) {
158 CommandStatusCallback(event);
159 } else {
160 ASSERT_NE(registered_events_.find(event_code), registered_events_.end()) << EventCodeText(event_code);
161 registered_events_[event_code](event);
162 }
163 }
164
IncomingLeMetaEvent(std::unique_ptr<LeMetaEventBuilder> event_builder)165 void HciLayerFake::IncomingLeMetaEvent(std::unique_ptr<LeMetaEventBuilder> event_builder) {
166 auto packet = GetPacketView(std::move(event_builder));
167 EventView event = EventView::Create(packet);
168 LeMetaEventView meta_event_view = LeMetaEventView::Create(event);
169 ASSERT_TRUE(meta_event_view.IsValid());
170 SubeventCode subevent_code = meta_event_view.GetSubeventCode();
171 ASSERT_TRUE(registered_le_events_.find(subevent_code) != registered_le_events_.end());
172 registered_le_events_[subevent_code](meta_event_view);
173 }
174
CommandCompleteCallback(EventView event)175 void HciLayerFake::CommandCompleteCallback(EventView event) {
176 CommandCompleteView complete_view = CommandCompleteView::Create(event);
177 ASSERT_TRUE(complete_view.IsValid());
178 std::move(command_complete_callbacks.front())(complete_view);
179 command_complete_callbacks.pop_front();
180 }
181
CommandStatusCallback(EventView event)182 void HciLayerFake::CommandStatusCallback(EventView event) {
183 CommandStatusView status_view = CommandStatusView::Create(event);
184 ASSERT_TRUE(status_view.IsValid());
185 std::move(command_status_callbacks.front())(status_view);
186 command_status_callbacks.pop_front();
187 }
188
InitEmptyCommand()189 void HciLayerFake::InitEmptyCommand() {
190 auto payload = std::make_unique<bluetooth::packet::RawBuilder>();
191 auto command_builder = CommandBuilder::Create(OpCode::NONE, std::move(payload));
192 empty_command_view_ = CommandView::Create(GetPacketView(std::move(command_builder)));
193 ASSERT_TRUE(empty_command_view_.IsValid());
194 }
195
IncomingAclData(uint16_t handle,std::unique_ptr<AclBuilder> acl_builder)196 void HciLayerFake::IncomingAclData(uint16_t handle, std::unique_ptr<AclBuilder> acl_builder) {
197 os::Handler* hci_handler = GetHandler();
198 auto* queue_end = acl_queue_.GetDownEnd();
199 std::promise<void> promise;
200 auto future = promise.get_future();
201 auto packet = GetPacketView(std::move(acl_builder));
202 auto acl_view = AclView::Create(packet);
203 queue_end->RegisterEnqueue(
204 hci_handler,
205 common::Bind(
206 [](decltype(queue_end) queue_end,
207 uint16_t /* handle */,
208 AclView acl2,
209 std::promise<void> promise) {
210 queue_end->UnregisterEnqueue();
211 promise.set_value();
212 return std::make_unique<AclView>(acl2);
213 },
214 queue_end,
215 handle,
216 acl_view,
217 common::Passed(std::move(promise))));
218 auto status = future.wait_for(std::chrono::milliseconds(1000));
219 ASSERT_EQ(status, std::future_status::ready);
220 }
221
IncomingAclData(uint16_t handle)222 void HciLayerFake::IncomingAclData(uint16_t handle) {
223 IncomingAclData(handle, NextAclPacket(handle));
224 }
225
AssertNoOutgoingAclData()226 void HciLayerFake::AssertNoOutgoingAclData() {
227 auto queue_end = acl_queue_.GetDownEnd();
228 EXPECT_EQ(queue_end->TryDequeue(), nullptr);
229 }
230
OutgoingAclData()231 PacketView<kLittleEndian> HciLayerFake::OutgoingAclData() {
232 auto queue_end = acl_queue_.GetDownEnd();
233 std::unique_ptr<AclBuilder> received;
234 do {
235 received = queue_end->TryDequeue();
236 } while (received == nullptr);
237
238 return GetPacketView(std::move(received));
239 }
240
GetAclQueueEnd()241 BidiQueueEnd<AclBuilder, AclView>* HciLayerFake::GetAclQueueEnd() {
242 return acl_queue_.GetUpEnd();
243 }
244
Disconnect(uint16_t handle,ErrorCode reason)245 void HciLayerFake::Disconnect(uint16_t handle, ErrorCode reason) {
246 GetHandler()->Post(
247 common::BindOnce(&HciLayerFake::do_disconnect, common::Unretained(this), handle, reason));
248 }
249
do_disconnect(uint16_t handle,ErrorCode reason)250 void HciLayerFake::do_disconnect(uint16_t handle, ErrorCode reason) {
251 HciLayer::Disconnect(handle, reason);
252 }
253
ListDependencies(ModuleList *) const254 void HciLayerFake::ListDependencies(ModuleList* /* list */) const {}
Start()255 void HciLayerFake::Start() {
256 std::lock_guard<std::mutex> lock(mutex_);
257 InitEmptyCommand();
258 os::Handler* handler = GetHandler();
259 StartWithNoHalDependencies(handler);
260 }
Stop()261 void HciLayerFake::Stop() {}
262
263 } // namespace hci
264 } // namespace bluetooth
265