Merge "Makes wifi configurable over shared memory" into gce-dev
diff --git a/common/frontend/socket_forward_proxy/Android.bp b/common/frontend/socket_forward_proxy/Android.bp
index c70983e..caad62b 100644
--- a/common/frontend/socket_forward_proxy/Android.bp
+++ b/common/frontend/socket_forward_proxy/Android.bp
@@ -21,6 +21,7 @@
shared_libs: [
"libbase",
"libcuttlefish_fs",
+ "libcuttlefish_strings",
"cuttlefish_auto_resources",
"vsoc_lib",
"liblog",
diff --git a/common/frontend/socket_forward_proxy/main.cpp b/common/frontend/socket_forward_proxy/main.cpp
index ad1ca10..ed4196e 100644
--- a/common/frontend/socket_forward_proxy/main.cpp
+++ b/common/frontend/socket_forward_proxy/main.cpp
@@ -29,6 +29,7 @@
#include <unistd.h>
#include "common/libs/fs/shared_fd.h"
+#include "common/libs/strings/str_split.h"
#include "common/vsoc/lib/socket_forward_region_view.h"
#ifdef CUTTLEFISH_HOST
@@ -39,9 +40,12 @@
using vsoc::socket_forward::SocketForwardRegionView;
#ifdef CUTTLEFISH_HOST
-DEFINE_string(ports, "",
- "Comma-separated list of ports from which to forward TCP "
- "connections.");
+DEFINE_string(guest_ports, "",
+ "Comma-separated list of ports on which to forward TCP "
+ "connections to the guest.");
+DEFINE_string(host_ports, "",
+ "Comma-separated list of ports on which to run TCP servers on "
+ "the host.");
#endif
namespace {
@@ -154,44 +158,53 @@
}
#ifdef CUTTLEFISH_HOST
+struct PortPair {
+ int guest_port;
+ int host_port;
+};
+
+
[[noreturn]] void host_impl(SocketForwardRegionView* shm,
- std::vector<int> ports, std::size_t index) {
+ std::vector<PortPair> ports, std::size_t index) {
// launch a worker for the following port before handling the current port.
// recursion (instead of a loop) removes the need fore any join() or having
// the main thread do no work.
if (index + 1 < ports.size()) {
std::thread(host_impl, shm, ports, index + 1).detach();
}
- auto remote_port = ports[index];
- auto local_port = vsoc::GetPerInstanceDefault(remote_port);
- LOG(INFO) << "starting server on " << local_port
- << " for guest port " << remote_port;
- auto server = cvd::SharedFD::SocketLocalServer(local_port, SOCK_STREAM);
- CHECK(server->IsOpen()) << "Could not start server on port " << local_port;
+ auto guest_port = ports[index].guest_port;
+ auto host_port = ports[index].host_port;
+ LOG(INFO) << "starting server on " << host_port
+ << " for guest port " << guest_port;
+ auto server = cvd::SharedFD::SocketLocalServer(host_port, SOCK_STREAM);
+ CHECK(server->IsOpen()) << "Could not start server on port " << host_port;
while (true) {
auto client_socket = cvd::SharedFD::Accept(*server);
CHECK(client_socket->IsOpen()) << "error creating client socket";
LOG(INFO) << "client socket accepted";
- auto conn = shm->OpenConnection(remote_port);
+ auto conn = shm->OpenConnection(guest_port);
LOG(INFO) << "shm connection opened";
LaunchWorkers(std::move(conn), std::move(client_socket));
}
}
[[noreturn]] void host(SocketForwardRegionView* shm,
- std::vector<int> ports) {
+ std::vector<PortPair> ports) {
CHECK(!ports.empty());
host_impl(shm, ports, 0);
}
-std::vector<int> ParsePortsList(const std::string& ports_flag) {
- std::istringstream ports_stream{ports_flag};
- std::vector<int> ports;
- std::string port_str{};
- while (std::getline(ports_stream, port_str, ',')) {
- ports.push_back(std::stoi(port_str));
+std::vector<PortPair> ParsePortsList(const std::string& guest_ports_str,
+ const std::string& host_ports_str) {
+ std::vector<PortPair> ports{};
+ auto guest_ports = cvd::StrSplit(guest_ports_str, ',');
+ auto host_ports = cvd::StrSplit(host_ports_str, ',');
+ CHECK(guest_ports.size() == host_ports.size());
+ for (std::size_t i = 0; i < guest_ports.size(); ++i) {
+ ports.push_back({std::stoi(guest_ports[i]), std::stoi(host_ports[i])});
}
return ports;
+
}
#else
@@ -250,8 +263,9 @@
auto worker = shm->StartWorker();
#ifdef CUTTLEFISH_HOST
- CHECK(!FLAGS_ports.empty()) << "Must specify --ports flag";
- host(shm, ParsePortsList(FLAGS_ports));
+ CHECK(!FLAGS_guest_ports.empty()) << "Must specify --guest_ports flag";
+ CHECK(!FLAGS_host_ports.empty()) << "Must specify --host_ports flag";
+ host(shm, ParsePortsList(FLAGS_guest_ports, FLAGS_host_ports));
#else
guest(shm);
#endif
diff --git a/common/libs/Android.bp b/common/libs/Android.bp
index b23571f..cb4ec3e 100644
--- a/common/libs/Android.bp
+++ b/common/libs/Android.bp
@@ -17,6 +17,7 @@
"auto_resources",
"fs",
"net",
+ "strings",
"tcp_socket",
"threads",
"time",
diff --git a/common/libs/net/network_interface_manager.cpp b/common/libs/net/network_interface_manager.cpp
index 32d5583..4ee96b7 100644
--- a/common/libs/net/network_interface_manager.cpp
+++ b/common/libs/net/network_interface_manager.cpp
@@ -75,15 +75,22 @@
: nl_client_(std::move(nl_client)) {}
std::unique_ptr<NetworkInterface> NetworkInterfaceManager::Open(
- const std::string& if_name) {
+ const std::string& if_name, const std::string& if_name_alt) {
std::unique_ptr<NetworkInterface> iface;
// NOTE: do not replace this code with an IOCTL call.
// On SELinux enabled Androids, RILD is not permitted to execute an IOCTL
// and this call will fail.
- const int32_t index = if_nametoindex(if_name.c_str());
- if (index < 0) {
- LOG(ERROR) << "Failed to get interface (" << if_name << ") index.";
- return iface;
+ int32_t index = if_nametoindex(if_name.c_str());
+ if (index == 0) {
+ // Try the alternate name. This will be renamed to our preferred name
+ // by the kernel, because we specify IFLA_IFNAME, but open by index.
+ LOG(ERROR) << "Failed to get interface (" << if_name << ") index, "
+ << "trying alternate.";
+ index = if_nametoindex(if_name_alt.c_str());
+ if (index == 0) {
+ LOG(ERROR) << "Failed to get interface (" << if_name_alt << ") index.";
+ return iface;
+ }
}
iface.reset(new NetworkInterface(index));
diff --git a/common/libs/net/network_interface_manager.h b/common/libs/net/network_interface_manager.h
index 3d6ccc5..f28b0ff 100644
--- a/common/libs/net/network_interface_manager.h
+++ b/common/libs/net/network_interface_manager.h
@@ -32,14 +32,15 @@
//
// std::unique_ptr<NetlinkClient> client(NetlinkClient::GetDefault());
// NetworkInterfaceManager manager(client.get());
-// std::unique_ptr<NetworkInterface> iface(manager.Open("eth0"));
+// std::unique_ptr<NetworkInterface> iface(manager.Open("eth0", "em0"));
//
class NetworkInterfaceManager {
public:
// Open existing network interface.
//
// NOTE: this method does not fill in any NetworkInterface details yet.
- std::unique_ptr<NetworkInterface> Open(const std::string& if_name);
+ std::unique_ptr<NetworkInterface> Open(const std::string& if_name,
+ const std::string& if_name_alt);
// Apply changes made to existing network interface.
// This method cannot be used to instantiate new network interfaces.
diff --git a/common/libs/strings/Android.bp b/common/libs/strings/Android.bp
new file mode 100644
index 0000000..273c79e
--- /dev/null
+++ b/common/libs/strings/Android.bp
@@ -0,0 +1,25 @@
+//
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library_shared {
+ name: "libcuttlefish_strings",
+ srcs: [
+ "str_split.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ ],
+ defaults: ["cuttlefish_host_and_guest"],
+}
diff --git a/common/libs/strings/str_split.cpp b/common/libs/strings/str_split.cpp
new file mode 100644
index 0000000..d76acad
--- /dev/null
+++ b/common/libs/strings/str_split.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "common/libs/strings/str_split.h"
+
+#include <vector>
+#include <string>
+#include <sstream>
+
+std::vector<std::string> cvd::StrSplit(const std::string& src, char delimiter) {
+ std::istringstream stream{src};
+ std::vector<std::string> result;
+ for (std::string s; std::getline(stream, s, delimiter); s.clear()) {
+ result.push_back(std::move(s));
+ }
+ return result;
+}
diff --git a/common/libs/strings/str_split.h b/common/libs/strings/str_split.h
new file mode 100644
index 0000000..cd18d15
--- /dev/null
+++ b/common/libs/strings/str_split.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CUTTLEFISH_COMMON_COMMON_LIBS_STRINGS_STR_SPLIT_H_
+#define CUTTLEFISH_COMMON_COMMON_LIBS_STRINGS_STR_SPLIT_H_
+
+#include <vector>
+#include <string>
+
+namespace cvd {
+std::vector<std::string> StrSplit(const std::string& src, char delimiter);
+} // namespace cvd
+
+#endif
diff --git a/guest/commands/vport_trigger/Android.mk b/guest/commands/vport_trigger/Android.mk
new file mode 100644
index 0000000..e994ce9
--- /dev/null
+++ b/guest/commands/vport_trigger/Android.mk
@@ -0,0 +1,26 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := vport_trigger
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := main.cpp
+LOCAL_SHARED_LIBRARIES := libcutils
+LOCAL_MULTILIB := first
+LOCAL_VENDOR_MODULE := true
+
+include $(BUILD_EXECUTABLE)
diff --git a/guest/commands/vport_trigger/main.cpp b/guest/commands/vport_trigger/main.cpp
new file mode 100644
index 0000000..9e4a5f7
--- /dev/null
+++ b/guest/commands/vport_trigger/main.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cutils/properties.h>
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <climits>
+#include <sstream>
+#include <string>
+
+// Taken from android::base, which wasn't available on platform versions
+// earlier than nougat.
+
+static bool ReadFdToString(int fd, std::string* content) {
+ content->clear();
+ char buf[BUFSIZ];
+ ssize_t n;
+ while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], sizeof(buf)))) > 0) {
+ content->append(buf, n);
+ }
+ return (n == 0) ? true : false;
+}
+
+static bool ReadFileToString(const std::string& path, std::string* content,
+ bool follow_symlinks) {
+ int flags = O_RDONLY | O_CLOEXEC | (follow_symlinks ? 0 : O_NOFOLLOW);
+ int fd = TEMP_FAILURE_RETRY(open(path.c_str(), flags));
+ if (fd == -1) {
+ return false;
+ }
+ bool result = ReadFdToString(fd, content);
+ close(fd);
+ return result;
+}
+
+int main(int argc __unused, char *argv[] __unused) {
+ // QEMU seems to create on either bus 0 or bus 1.
+ for (size_t bus = 0; bus < 2U; bus++) {
+ // 'max_ports' is set to '31' upstream.
+ for (size_t port = 0; port < 31U; port++) {
+ std::ostringstream vport;
+ vport << "vport" << bus << "p" << port;
+ std::string sysfs("/sys/class/virtio-ports/" + vport.str() + "/name");
+ struct stat st;
+ if (stat(sysfs.c_str(), &st)) {
+ continue;
+ }
+ std::string content;
+ if (!ReadFileToString(sysfs, &content, true)) {
+ continue;
+ }
+ if (content.empty()) {
+ continue;
+ }
+ content.erase(content.end() - 1);
+ // Leaves 32-11=22 characters for the port name from QEMU.
+ std::string propname("sys.cf.ser." + content);
+ std::string dev("/dev/" + vport.str());
+ property_set(propname.c_str(), dev.c_str());
+ }
+ }
+ return 0;
+}
diff --git a/guest/hals/health/health_service.cpp b/guest/hals/health/health_service.cpp
index ae3d28f..48c2571 100644
--- a/guest/hals/health/health_service.cpp
+++ b/guest/hals/health/health_service.cpp
@@ -28,7 +28,7 @@
int healthd_board_battery_update(
struct android::BatteryProperties* battery_props) {
- battery_props->chargerAcOnline = false;
+ battery_props->chargerAcOnline = true;
battery_props->chargerUsbOnline = true;
battery_props->chargerWirelessOnline = false;
battery_props->maxChargingCurrent = 500000;
diff --git a/guest/hals/ril/vsoc_ril.cpp b/guest/hals/ril/vsoc_ril.cpp
index b60ad8d..0d33dd9 100644
--- a/guest/hals/ril/vsoc_ril.cpp
+++ b/guest/hals/ril/vsoc_ril.cpp
@@ -114,9 +114,10 @@
std::unique_ptr<cvd::NetlinkClient> nl(factory->New(NETLINK_ROUTE));
std::unique_ptr<cvd::NetworkInterfaceManager> nm(
cvd::NetworkInterfaceManager::New(factory));
- std::unique_ptr<cvd::NetworkInterface> ni(nm->Open("rmnet0"));
+ std::unique_ptr<cvd::NetworkInterface> ni(nm->Open("rmnet0", "eth0"));
if (ni) {
+ ni->SetName("rmnet0");
ni->SetAddress(ipaddr);
ni->SetBroadcastAddress(bcaddr);
ni->SetPrefixLength(prefixlen);
@@ -132,7 +133,7 @@
// This call returns true, if operation was successful.
bool TearDownNetworkInterface() {
auto nm(cvd::NetworkInterfaceManager::New(nullptr));
- auto ni(nm->Open("rmnet0"));
+ auto ni(nm->Open("rmnet0", "eth0"));
if (ni) {
ni->SetOperational(false);
diff --git a/host/commands/launch/Android.bp b/host/commands/launch/Android.bp
index c6b2163..f888d79 100644
--- a/host/commands/launch/Android.bp
+++ b/host/commands/launch/Android.bp
@@ -12,6 +12,7 @@
shared_libs: [
"vsoc_lib",
"libcuttlefish_fs",
+ "libcuttlefish_strings",
"cuttlefish_auto_resources",
"libicuuc",
"libbase",
diff --git a/host/commands/launch/main.cc b/host/commands/launch/main.cc
index eacd5da..416ebf1 100644
--- a/host/commands/launch/main.cc
+++ b/host/commands/launch/main.cc
@@ -22,15 +22,19 @@
#include <sys/wait.h>
#include <unistd.h>
+#include <algorithm>
#include <fstream>
#include <iomanip>
#include <memory>
#include <sstream>
+#include <string>
+#include <vector>
#include <gflags/gflags.h>
#include <glog/logging.h>
#include "common/libs/fs/shared_select.h"
+#include "common/libs/strings/str_split.h"
#include "host/commands/launch/pre_launch_initializers.h"
#include "host/libs/config/file_partition.h"
#include "host/libs/config/guest_config.h"
@@ -112,17 +116,12 @@
StringFromEnv("ANDROID_HOST_OUT", StringFromEnv("HOME", ".")) +
"/bin/vnc_server",
"Location of the vnc server binary.");
-DEFINE_int32(vnc_server_port, vsoc::GetPerInstanceDefault(6444),
+DEFINE_int32(vnc_server_port, GetPerInstanceDefault(6444),
"The port on which the vnc server should listen");
DEFINE_string(socket_forward_proxy_binary,
StringFromEnv("ANDROID_HOST_OUT", StringFromEnv("HOME", ".")) +
"/bin/socket_forward_proxy",
"Location of the socket_forward_proxy binary.");
-DEFINE_string(socket_forward_proxy_ports, "5555", "Comma-separated list of "
- "ports on which to run the socket_forward_proxy server. These "
- "are the port numbers of the guest-side process. The "
- "host-side socket_forward_proxy process will bias the port "
- "numbers.");
DEFINE_bool(start_wifi_relay, true, "Whether to start the wifi_relay process.");
DEFINE_string(wifi_relay_binary,
@@ -309,6 +308,20 @@
"/bin/rm", "-f", file.c_str(), NULL};
subprocess(rm_command, NULL);
}
+
+
+// Emulators are discovered on odd numbered ports from 5555 to 5585
+constexpr int kFirstEmulatorPort = 5555;
+
+std::string GetGuestPortArg() {
+ return std::string{"--guest_ports="} + std::to_string(kFirstEmulatorPort);
+}
+
+std::string GetHostPortArg() {
+ return std::string{"--host_ports="} +
+ std::to_string(kFirstEmulatorPort + (vsoc::GetDefaultInstance() - 1) * 2);
+}
+
} // anonymous namespace
int main(int argc, char** argv) {
@@ -419,9 +432,14 @@
std::string entropy_source = "/dev/urandom";
- auto port_arg = std::string{"--ports="} + FLAGS_socket_forward_proxy_ports;
+ auto guest_port_arg = GetGuestPortArg();
+ auto host_port_arg = GetHostPortArg();
+
const char* const socket_proxy[] =
- {FLAGS_socket_forward_proxy_binary.c_str(), port_arg.c_str(), NULL};
+ {FLAGS_socket_forward_proxy_binary.c_str(),
+ guest_port_arg.c_str(),
+ host_port_arg.c_str(),
+ NULL};
subprocess(socket_proxy, nullptr, false);
config::GuestConfig cfg;
diff --git a/host/libs/config/host_config.cpp b/host/libs/config/host_config.cpp
index cc0218d..df39bb6 100644
--- a/host/libs/config/host_config.cpp
+++ b/host/libs/config/host_config.cpp
@@ -16,21 +16,29 @@
#include "host/libs/config/host_config.h"
-#include <stdlib.h>
-#include <string.h>
+#include <cstdlib>
+#include <cstring>
#include <string>
#include <iomanip>
#include <sstream>
#include <gflags/gflags.h>
-const char kVsocUserPrefix[] = "vsoc-";
-const char kDefaultUuidPrefix[] = "699acfc4-c8c4-11e7-882b-5065f31dc1";
+constexpr char kDefaultUuidPrefix[] = "699acfc4-c8c4-11e7-882b-5065f31dc1";
-int GetDefaultInstance() {
- char* user = getenv("USER");
- if (user && !memcmp(user, kVsocUserPrefix, sizeof(kVsocUserPrefix) - 1)) {
- int temp = atoi(user + sizeof(kVsocUserPrefix) - 1);
+DEFINE_string(domain, vsoc::GetDefaultShmClientSocketPath(),
+ "Path to the ivshmem client socket");
+DEFINE_int32(instance, vsoc::GetDefaultInstance(),
+ "Instance number. Must be unique.");
+DEFINE_string(uuid, vsoc::GetPerInstanceDefault(kDefaultUuidPrefix).c_str(),
+ "UUID to use for the device. Random if not specified");
+
+int vsoc::GetDefaultInstance() {
+ static constexpr char kVsocUserPrefix[] = "vsoc-";
+ const char* user = std::getenv("USER");
+ if (user && !std::strncmp(user, kVsocUserPrefix,
+ sizeof(kVsocUserPrefix) - 1)) {
+ int temp = std::atoi(user + sizeof(kVsocUserPrefix) - 1);
if (temp > 0) {
return temp;
}
@@ -38,13 +46,6 @@
return 1;
}
-DEFINE_string(domain, vsoc::GetDefaultShmClientSocketPath(),
- "Path to the ivshmem client socket");
-DEFINE_int32(instance, GetDefaultInstance(),
- "Instance number. Must be unique.");
-DEFINE_string(uuid, vsoc::GetPerInstanceDefault(kDefaultUuidPrefix).c_str(),
- "UUID to use for the device. Random if not specified");
-
std::string vsoc::GetPerInstanceDefault(const char* prefix) {
std::ostringstream stream;
stream << prefix << std::setfill('0') << std::setw(2)
diff --git a/host/libs/config/host_config.h b/host/libs/config/host_config.h
index 65ef523..15d2059 100644
--- a/host/libs/config/host_config.h
+++ b/host/libs/config/host_config.h
@@ -21,6 +21,7 @@
#include <string>
namespace vsoc {
+int GetDefaultInstance();
std::string GetPerInstanceDefault(const char* prefix);
int GetPerInstanceDefault(int base);
std::string GetDefaultPerInstanceDir();