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