diff --git a/base/cvd/cuttlefish/host/commands/assemble_cvd/assemble_cvd_flags.cpp b/base/cvd/cuttlefish/host/commands/assemble_cvd/assemble_cvd_flags.cpp index 826ceb7b0e9..96778f9bdec 100644 --- a/base/cvd/cuttlefish/host/commands/assemble_cvd/assemble_cvd_flags.cpp +++ b/base/cvd/cuttlefish/host/commands/assemble_cvd/assemble_cvd_flags.cpp @@ -142,6 +142,8 @@ DEFINE_vec(netsim_uwb, fmt::format("{}", CF_DEFAULTS_NETSIM_UWB), "[Experimental] Connect Uwb radio to netsim."); DEFINE_vec(netsim_nfc, fmt::format("{}", CF_DEFAULTS_NETSIM_NFC), "[Experimental] Connect Nfc radio to netsim."); +DEFINE_vec(netsim_modem, fmt::format("{}", CF_DEFAULTS_NETSIM_MODEM), + "[Experimental] Connect Modem radio to netsim."); DEFINE_string(netsim_args, CF_DEFAULTS_NETSIM_ARGS, "Space-separated list of netsim args."); diff --git a/base/cvd/cuttlefish/host/commands/assemble_cvd/assemble_cvd_flags.h b/base/cvd/cuttlefish/host/commands/assemble_cvd/assemble_cvd_flags.h index bb4c32857c8..d0501b7fde3 100644 --- a/base/cvd/cuttlefish/host/commands/assemble_cvd/assemble_cvd_flags.h +++ b/base/cvd/cuttlefish/host/commands/assemble_cvd/assemble_cvd_flags.h @@ -69,6 +69,7 @@ DECLARE_vec(netsim); DECLARE_vec(netsim_bt); DECLARE_vec(netsim_uwb); DECLARE_vec(netsim_nfc); +DECLARE_vec(netsim_modem); DECLARE_string(netsim_args); DECLARE_bool(enable_automotive_proxy); diff --git a/base/cvd/cuttlefish/host/commands/assemble_cvd/bootconfig_args.cpp b/base/cvd/cuttlefish/host/commands/assemble_cvd/bootconfig_args.cpp index 95f62149016..5edfade22df 100644 --- a/base/cvd/cuttlefish/host/commands/assemble_cvd/bootconfig_args.cpp +++ b/base/cvd/cuttlefish/host/commands/assemble_cvd/bootconfig_args.cpp @@ -21,10 +21,10 @@ #include #include -#include "absl/strings/str_join.h" -#include "absl/strings/str_split.h" #include "absl/log/log.h" #include "absl/strings/numbers.h" +#include "absl/strings/str_join.h" +#include "absl/strings/str_split.h" #include "cuttlefish/common/libs/utils/contains.h" #include "cuttlefish/common/libs/utils/json.h" @@ -156,8 +156,10 @@ Result ValidateBoardBootconfigKeys( Result> BootconfigArgsFromConfig( const CuttlefishConfig& config, const CuttlefishConfig::InstanceSpecific& instance, - const std::map> builtin_bootconfig_args) { - CF_EXPECT(ValidateBoardBootconfigKeys(instance.device_type(), builtin_bootconfig_args)); + const std::map> + builtin_bootconfig_args) { + CF_EXPECT(ValidateBoardBootconfigKeys(instance.device_type(), + builtin_bootconfig_args)); std::unordered_map bootconfig_args; @@ -237,6 +239,10 @@ Result> BootconfigArgsFromConfig( instance.modem_simulator_ports(); } + if (instance.enable_modem_netsim()) { + bootconfig_args["androidboot.netsim_modem"] = "1"; + } + // Once all Cuttlefish kernel versions are at least 5.15, filename encryption // will not need to be set conditionally. HCTR2 will always be available. // At that point fstab.cf.f2fs.cts and fstab.cf.ext4.cts can be removed. @@ -331,7 +337,8 @@ Result> BootconfigArgsFromConfig( bootconfig_args["androidboot.wifi_impl"] = "virt_wifi"; } - if (!builtin_bootconfig_args.count("androidboot.vendor.apex.com.google.emulated.camera.provider.hal")){ + if (!builtin_bootconfig_args.count( + "androidboot.vendor.apex.com.google.emulated.camera.provider.hal")) { bootconfig_args ["androidboot.vendor.apex.com.google.emulated.camera.provider.hal"] = // Camera configs is only populated for virtio-media host camera @@ -343,9 +350,11 @@ Result> BootconfigArgsFromConfig( } if (instance.device_type() == cuttlefish::DeviceType::Auto) { - if (!builtin_bootconfig_args.count("androidboot.cuttlefish_service_bluetooth_checker")) { + if (!builtin_bootconfig_args.count( + "androidboot.cuttlefish_service_bluetooth_checker")) { // # TODO (b/405655265) Remove once the BT issue is fixed - bootconfig_args["androidboot.cuttlefish_service_bluetooth_checker"] = "false"; + bootconfig_args["androidboot.cuttlefish_service_bluetooth_checker"] = + "false"; } } diff --git a/base/cvd/cuttlefish/host/commands/assemble_cvd/flags.cc b/base/cvd/cuttlefish/host/commands/assemble_cvd/flags.cc index c3cb9dc8c3b..324f7470d3e 100644 --- a/base/cvd/cuttlefish/host/commands/assemble_cvd/flags.cc +++ b/base/cvd/cuttlefish/host/commands/assemble_cvd/flags.cc @@ -486,9 +486,15 @@ Result InitializeCuttlefishConfiguration( std::vector netsim_nfc_vec = CF_EXPECT(GET_FLAG_BOOL_VALUE(netsim_nfc)); bool any_netsim_nfc = std::any_of( netsim_nfc_vec.begin(), netsim_nfc_vec.end(), [](bool e) { return e; }); + std::vector netsim_modem_vec = + CF_EXPECT(GET_FLAG_BOOL_VALUE(netsim_modem)); + bool any_netsim_modem = + std::any_of(netsim_modem_vec.begin(), netsim_modem_vec.end(), + [](bool e) { return e; }); bool netsim_has_bt = any_netsim_all_radios || any_netsim_bt; bool netsim_has_uwb = any_netsim_all_radios || any_netsim_uwb; bool netsim_has_nfc = any_netsim_all_radios || any_netsim_nfc; + bool netsim_has_modem = any_netsim_all_radios || any_netsim_modem; // These flags inform NetsimServer::ResultSetup which radios it owns. if (netsim_has_bt) { @@ -501,6 +507,9 @@ Result InitializeCuttlefishConfiguration( if (netsim_has_nfc) { tmp_config_obj.netsim_radio_enable(CuttlefishConfig::NetsimRadio::Nfc); } + if (netsim_has_modem) { + tmp_config_obj.netsim_radio_enable(CuttlefishConfig::NetsimRadio::Modem); + } bool any_not_netsim_bt = false; bool any_not_netsim_uwb = false; @@ -1034,9 +1043,12 @@ Result InitializeCuttlefishConfiguration( guest_enforce_security_values.ForIndex(instance_index)); instance.set_pause_in_bootloader(pause_in_bootloader_vec[instance_index]); instance.set_run_as_daemon(daemon_values.ForIndex(instance_index)); + bool is_netsim_all = netsim_all_radios_vec[instance_index]; + bool is_modem_netsim = is_netsim_all || netsim_modem_vec[instance_index]; instance.set_enable_modem_simulator( enable_modem_simulator_vec[instance_index] && - !enable_minimal_mode_vec[instance_index]); + !enable_minimal_mode_vec[instance_index] && !is_modem_netsim); + instance.set_enable_modem_netsim(is_modem_netsim); instance.set_modem_simulator_instance_number( modem_simulator_count_vec[instance_index]); instance.set_modem_simulator_sim_type( @@ -1079,7 +1091,6 @@ Result InitializeCuttlefishConfiguration( // crosvm should create fifos for Bluetooth bool enable_host_bluetooth = enable_host_bluetooth_vec[instance_index]; - bool is_netsim_all = netsim_all_radios_vec[instance_index]; bool is_bt_netsim = is_netsim_all || netsim_bt_vec[instance_index]; // or is_bt_netsim is here for backwards compatibility only instance.set_has_bluetooth(enable_host_bluetooth || is_bt_netsim); @@ -1092,8 +1103,6 @@ Result InitializeCuttlefishConfiguration( instance.set_enable_host_uwb_connector(FLAGS_enable_host_uwb && !is_uwb_netsim); - bool is_any_netsim = is_netsim_all || is_bt_netsim || is_uwb_netsim; - instance.set_uuid(uuid_vec[instance_index]); instance.set_environment_name(environment_name); @@ -1284,7 +1293,9 @@ Result InitializeCuttlefishConfiguration( auto port = 8443 + num - 1; // Change the signaling server port for all instances tmp_config_obj.set_sig_server_proxy_port(port); - instance.set_start_netsim(is_first_instance && is_any_netsim); + instance.set_start_netsim(is_first_instance && + (netsim_has_bt || netsim_has_uwb || + netsim_has_nfc || netsim_has_modem)); instance.set_start_rootcanal(is_first_instance && any_not_netsim_bt && (FLAGS_rootcanal_instance_num <= 0)); diff --git a/base/cvd/cuttlefish/host/commands/assemble_cvd/flags_defaults.h b/base/cvd/cuttlefish/host/commands/assemble_cvd/flags_defaults.h index 8b47a93d487..cb10cfbbb69 100644 --- a/base/cvd/cuttlefish/host/commands/assemble_cvd/flags_defaults.h +++ b/base/cvd/cuttlefish/host/commands/assemble_cvd/flags_defaults.h @@ -175,6 +175,7 @@ #define CF_DEFAULTS_NETSIM_BT true #define CF_DEFAULTS_NETSIM_UWB true #define CF_DEFAULTS_NETSIM_NFC false +#define CF_DEFAULTS_NETSIM_MODEM false // Netsim default parameters #define CF_DEFAULTS_NETSIM_ARGS "" diff --git a/base/cvd/cuttlefish/host/commands/run_cvd/launch/netsim_server.cpp b/base/cvd/cuttlefish/host/commands/run_cvd/launch/netsim_server.cpp index f684cf87238..4e2f3a99b54 100644 --- a/base/cvd/cuttlefish/host/commands/run_cvd/launch/netsim_server.cpp +++ b/base/cvd/cuttlefish/host/commands/run_cvd/launch/netsim_server.cpp @@ -56,13 +56,20 @@ class Chip { public: SharedFD fd_in; SharedFD fd_out; + int sim_type = 1; Chip(std::string kind) : kind_(kind) {} // Append the chip information as Json to the command. void Append(Command& c) const { c.AppendToLastParameter(R"({"kind":")", kind_, R"(","fdIn":)", fd_in, - R"(,"fdOut":)", fd_out, "}"); + R"(,"fdOut":)", fd_out); + if (kind_ == "CELLULAR") { + // simType is defined as int32 in netsim's startup.proto, so do not quote + // it. + c.AppendToLastParameter(R"(,"simType":)", std::to_string(sim_type)); + } + c.AppendToLastParameter("}"); } private: @@ -207,6 +214,14 @@ class NetsimServer : public CommandSource { chip.fd_out = CF_EXPECT(MakeFifo(instance, "nfc_fifo_vm.out")); device.chips.emplace_back(chip); } + // Add modem chip if enabled + if (config_.netsim_radio_enabled(CuttlefishConfig::NetsimRadio::Modem)) { + Chip chip("CELLULAR"); + chip.fd_in = CF_EXPECT(MakeFifo(instance, "modem_fifo_vm.in")); + chip.fd_out = CF_EXPECT(MakeFifo(instance, "modem_fifo_vm.out")); + chip.sim_type = instance.modem_simulator_sim_type(); + device.chips.emplace_back(chip); + } // Add other chips if enabled devices_.emplace_back(device); } diff --git a/base/cvd/cuttlefish/host/libs/config/cuttlefish_config.h b/base/cvd/cuttlefish/host/libs/config/cuttlefish_config.h index 0a667ab4473..d2d0c7f961f 100644 --- a/base/cvd/cuttlefish/host/libs/config/cuttlefish_config.h +++ b/base/cvd/cuttlefish/host/libs/config/cuttlefish_config.h @@ -161,6 +161,7 @@ class CuttlefishConfig { Wifi = 0b00000010, Uwb = 0b00000100, Nfc = 0b00001000, + Modem = 0b00010000, }; void netsim_radio_enable(NetsimRadio flag); @@ -384,6 +385,7 @@ class CuttlefishConfig { // modem simulator related std::string modem_simulator_ports() const; + bool enable_modem_netsim() const; // The device id the webrtc process should use to register with the // signaling server @@ -646,6 +648,7 @@ class CuttlefishConfig { void set_environment_name(const std::string& env_name); // modem simulator related void set_modem_simulator_ports(const std::string& modem_simulator_ports); + void set_enable_modem_netsim(bool enable); void set_virtual_disk_paths(const std::vector& disk_paths); void set_webrtc_device_id(const std::string& id); void set_start_rootcanal(bool start); diff --git a/base/cvd/cuttlefish/host/libs/config/cuttlefish_config_instance.cpp b/base/cvd/cuttlefish/host/libs/config/cuttlefish_config_instance.cpp index 83d7dda6cb0..201d99e9ab4 100644 --- a/base/cvd/cuttlefish/host/libs/config/cuttlefish_config_instance.cpp +++ b/base/cvd/cuttlefish/host/libs/config/cuttlefish_config_instance.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#include "cuttlefish/host/libs/config/cuttlefish_config.h" - #include #include @@ -46,6 +44,7 @@ #include "cuttlefish/host/libs/config/ap_boot_flow.h" #include "cuttlefish/host/libs/config/boot_flow.h" #include "cuttlefish/host/libs/config/config_constants.h" +#include "cuttlefish/host/libs/config/cuttlefish_config.h" #include "cuttlefish/host/libs/config/data_image_policy.h" #include "cuttlefish/host/libs/config/external_network_mode.h" #include "cuttlefish/host/libs/config/gpu_mode.h" @@ -309,7 +308,8 @@ void CuttlefishConfig::MutableInstanceSpecific::set_fuchsia_multiboot_bin_path( const std::string& fuchsia_multiboot_bin_path) { (*Dictionary())[kFuchsiaMultibootBinPath] = fuchsia_multiboot_bin_path; } -std::string CuttlefishConfig::InstanceSpecific::fuchsia_multiboot_bin_path() const { +std::string CuttlefishConfig::InstanceSpecific::fuchsia_multiboot_bin_path() + const { return (*Dictionary())[kFuchsiaMultibootBinPath].asString(); } static constexpr char kFuchsiaRootImage[] = "fuchsia_root_image"; @@ -408,7 +408,8 @@ int CuttlefishConfig::InstanceSpecific::index() const { } static constexpr char kVirtualDiskPaths[] = "virtual_disk_paths"; -std::vector CuttlefishConfig::InstanceSpecific::virtual_disk_paths() const { +std::vector +CuttlefishConfig::InstanceSpecific::virtual_disk_paths() const { std::vector virtual_disks; auto virtual_disks_json_obj = (*Dictionary())[kVirtualDiskPaths]; for (const auto& disk : virtual_disks_json_obj) { @@ -444,7 +445,8 @@ void CuttlefishConfig::MutableInstanceSpecific::set_bootconfig_supported( } static constexpr char kFilenameEncryptionMode[] = "filename_encryption_mode"; -std::string CuttlefishConfig::InstanceSpecific::filename_encryption_mode() const { +std::string CuttlefishConfig::InstanceSpecific::filename_encryption_mode() + const { return (*Dictionary())[kFilenameEncryptionMode].asString(); } void CuttlefishConfig::MutableInstanceSpecific::set_filename_encryption_mode( @@ -480,7 +482,7 @@ std::string CuttlefishConfig::InstanceSpecific::gnss_file_path() const { return (*Dictionary())[kGnssFilePath].asString(); } void CuttlefishConfig::MutableInstanceSpecific::set_gnss_file_path( - const std::string& gnss_file_path) { + const std::string& gnss_file_path) { (*Dictionary())[kGnssFilePath] = gnss_file_path; } @@ -521,8 +523,12 @@ bool CuttlefishConfig::InstanceSpecific::kgdb() const { } static constexpr char kCpus[] = "cpus"; -void CuttlefishConfig::MutableInstanceSpecific::set_cpus(int cpus) { (*Dictionary())[kCpus] = cpus; } -int CuttlefishConfig::InstanceSpecific::cpus() const { return (*Dictionary())[kCpus].asInt(); } +void CuttlefishConfig::MutableInstanceSpecific::set_cpus(int cpus) { + (*Dictionary())[kCpus] = cpus; +} +int CuttlefishConfig::InstanceSpecific::cpus() const { + return (*Dictionary())[kCpus].asInt(); +} static constexpr char kVcpuInfo[] = "vcpu_config_path"; void CuttlefishConfig::MutableInstanceSpecific::set_vcpu_config_path( @@ -591,14 +597,16 @@ static constexpr char kUserdataFormat[] = "userdata_format"; std::string CuttlefishConfig::InstanceSpecific::userdata_format() const { return (*Dictionary())[kUserdataFormat].asString(); } -void CuttlefishConfig::MutableInstanceSpecific::set_userdata_format(const std::string& userdata_format) { +void CuttlefishConfig::MutableInstanceSpecific::set_userdata_format( + const std::string& userdata_format) { auto fmt = userdata_format; std::transform(fmt.begin(), fmt.end(), fmt.begin(), ::tolower); (*Dictionary())[kUserdataFormat] = fmt; } static constexpr char kGuestEnforceSecurity[] = "guest_enforce_security"; -void CuttlefishConfig::MutableInstanceSpecific::set_guest_enforce_security(bool guest_enforce_security) { +void CuttlefishConfig::MutableInstanceSpecific::set_guest_enforce_security( + bool guest_enforce_security) { (*Dictionary())[kGuestEnforceSecurity] = guest_enforce_security; } bool CuttlefishConfig::InstanceSpecific::guest_enforce_security() const { @@ -606,7 +614,8 @@ bool CuttlefishConfig::InstanceSpecific::guest_enforce_security() const { } static constexpr char kUseSdcard[] = "use_sdcard"; -void CuttlefishConfig::MutableInstanceSpecific::set_use_sdcard(bool use_sdcard) { +void CuttlefishConfig::MutableInstanceSpecific::set_use_sdcard( + bool use_sdcard) { (*Dictionary())[kUseSdcard] = use_sdcard; } bool CuttlefishConfig::InstanceSpecific::use_sdcard() const { @@ -614,7 +623,8 @@ bool CuttlefishConfig::InstanceSpecific::use_sdcard() const { } static constexpr char kPauseInBootloader[] = "pause_in_bootloader"; -void CuttlefishConfig::MutableInstanceSpecific::set_pause_in_bootloader(bool pause_in_bootloader) { +void CuttlefishConfig::MutableInstanceSpecific::set_pause_in_bootloader( + bool pause_in_bootloader) { (*Dictionary())[kPauseInBootloader] = pause_in_bootloader; } bool CuttlefishConfig::InstanceSpecific::pause_in_bootloader() const { @@ -625,7 +635,8 @@ static constexpr char kRunAsDaemon[] = "run_as_daemon"; bool CuttlefishConfig::InstanceSpecific::run_as_daemon() const { return (*Dictionary())[kRunAsDaemon].asBool(); } -void CuttlefishConfig::MutableInstanceSpecific::set_run_as_daemon(bool run_as_daemon) { +void CuttlefishConfig::MutableInstanceSpecific::set_run_as_daemon( + bool run_as_daemon) { (*Dictionary())[kRunAsDaemon] = run_as_daemon; } @@ -735,7 +746,8 @@ static constexpr char kGpuCaptureBinary[] = "gpu_capture_binary"; std::string CuttlefishConfig::InstanceSpecific::gpu_capture_binary() const { return (*Dictionary())[kGpuCaptureBinary].asString(); } -void CuttlefishConfig::MutableInstanceSpecific::set_gpu_capture_binary(const std::string& name) { +void CuttlefishConfig::MutableInstanceSpecific::set_gpu_capture_binary( + const std::string& name) { (*Dictionary())[kGpuCaptureBinary] = name; } @@ -812,7 +824,8 @@ static constexpr char kRestartSubprocesses[] = "restart_subprocesses"; bool CuttlefishConfig::InstanceSpecific::restart_subprocesses() const { return (*Dictionary())[kRestartSubprocesses].asBool(); } -void CuttlefishConfig::MutableInstanceSpecific::set_restart_subprocesses(bool restart_subprocesses) { +void CuttlefishConfig::MutableInstanceSpecific::set_restart_subprocesses( + bool restart_subprocesses) { (*Dictionary())[kRestartSubprocesses] = restart_subprocesses; } @@ -820,12 +833,14 @@ static constexpr char kHWComposer[] = "hwcomposer"; std::string CuttlefishConfig::InstanceSpecific::hwcomposer() const { return (*Dictionary())[kHWComposer].asString(); } -void CuttlefishConfig::MutableInstanceSpecific::set_hwcomposer(const std::string& name) { +void CuttlefishConfig::MutableInstanceSpecific::set_hwcomposer( + const std::string& name) { (*Dictionary())[kHWComposer] = name; } static constexpr char kEnableGpuUdmabuf[] = "enable_gpu_udmabuf"; -void CuttlefishConfig::MutableInstanceSpecific::set_enable_gpu_udmabuf(const bool enable_gpu_udmabuf) { +void CuttlefishConfig::MutableInstanceSpecific::set_enable_gpu_udmabuf( + const bool enable_gpu_udmabuf) { (*Dictionary())[kEnableGpuUdmabuf] = enable_gpu_udmabuf; } bool CuttlefishConfig::InstanceSpecific::enable_gpu_udmabuf() const { @@ -918,7 +933,8 @@ const Json::Value& CuttlefishConfig::InstanceSpecific::domkey_mapping_config() } static constexpr char kEnableGnssGrpcProxy[] = "enable_gnss_grpc_proxy"; -void CuttlefishConfig::MutableInstanceSpecific::set_enable_gnss_grpc_proxy(const bool enable_gnss_grpc_proxy) { +void CuttlefishConfig::MutableInstanceSpecific::set_enable_gnss_grpc_proxy( + const bool enable_gnss_grpc_proxy) { (*Dictionary())[kEnableGnssGrpcProxy] = enable_gnss_grpc_proxy; } bool CuttlefishConfig::InstanceSpecific::enable_gnss_grpc_proxy() const { @@ -975,7 +991,8 @@ static constexpr char kGem5DebugFile[] = "gem5_debug_file"; std::string CuttlefishConfig::InstanceSpecific::gem5_debug_file() const { return (*Dictionary())[kGem5DebugFile].asString(); } -void CuttlefishConfig::MutableInstanceSpecific::set_gem5_debug_file(const std::string& gem5_debug_file) { +void CuttlefishConfig::MutableInstanceSpecific::set_gem5_debug_file( + const std::string& gem5_debug_file) { (*Dictionary())[kGem5DebugFile] = gem5_debug_file; } @@ -988,7 +1005,8 @@ bool CuttlefishConfig::InstanceSpecific::mte() const { } static constexpr char kEnableKernelLog[] = "enable_kernel_log"; -void CuttlefishConfig::MutableInstanceSpecific::set_enable_kernel_log(bool enable_kernel_log) { +void CuttlefishConfig::MutableInstanceSpecific::set_enable_kernel_log( + bool enable_kernel_log) { (*Dictionary())[kEnableKernelLog] = enable_kernel_log; } bool CuttlefishConfig::InstanceSpecific::enable_kernel_log() const { @@ -996,7 +1014,8 @@ bool CuttlefishConfig::InstanceSpecific::enable_kernel_log() const { } static constexpr char kBootSlot[] = "boot_slot"; -void CuttlefishConfig::MutableInstanceSpecific::set_boot_slot(const std::string& boot_slot) { +void CuttlefishConfig::MutableInstanceSpecific::set_boot_slot( + const std::string& boot_slot) { (*Dictionary())[kBootSlot] = boot_slot; } std::string CuttlefishConfig::InstanceSpecific::boot_slot() const { @@ -1040,7 +1059,8 @@ bool CuttlefishConfig::InstanceSpecific::enable_jcard_simulator() const { } static constexpr char kWebRTCAssetsDir[] = "webrtc_assets_dir"; -void CuttlefishConfig::MutableInstanceSpecific::set_webrtc_assets_dir(const std::string& webrtc_assets_dir) { +void CuttlefishConfig::MutableInstanceSpecific::set_webrtc_assets_dir( + const std::string& webrtc_assets_dir) { (*Dictionary())[kWebRTCAssetsDir] = webrtc_assets_dir; } std::string CuttlefishConfig::InstanceSpecific::webrtc_assets_dir() const { @@ -1055,7 +1075,8 @@ void CuttlefishConfig::MutableInstanceSpecific::set_webrtc_tcp_port_range( arr[1] = range.second; (*Dictionary())[kWebrtcTcpPortRange] = arr; } -std::pair CuttlefishConfig::InstanceSpecific::webrtc_tcp_port_range() const { +std::pair +CuttlefishConfig::InstanceSpecific::webrtc_tcp_port_range() const { std::pair ret; ret.first = (*Dictionary())[kWebrtcTcpPortRange][0].asInt(); ret.second = (*Dictionary())[kWebrtcTcpPortRange][1].asInt(); @@ -1070,7 +1091,8 @@ void CuttlefishConfig::MutableInstanceSpecific::set_webrtc_udp_port_range( arr[1] = range.second; (*Dictionary())[kWebrtcUdpPortRange] = arr; } -std::pair CuttlefishConfig::InstanceSpecific::webrtc_udp_port_range() const { +std::pair +CuttlefishConfig::InstanceSpecific::webrtc_udp_port_range() const { std::pair ret; ret.first = (*Dictionary())[kWebrtcUdpPortRange][0].asInt(); ret.second = (*Dictionary())[kWebrtcUdpPortRange][1].asInt(); @@ -1142,7 +1164,8 @@ bool CuttlefishConfig::InstanceSpecific::vhost_net() const { } static constexpr char kOpenThreadNodeId[] = "openthread_node_id"; -void CuttlefishConfig::MutableInstanceSpecific::set_openthread_node_id(int node_id) { +void CuttlefishConfig::MutableInstanceSpecific::set_openthread_node_id( + int node_id) { (*Dictionary())[kOpenThreadNodeId] = node_id; } int CuttlefishConfig::InstanceSpecific::openthread_node_id() const { @@ -1159,7 +1182,8 @@ bool CuttlefishConfig::InstanceSpecific::vhost_user_vsock() const { } static constexpr char kRilDns[] = "ril_dns"; -void CuttlefishConfig::MutableInstanceSpecific::set_ril_dns(const std::string& ril_dns) { +void CuttlefishConfig::MutableInstanceSpecific::set_ril_dns( + const std::string& ril_dns) { (*Dictionary())[kRilDns] = ril_dns; } std::string CuttlefishConfig::InstanceSpecific::ril_dns() const { @@ -1299,7 +1323,8 @@ DeviceType CuttlefishConfig::InstanceSpecific::device_type() const { } static constexpr char kEnableSandbox[] = "enable_sandbox"; -void CuttlefishConfig::MutableInstanceSpecific::set_enable_sandbox(const bool enable_sandbox) { +void CuttlefishConfig::MutableInstanceSpecific::set_enable_sandbox( + const bool enable_sandbox) { (*Dictionary())[kEnableSandbox] = enable_sandbox; } bool CuttlefishConfig::InstanceSpecific::enable_sandbox() const { @@ -1351,6 +1376,15 @@ void CuttlefishConfig::MutableInstanceSpecific::set_modem_simulator_ports( (*Dictionary())[kModemSimulatorPorts] = modem_simulator_ports; } +static constexpr char kEnableModemNetsim[] = "enable_modem_netsim"; +bool CuttlefishConfig::InstanceSpecific::enable_modem_netsim() const { + return (*Dictionary())[kEnableModemNetsim].asBool(); +} +void CuttlefishConfig::MutableInstanceSpecific::set_enable_modem_netsim( + bool enable) { + (*Dictionary())[kEnableModemNetsim] = enable; +} + std::string CuttlefishConfig::InstanceSpecific::launcher_log_path() const { return AbsolutePath(PerInstanceLogPath(kLogNameLauncher)); } @@ -1368,8 +1402,8 @@ std::string CuttlefishConfig::InstanceSpecific::persistent_composite_disk_path() return AbsolutePath(PerInstancePath("persistent_composite.img")); } -std::string CuttlefishConfig::InstanceSpecific::persistent_ap_composite_disk_path() - const { +std::string +CuttlefishConfig::InstanceSpecific::persistent_ap_composite_disk_path() const { return AbsolutePath(PerInstancePath("ap_persistent_composite.img")); } @@ -1379,17 +1413,16 @@ CuttlefishConfig::InstanceSpecific::persistent_ap_composite_overlay_path() return AbsolutePath(PerInstancePath("ap_persistent_composite_overlay.img")); } -std::string CuttlefishConfig::InstanceSpecific::os_composite_disk_path() - const { +std::string CuttlefishConfig::InstanceSpecific::os_composite_disk_path() const { return AbsolutePath(PerInstancePath("os_composite.img")); } -std::string CuttlefishConfig::InstanceSpecific::ap_composite_disk_path() - const { +std::string CuttlefishConfig::InstanceSpecific::ap_composite_disk_path() const { return AbsolutePath(PerInstancePath("ap_composite.img")); } -std::string CuttlefishConfig::InstanceSpecific::ap_uboot_env_image_path() const { +std::string CuttlefishConfig::InstanceSpecific::ap_uboot_env_image_path() + const { return AbsolutePath(PerInstancePath("ap_uboot_env.img")); } @@ -1415,13 +1448,13 @@ BootFlow CuttlefishConfig::InstanceSpecific::boot_flow() const { const bool chromeos_flow_used = !chromeos_kernel_path().empty() || !chromeos_root_image().empty(); - const bool linux_flow_used = !linux_kernel_path().empty() - || !linux_initramfs_path().empty() - || !linux_root_image().empty(); + const bool linux_flow_used = !linux_kernel_path().empty() || + !linux_initramfs_path().empty() || + !linux_root_image().empty(); - const bool fuchsia_flow_used = !fuchsia_zedboot_path().empty() - || !fuchsia_root_image().empty() - || !fuchsia_multiboot_bin_path().empty(); + const bool fuchsia_flow_used = !fuchsia_zedboot_path().empty() || + !fuchsia_root_image().empty() || + !fuchsia_multiboot_bin_path().empty(); if (android_efi_loader_flow_used) { return BootFlow::AndroidEfiLoader; @@ -1614,7 +1647,8 @@ static constexpr char kUuid[] = "uuid"; std::string CuttlefishConfig::InstanceSpecific::uuid() const { return (*Dictionary())[kUuid].asString(); } -void CuttlefishConfig::MutableInstanceSpecific::set_uuid(const std::string& uuid) { +void CuttlefishConfig::MutableInstanceSpecific::set_uuid( + const std::string& uuid) { (*Dictionary())[kUuid] = uuid; } @@ -1648,7 +1682,8 @@ static constexpr char kFastbootHostPort[] = "fastboot_host_port"; int CuttlefishConfig::InstanceSpecific::fastboot_host_port() const { return (*Dictionary())[kFastbootHostPort].asInt(); } -void CuttlefishConfig::MutableInstanceSpecific::set_fastboot_host_port(int port) { +void CuttlefishConfig::MutableInstanceSpecific::set_fastboot_host_port( + int port) { (*Dictionary())[kFastbootHostPort] = port; } @@ -1691,7 +1726,8 @@ static constexpr char kTombstoneReceiverPort[] = "tombstone_receiver_port"; int CuttlefishConfig::InstanceSpecific::tombstone_receiver_port() const { return (*Dictionary())[kTombstoneReceiverPort].asInt(); } -void CuttlefishConfig::MutableInstanceSpecific::set_tombstone_receiver_port(int tombstone_receiver_port) { +void CuttlefishConfig::MutableInstanceSpecific::set_tombstone_receiver_port( + int tombstone_receiver_port) { (*Dictionary())[kTombstoneReceiverPort] = tombstone_receiver_port; } @@ -1699,7 +1735,8 @@ static constexpr char kAudioControlServerPort[] = "audiocontrol_server_port"; int CuttlefishConfig::InstanceSpecific::audiocontrol_server_port() const { return (*Dictionary())[kAudioControlServerPort].asInt(); } -void CuttlefishConfig::MutableInstanceSpecific::set_audiocontrol_server_port(int audiocontrol_server_port) { +void CuttlefishConfig::MutableInstanceSpecific::set_audiocontrol_server_port( + int audiocontrol_server_port) { (*Dictionary())[kAudioControlServerPort] = audiocontrol_server_port; } @@ -1707,7 +1744,8 @@ static constexpr char kLightsServerPort[] = "lights_server_port"; int CuttlefishConfig::InstanceSpecific::lights_server_port() const { return (*Dictionary())[kLightsServerPort].asInt(); } -void CuttlefishConfig::MutableInstanceSpecific::set_lights_server_port(int lights_server_port) { +void CuttlefishConfig::MutableInstanceSpecific::set_lights_server_port( + int lights_server_port) { (*Dictionary())[kLightsServerPort] = lights_server_port; } @@ -1747,8 +1785,7 @@ bool CuttlefishConfig::InstanceSpecific::start_casimir() const { } static constexpr char kStartPica[] = "start_pica"; -void CuttlefishConfig::MutableInstanceSpecific::set_start_pica( - bool start) { +void CuttlefishConfig::MutableInstanceSpecific::set_start_pica(bool start) { (*Dictionary())[kStartPica] = start; } bool CuttlefishConfig::InstanceSpecific::start_pica() const { @@ -1774,7 +1811,8 @@ bool CuttlefishConfig::InstanceSpecific::start_wmediumd_instance() const { } static constexpr char kMcu[] = "mcu"; -void CuttlefishConfig::MutableInstanceSpecific::set_mcu(const Json::Value& cfg) { +void CuttlefishConfig::MutableInstanceSpecific::set_mcu( + const Json::Value& cfg) { (*Dictionary())[kMcu] = cfg; } const Json::Value& CuttlefishConfig::InstanceSpecific::mcu() const { @@ -1782,7 +1820,8 @@ const Json::Value& CuttlefishConfig::InstanceSpecific::mcu() const { } static constexpr char kApBootFlow[] = "ap_boot_flow"; -void CuttlefishConfig::MutableInstanceSpecific::set_ap_boot_flow(APBootFlow flow) { +void CuttlefishConfig::MutableInstanceSpecific::set_ap_boot_flow( + APBootFlow flow) { (*Dictionary())[kApBootFlow] = static_cast(flow); } APBootFlow CuttlefishConfig::InstanceSpecific::ap_boot_flow() const { @@ -1849,7 +1888,8 @@ std::string CuttlefishConfig::InstanceSpecific::touch_socket_path( return PerInstanceInternalUdsPath(name); } -std::string CuttlefishConfig::InstanceSpecific::media_socket_path(int index) const { +std::string CuttlefishConfig::InstanceSpecific::media_socket_path( + int index) const { return PerInstanceInternalUdsPath(absl::StrCat("media_", index, ".sock")); } @@ -2006,4 +2046,3 @@ std::string CuttlefishConfig::InstanceSpecific::instance_name() const { std::string CuttlefishConfig::InstanceSpecific::id() const { return id_; } } // namespace cuttlefish - diff --git a/base/cvd/cuttlefish/host/libs/vm_manager/crosvm_manager.cpp b/base/cvd/cuttlefish/host/libs/vm_manager/crosvm_manager.cpp index 990b15a89e1..2efdf3ce346 100644 --- a/base/cvd/cuttlefish/host/libs/vm_manager/crosvm_manager.cpp +++ b/base/cvd/cuttlefish/host/libs/vm_manager/crosvm_manager.cpp @@ -16,10 +16,13 @@ #include "cuttlefish/host/libs/vm_manager/crosvm_manager.h" +#include +#include #include #include #include #include +#include #include #include @@ -28,10 +31,7 @@ #include #include -#include #include "absl/strings/str_join.h" -#include -#include #include "cuttlefish/common/libs/utils/files.h" #include "cuttlefish/common/libs/utils/in_sandbox.h" @@ -261,7 +261,7 @@ Result CrosvmPathForVhostUserGpu(const CuttlefishConfig& config) { break; default: return CF_ERR("Unhandled host arch " << HostArchStr() - << " for vhost user gpu crosvm"); + << " for vhost user gpu crosvm"); } if (FileExists(crosvm_path)) { return crosvm_path; @@ -278,10 +278,11 @@ Result CrosvmPathForVhostUserGpu(const CuttlefishConfig& config) { break; default: return CF_ERR("Unhandled host arch " << HostArchStr() - << " for vhost user gpu crosvm"); + << " for vhost user gpu crosvm"); } - CF_EXPECT(FileExists(crosvm_path), "Failed to find crosvm prebuilt for vhost user gpu."); + CF_EXPECT(FileExists(crosvm_path), + "Failed to find crosvm prebuilt for vhost user gpu."); return crosvm_path; } @@ -601,7 +602,8 @@ Result> CrosvmManager::StartCommands( } if (!instance.crosvm_v4l2_proxy().empty()) { - crosvm_cmd.Cmd().AddParameter("--v4l2-proxy=", instance.crosvm_v4l2_proxy()); + crosvm_cmd.Cmd().AddParameter("--v4l2-proxy=", + instance.crosvm_v4l2_proxy()); } if (instance.gdb_port() > 0) { @@ -922,6 +924,15 @@ Result> CrosvmManager::StartCommands( instance.PerInstanceInternalPath("sensors_data_fifo_vm.out"), instance.PerInstanceInternalPath("sensors_data_fifo_vm.in")); + // /dev/hvc20 = modem + if (instance.enable_modem_netsim()) { + crosvm_cmd.AddHvcReadWrite( + instance.PerInstanceInternalPath("modem_fifo_vm.out"), + instance.PerInstanceInternalPath("modem_fifo_vm.in")); + } else { + crosvm_cmd.AddHvcSink(); + } + for (auto i = 0; i < VmManager::kMaxDisks - disk_num; i++) { crosvm_cmd.AddHvcSink(); } @@ -957,7 +968,8 @@ Result> CrosvmManager::StartCommands( auto config = instance.media_configs()[index]; if (config.type == CuttlefishConfig::MediaType::kV4l2EmulatedCameraSPlane || config.type == CuttlefishConfig::MediaType::kV4l2EmulatedCameraMPlane) { - crosvm_cmd.Cmd().AddParameter("--vhost-user=type=media,socket=", instance.media_socket_path(index)); + crosvm_cmd.Cmd().AddParameter("--vhost-user=type=media,socket=", + instance.media_socket_path(index)); } else if (config.type == CuttlefishConfig::MediaType::kV4l2Proxy) { crosvm_cmd.Cmd().AddParameter("--v4l2-proxy=", "/dev/video0"); } @@ -1071,4 +1083,3 @@ Result CrosvmManager::WaitForRestoreComplete(SharedFD stop_fd) const { } // namespace vm_manager } // namespace cuttlefish - diff --git a/base/cvd/cuttlefish/host/libs/vm_manager/qemu_manager.cpp b/base/cvd/cuttlefish/host/libs/vm_manager/qemu_manager.cpp index c8195def842..d25e9fba948 100644 --- a/base/cvd/cuttlefish/host/libs/vm_manager/qemu_manager.cpp +++ b/base/cvd/cuttlefish/host/libs/vm_manager/qemu_manager.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -30,7 +31,6 @@ #include #include -#include #include "absl/log/log.h" #include "absl/strings/str_split.h" @@ -65,8 +65,8 @@ std::string GetMonitorPath(const CuttlefishConfig& config) { StopperResult Stop() { auto config = CuttlefishConfig::Get(); auto monitor_path = GetMonitorPath(*config); - auto monitor_sock = SharedFD::SocketLocalClient( - monitor_path.c_str(), false, SOCK_STREAM); + auto monitor_sock = + SharedFD::SocketLocalClient(monitor_path.c_str(), false, SOCK_STREAM); if (!monitor_sock->IsOpen()) { LOG(ERROR) << "The connection to qemu is closed, is it still running?"; @@ -115,9 +115,7 @@ Result> GetQemuVersion(const std::string& qemu_binary) { QemuManager::QemuManager(Arch arch) : arch_(arch) {} -bool QemuManager::IsSupported() { - return HostSupportsQemuCli(); -} +bool QemuManager::IsSupported() { return HostSupportsQemuCli(); } Result> QemuManager::ConfigureGraphics( @@ -327,8 +325,8 @@ Result> QemuManager::StartCommands( if (FileExists(access_kregistry)) { access_kregistry_size_bytes = FileSize(access_kregistry); CF_EXPECTF((access_kregistry_size_bytes & (1024 * 1024 - 1)) == 0, - "'{}' file size ({}) not a multiple of 1MB", - access_kregistry, access_kregistry_size_bytes); + "'{}' file size ({}) not a multiple of 1MB", access_kregistry, + access_kregistry_size_bytes); } auto hwcomposer_pmem_size_bytes = 0; @@ -351,7 +349,8 @@ Result> QemuManager::StartCommands( } qemu_cmd.AddParameter("-name"); - qemu_cmd.AddParameter("guest=", instance.instance_name(), ",debug-threads=on"); + qemu_cmd.AddParameter("guest=", instance.instance_name(), + ",debug-threads=on"); std::string machine = is_x86 ? "pc,nvdimm=on" : "virt"; if (is_arm) { @@ -367,7 +366,8 @@ Result> QemuManager::StartCommands( machine += ",mte=on"; } qemu_cmd.AddParameter("-machine"); - qemu_cmd.AddParameter(machine, ",usb=off,dump-guest-core=off,memory-backend=vm_ram"); + qemu_cmd.AddParameter(machine, + ",usb=off,dump-guest-core=off,memory-backend=vm_ram"); if (IsHostCompatible(arch_)) { qemu_cmd.AddParameter("-accel"); @@ -400,8 +400,8 @@ Result> QemuManager::StartCommands( (hwcomposer_pmem_size_bytes / 1024 / 1024) + (is_x86 ? pstore_size_bytes / 1024 / 1024 : 0); auto slots = is_x86 ? ",slots=2" : ""; - qemu_cmd.AddParameter("size=", instance.memory_mb(), "M", - ",maxmem=", maxmem, "M", slots); + qemu_cmd.AddParameter("size=", instance.memory_mb(), "M", ",maxmem=", maxmem, + "M", slots); qemu_cmd.AddParameter("-overcommit"); qemu_cmd.AddParameter("mem-lock=off"); @@ -412,11 +412,11 @@ Result> QemuManager::StartCommands( if (instance.smt()) { CF_EXPECT(instance.cpus() % 2 == 0, "CPUs must be a multiple of 2 in SMT mode"); - qemu_cmd.AddParameter(instance.cpus(), ",cores=", - instance.cpus() / 2, ",threads=2"); + qemu_cmd.AddParameter(instance.cpus(), ",cores=", instance.cpus() / 2, + ",threads=2"); } else { - qemu_cmd.AddParameter(instance.cpus(), ",cores=", - instance.cpus(), ",threads=1"); + qemu_cmd.AddParameter(instance.cpus(), ",cores=", instance.cpus(), + ",threads=1"); } qemu_cmd.AddParameter("-uuid"); @@ -511,9 +511,8 @@ Result> QemuManager::StartCommands( } qemu_cmd.AddParameter("-device"); - qemu_cmd.AddParameter( - "virtio-serial-pci-non-transitional,max_ports=", kMaxSerialPorts, - ",id=virtio-serial"); + qemu_cmd.AddParameter("virtio-serial-pci-non-transitional,max_ports=", + kMaxSerialPorts, ",id=virtio-serial"); // /dev/hvc0 = kernel console // If kernel log is enabled, the virtio-console port will be specified as @@ -658,6 +657,13 @@ Result> QemuManager::StartCommands( // /dev/hvc19 = sensors data add_hvc(instance.PerInstanceInternalPath("sensors_data_fifo_vm")); + // /dev/hvc20 = modem + if (instance.enable_modem_netsim()) { + add_hvc(instance.PerInstanceInternalPath("modem_fifo_vm")); + } else { + add_hvc_sink(); + } + auto disk_num = instance.virtual_disk_paths().size(); for (auto i = 0; i < VmManager::kMaxDisks - disk_num; i++) { @@ -727,8 +733,7 @@ Result> QemuManager::StartCommands( qemu_cmd.AddParameter("-object"); qemu_cmd.AddParameter( "memory-backend-file,id=objpmem1,share=on,mem-path=", - AccessKregistryPath(instance), - ",size=", access_kregistry_size_bytes); + AccessKregistryPath(instance), ",size=", access_kregistry_size_bytes); qemu_cmd.AddParameter("-device"); qemu_cmd.AddParameter( @@ -856,8 +861,7 @@ Result> QemuManager::StartCommands( // behavior changes upstream. if (is_riscv64) { qemu_cmd.AddParameter("-cpu"); - qemu_cmd.AddParameter("rv64", - ",v=true,elen=64,vlen=128", + qemu_cmd.AddParameter("rv64", ",v=true,elen=64,vlen=128", ",zba=true,zbb=true,zbs=true"); } diff --git a/base/cvd/cuttlefish/host/libs/vm_manager/vm_manager.h b/base/cvd/cuttlefish/host/libs/vm_manager/vm_manager.h index 0e43851a257..a571bcda5f6 100644 --- a/base/cvd/cuttlefish/host/libs/vm_manager/vm_manager.h +++ b/base/cvd/cuttlefish/host/libs/vm_manager/vm_manager.h @@ -20,7 +20,7 @@ #include #include -#include +#include "fruit/fruit.h" #include "cuttlefish/common/libs/utils/host_info.h" #include "cuttlefish/host/libs/config/cuttlefish_config.h" @@ -61,14 +61,15 @@ class VmManager { // - /dev/hvc10 = oemlock // - /dev/hvc11 = keymint // - /dev/hvc12 = NFC - // - /dev/hvc13 = vacant (sink, so feel free to use) + // - /dev/hvc13 = Weaver // - /dev/hvc14 = MCU control // - /dev/hvc15 = MCU UART // - /dev/hvc16 = Ti50 TPM FIFO // - /dev/hvc17 = jcardsimulator // - /dev/hvc18 = Sensors control // - /dev/hvc19 = Sensors data - static const int kDefaultNumHvcs = 20; + // - /dev/hvc20 = Modem + static const int kDefaultNumHvcs = 21; // This is the number of virtual disks (block devices) that should be // configured by the VmManager. Related to the description above regarding @@ -132,5 +133,5 @@ Result> ConfigureMultipleBootDevices(const std::string& pci_path, int pci_offset, int num_disks); -} // namespace vm_manager -} // namespace cuttlefish +} // namespace vm_manager +} // namespace cuttlefish