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