1 //
2 // Copyright (C) 2019 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 #include "host/commands/run_cvd/launch/launch.h"
17 
18 #include <string>
19 #include <unordered_set>
20 #include <utility>
21 #include <vector>
22 
23 #include <fruit/fruit.h>
24 
25 #include "common/libs/utils/result.h"
26 #include "host/commands/run_cvd/launch/log_tee_creator.h"
27 #include "host/libs/config/command_source.h"
28 #include "host/libs/config/cuttlefish_config.h"
29 #include "host/libs/config/known_paths.h"
30 
31 namespace cuttlefish {
32 namespace {
33 
34 class RootCanal : public CommandSource {
35  public:
INJECT(RootCanal (const CuttlefishConfig & config,const CuttlefishConfig::InstanceSpecific & instance,LogTeeCreator & log_tee))36   INJECT(RootCanal(const CuttlefishConfig& config,
37                    const CuttlefishConfig::InstanceSpecific& instance,
38                    LogTeeCreator& log_tee))
39       : config_(config), instance_(instance), log_tee_(log_tee) {}
40 
41   // CommandSource
Commands()42   Result<std::vector<MonitorCommand>> Commands() override {
43     // Create the root-canal command with the process_restarter
44     // as runner to restart root-canal when it crashes.
45     Command rootcanal(ProcessRestarterBinary());
46     rootcanal.AddParameter("-when_killed");
47     rootcanal.AddParameter("-when_dumped");
48     rootcanal.AddParameter("-when_exited_with_failure");
49     rootcanal.AddParameter("--");
50     rootcanal.AddParameter(RootCanalBinary());
51 
52     // Port configuration.
53     rootcanal.AddParameter("--test_port=", config_.rootcanal_test_port());
54     rootcanal.AddParameter("--hci_port=", config_.rootcanal_hci_port());
55     rootcanal.AddParameter("--link_port=", config_.rootcanal_link_port());
56     rootcanal.AddParameter("--link_ble_port=",
57                            config_.rootcanal_link_ble_port());
58 
59     // Add parameters from passthrough option --rootcanal-args
60     for (auto const& arg : config_.rootcanal_args()) {
61       rootcanal.AddParameter(arg);
62     }
63 
64     // Add command for forwarding the HCI port to a vsock server.
65     Command hci_vsock_proxy(SocketVsockProxyBinary());
66     hci_vsock_proxy.AddParameter("--server_type=vsock");
67     hci_vsock_proxy.AddParameter("--server_vsock_id=",
68                                  instance_.vsock_guest_cid());
69     hci_vsock_proxy.AddParameter("--server_vsock_port=",
70                                  config_.rootcanal_hci_port());
71     hci_vsock_proxy.AddParameter("--client_type=tcp");
72     hci_vsock_proxy.AddParameter("--client_tcp_host=127.0.0.1");
73     hci_vsock_proxy.AddParameter("--client_tcp_port=",
74                                  config_.rootcanal_hci_port());
75 
76     // Add command for forwarding the test port to a vsock server.
77     Command test_vsock_proxy(SocketVsockProxyBinary());
78     test_vsock_proxy.AddParameter("--server_type=vsock");
79     test_vsock_proxy.AddParameter("--server_vsock_id=",
80                                   instance_.vsock_guest_cid());
81     test_vsock_proxy.AddParameter("--server_vsock_port=",
82                                   config_.rootcanal_test_port());
83     test_vsock_proxy.AddParameter("--client_type=tcp");
84     test_vsock_proxy.AddParameter("--client_tcp_host=127.0.0.1");
85     test_vsock_proxy.AddParameter("--client_tcp_port=",
86                                   config_.rootcanal_test_port());
87 
88     std::vector<MonitorCommand> commands;
89     commands.emplace_back(
90         CF_EXPECT(log_tee_.CreateLogTee(rootcanal, "rootcanal")));
91     commands.emplace_back(std::move(rootcanal));
92     commands.emplace_back(std::move(hci_vsock_proxy));
93     commands.emplace_back(std::move(test_vsock_proxy));
94     return commands;
95   }
96 
97   // SetupFeature
Name() const98   std::string Name() const override { return "RootCanal"; }
Enabled() const99   bool Enabled() const override {
100     return config_.enable_host_bluetooth_connector() && instance_.start_rootcanal();
101   }
102 
103  private:
Dependencies() const104   std::unordered_set<SetupFeature*> Dependencies() const override { return {}; }
ResultSetup()105   Result<void> ResultSetup() override { return {}; }
106 
107   const CuttlefishConfig& config_;
108   const CuttlefishConfig::InstanceSpecific& instance_;
109   LogTeeCreator& log_tee_;
110 };
111 
112 }  // namespace
113 
114 fruit::Component<
115     fruit::Required<const CuttlefishConfig,
116                     const CuttlefishConfig::InstanceSpecific, LogTeeCreator>>
RootCanalComponent()117 RootCanalComponent() {
118   return fruit::createComponent()
119       .addMultibinding<CommandSource, RootCanal>()
120       .addMultibinding<SetupFeature, RootCanal>();
121 }
122 
123 }  // namespace cuttlefish
124