• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <future>
18 #include <map>
19 
20 #include "common/bind.h"
21 #include "hci/address.h"
22 #include "hci/hci_layer.h"
23 #include "packet/raw_builder.h"
24 
25 namespace bluetooth {
26 namespace hci {
27 
28 packet::PacketView<packet::kLittleEndian> GetPacketView(
29     std::unique_ptr<packet::BasePacketBuilder> packet);
30 
31 std::unique_ptr<BasePacketBuilder> NextPayload(uint16_t handle);
32 
33 class TestHciLayer : public HciLayer {
34  public:
35   void EnqueueCommand(
36       std::unique_ptr<CommandBuilder> command,
37       common::ContextualOnceCallback<void(CommandStatusView)> on_status) override;
38 
39   void EnqueueCommand(
40       std::unique_ptr<CommandBuilder> command,
41       common::ContextualOnceCallback<void(CommandCompleteView)> on_complete) override;
42 
43   CommandView GetCommand();
44 
45   void RegisterEventHandler(EventCode event_code, common::ContextualCallback<void(EventView)> event_handler) override;
46 
47   void UnregisterEventHandler(EventCode event_code) override;
48 
49   void RegisterLeEventHandler(
50       SubeventCode subevent_code, common::ContextualCallback<void(LeMetaEventView)> event_handler) override;
51 
52   void UnregisterLeEventHandler(SubeventCode subevent_code) override;
53 
54   void IncomingEvent(std::unique_ptr<EventBuilder> event_builder);
55 
56   void IncomingLeMetaEvent(std::unique_ptr<LeMetaEventBuilder> event_builder);
57 
58   void CommandCompleteCallback(EventView event);
59 
60   void CommandStatusCallback(EventView event);
61 
62   void IncomingAclData(uint16_t handle);
63 
64   void AssertNoOutgoingAclData();
65 
66   packet::PacketView<packet::kLittleEndian> OutgoingAclData();
67 
68   common::BidiQueueEnd<AclBuilder, AclView>* GetAclQueueEnd() override;
69 
70   void Disconnect(uint16_t handle, ErrorCode reason) override;
71 
72  protected:
73   void ListDependencies(ModuleList* list) const override;
74   void Start() override;
75   void Stop() override;
76 
77  private:
78   void InitEmptyCommand();
79   void do_disconnect(uint16_t handle, ErrorCode reason);
80 
81   // Handler-only state. Mutexes are not needed when accessing these fields.
82   std::list<common::ContextualOnceCallback<void(CommandCompleteView)>> command_complete_callbacks;
83   std::list<common::ContextualOnceCallback<void(CommandStatusView)>> command_status_callbacks;
84   std::map<EventCode, common::ContextualCallback<void(EventView)>> registered_events_;
85   std::map<SubeventCode, common::ContextualCallback<void(LeMetaEventView)>> registered_le_events_;
86 
87   // thread-safe
88   common::BidiQueue<AclView, AclBuilder> acl_queue_{3 /* TODO: Set queue depth */};
89 
90   // Most operations must acquire this mutex before manipulating shared state. The ONLY exception
91   // is blocking on a promise, IF your thread is the only one mutating it. Note that SETTING a
92   // promise REQUIRES a lock, since another thread may replace the promise while you are doing so.
93   mutable std::mutex mutex_{};
94 
95   // Shared state between the test and stack threads
96   std::queue<std::unique_ptr<CommandBuilder>> command_queue_;
97 
98   // We start with Consumed=Set, Command=Unset.
99   // When a command is enqueued, we set Command=set
100   // When a command is popped, we block until Command=Set, then (if the queue is now empty) we
101   // reset Command=Unset and set Consumed=Set. This way we emulate a blocking queue.
102   std::promise<void> command_promise_{};  // Set when at least one command is in the queue
103   std::future<void> command_future_ =
104       command_promise_.get_future();  // GetCommand() blocks until this is fulfilled
105 
106   CommandView empty_command_view_ = CommandView::Create(
107       PacketView<packet::kLittleEndian>(std::make_shared<std::vector<uint8_t>>()));
108 };
109 
110 }  // namespace hci
111 }  // namespace bluetooth