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