1 //
2 // Copyright 2017 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 #pragma once
18 
19 #include <chrono>
20 #include <functional>
21 #include <future>
22 #include <memory>
23 #include <string>
24 #include <vector>
25 
26 #include "model/controller/controller_properties.h"
27 #include "model/setup/async_manager.h"
28 #include "model/setup/test_channel_transport.h"
29 #include "model/setup/test_command_handler.h"
30 #include "model/setup/test_model.h"
31 #include "net/async_data_channel_server.h"
32 
33 namespace android::net {
34 class AsyncDataChannel;
35 class AsyncDataChannelConnector;
36 }  // namespace android::net
37 
38 namespace rootcanal {
39 
40 using android::net::AsyncDataChannel;
41 using android::net::AsyncDataChannelConnector;
42 using android::net::AsyncDataChannelServer;
43 using android::net::ConnectCallback;
44 
45 using rootcanal::AsyncManager;
46 using rootcanal::Device;
47 using rootcanal::Phy;
48 
49 class TestEnvironment {
50 public:
51   TestEnvironment(
52           std::function<std::shared_ptr<AsyncDataChannelServer>(AsyncManager*, int)> open_server,
53           std::function<std::shared_ptr<AsyncDataChannelConnector>(AsyncManager*)> open_connector,
54           int test_port, int hci_port, int link_port, int link_ble_port,
55           std::string const& config_str, bool enable_hci_sniffer = false,
56           bool enable_baseband_sniffer = false, bool enable_pcap_filter = false,
57           bool disable_address_reuse = false);
58 
59   void initialize(std::promise<void> barrier);
60   void close();
61 
62 private:
63   rootcanal::AsyncManager async_manager_;
64   rootcanal::TestChannelTransport test_channel_transport_;
65   std::shared_ptr<AsyncDataChannelServer> test_socket_server_;
66   std::vector<std::shared_ptr<AsyncDataChannelServer>> hci_socket_servers_;
67   std::shared_ptr<AsyncDataChannelServer> link_socket_server_;
68   std::shared_ptr<AsyncDataChannelServer> link_ble_socket_server_;
69   std::shared_ptr<AsyncDataChannelConnector> connector_;
70   bool enable_hci_sniffer_;
71   bool enable_baseband_sniffer_;
72   bool enable_pcap_filter_;
73   bool test_channel_open_{false};
74   std::promise<void> barrier_;
75   rootcanal::AsyncUserId socket_user_id_{};
76 
77   void SetUpTestChannel();
78   void SetUpHciServer(
79           std::function<std::shared_ptr<AsyncDataChannelServer>(AsyncManager*, int)> open_server,
80           int tcp_port, rootcanal::ControllerProperties properties);
81   void SetUpLinkLayerServer();
82   void SetUpLinkBleLayerServer();
83 
84   std::shared_ptr<Device> ConnectToRemoteServer(const std::string& server, int port,
85                                                 Phy::Type phy_type);
86 
87   rootcanal::TestModel test_model_{
88           [this]() { return async_manager_.GetNextUserId(); },
89           [this](rootcanal::AsyncUserId user_id, std::chrono::milliseconds delay,
90                  const rootcanal::TaskCallback& task) {
91             return async_manager_.ExecAsync(user_id, delay, task);
92           },
93 
94           [this](rootcanal::AsyncUserId user_id, std::chrono::milliseconds delay,
95                  std::chrono::milliseconds period, const rootcanal::TaskCallback& task) {
96             return async_manager_.ExecAsyncPeriodically(user_id, delay, period, task);
97           },
98 
99           [this](rootcanal::AsyncUserId user) { async_manager_.CancelAsyncTasksFromUser(user); },
100 
101           [this](rootcanal::AsyncTaskId task) { async_manager_.CancelAsyncTask(task); },
102 
103           [this](const std::string& server, int port, Phy::Type phy_type) {
104             return ConnectToRemoteServer(server, port, phy_type);
105           }};
106 
107   rootcanal::TestCommandHandler test_channel_{test_model_};
108 };
109 
110 }  // namespace rootcanal
111