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