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 2832ce27417..066109e2ba4 100644 --- a/base/cvd/cuttlefish/host/commands/assemble_cvd/bootconfig_args.cpp +++ b/base/cvd/cuttlefish/host/commands/assemble_cvd/bootconfig_args.cpp @@ -242,7 +242,11 @@ Result> BootconfigArgsFromConfig( std::to_string(instance.vsock_guest_cid()); } - if (instance.enable_modem_simulator() && + // Export modem simulator ports for both standalone modem_simulator and + // netsim. The guest RIL (ag/40529282) polls ro.boot.modem_simulator_ports on + // startup to connect over VSOCK regardless of which daemon handles the host + // connection. + if ((instance.enable_modem_simulator() || instance.enable_modem_netsim()) && !instance.modem_simulator_ports().empty()) { bootconfig_args["androidboot.modem_simulator_ports"] = instance.modem_simulator_ports(); diff --git a/base/cvd/cuttlefish/host/commands/assemble_cvd/flags.cc b/base/cvd/cuttlefish/host/commands/assemble_cvd/flags.cc index b9ef55a3c47..9846515d65e 100644 --- a/base/cvd/cuttlefish/host/commands/assemble_cvd/flags.cc +++ b/base/cvd/cuttlefish/host/commands/assemble_cvd/flags.cc @@ -456,9 +456,6 @@ Result InitializeCuttlefishConfiguration( tmp_config_obj.set_ap_rootfs_image(ap_rootfs_image); tmp_config_obj.set_ap_kernel_image(FLAGS_ap_kernel_image); - tmp_config_obj.set_enable_host_nfc(FLAGS_enable_host_nfc); - tmp_config_obj.set_enable_host_nfc_connector(FLAGS_enable_host_nfc); - // get flag default values and store into map auto name_to_default_value = CurrentFlagsToDefaultValue(); // old flags but vectorized for multi-device instances @@ -467,33 +464,15 @@ Result InitializeCuttlefishConfiguration( // netsim flags allow all radios or selecting a specific radio std::vector netsim_all_radios_vec = CF_EXPECT(GET_FLAG_BOOL_VALUE(netsim)); - bool any_netsim_all_radios = - std::any_of(netsim_all_radios_vec.begin(), netsim_all_radios_vec.end(), - [](bool e) { return e; }); std::vector netsim_bt_vec = CF_EXPECT(GET_FLAG_BOOL_VALUE(netsim_bt)); - bool any_netsim_bt = std::any_of(netsim_bt_vec.begin(), netsim_bt_vec.end(), - [](bool e) { return e; }); std::vector netsim_uwb_vec = CF_EXPECT(GET_FLAG_BOOL_VALUE(netsim_uwb)); bool any_netsim_uwb = std::any_of( netsim_uwb_vec.begin(), netsim_uwb_vec.end(), [](bool e) { return e; }); 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; }); - 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; - - // These flags inform NetsimServer::ResultSetup which radios it owns. - if (netsim_has_bt) { - tmp_config_obj.netsim_radio_enable( - CuttlefishConfig::NetsimRadio::Bluetooth); - } - if (netsim_has_uwb) { - tmp_config_obj.netsim_radio_enable(CuttlefishConfig::NetsimRadio::Uwb); - } - if (netsim_has_nfc) { - tmp_config_obj.netsim_radio_enable(CuttlefishConfig::NetsimRadio::Nfc); - } + std::vector netsim_modem_vec = + CF_EXPECT(GET_FLAG_BOOL_VALUE(netsim_modem)); bool any_not_netsim_bt = false; bool any_not_netsim_uwb = false; @@ -1027,9 +1006,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_modem_netsim = netsim_all_radios_vec[instance_index] || + 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( @@ -1085,7 +1067,9 @@ 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; + bool is_nfc_netsim = is_netsim_all || netsim_nfc_vec[instance_index]; + bool is_any_netsim = is_netsim_all || is_bt_netsim || is_uwb_netsim || + is_nfc_netsim || is_modem_netsim; instance.set_uuid(uuid_vec[instance_index]); 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/cvd/cli/parser/golang/load_config.pb.go b/base/cvd/cuttlefish/host/commands/cvd/cli/parser/golang/load_config.pb.go index 66cc46d4f09..8006029776b 100644 --- a/base/cvd/cuttlefish/host/commands/cvd/cli/parser/golang/load_config.pb.go +++ b/base/cvd/cuttlefish/host/commands/cvd/cli/parser/golang/load_config.pb.go @@ -1,7 +1,22 @@ +// +// Copyright (C) 2024 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. + // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 -// protoc v6.33.0 +// protoc-gen-go v1.36.11 +// protoc v3.21.12 // source: cuttlefish/host/commands/cvd/cli/parser/load_config.proto package golang @@ -21,12 +36,18 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// Specifies the emulated user space page size. type UserPageSize int32 const ( + // Kernel page size will be used. UserPageSize_USER_PAGE_SIZE_UNSPECIFIED UserPageSize = 0 - UserPageSize_USER_PAGE_SIZE_16KB UserPageSize = 1 - UserPageSize_USER_PAGE_SIZE_64KB UserPageSize = 2 + // Request a 16KB page size. + // On x86_64, this implies emulation via kernel command line (e.g., + // page_shift=14). + UserPageSize_USER_PAGE_SIZE_16KB UserPageSize = 1 + // Request a 64KB page size. + UserPageSize_USER_PAGE_SIZE_64KB UserPageSize = 2 ) // Enum value maps for UserPageSize. @@ -128,6 +149,7 @@ type EnvironmentSpecification struct { NetsimBt *bool `protobuf:"varint,5,opt,name=netsim_bt,json=netsimBt,proto3,oneof" json:"netsim_bt,omitempty"` NetsimUwb *bool `protobuf:"varint,6,opt,name=netsim_uwb,json=netsimUwb,proto3,oneof" json:"netsim_uwb,omitempty"` NetsimArgs []string `protobuf:"bytes,7,rep,name=netsim_args,json=netsimArgs,proto3" json:"netsim_args,omitempty"` + NetsimModem *bool `protobuf:"varint,8,opt,name=netsim_modem,json=netsimModem,proto3,oneof" json:"netsim_modem,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -211,6 +233,15 @@ func (x *EnvironmentSpecification) GetNetsimArgs() []string { return nil } +func (x *EnvironmentSpecification) GetNetsimModem() bool { + if x != nil && x.NetsimModem != nil { + return *x.NetsimModem + } + return false +} + +// TODO: chadreynolds - when we can make breaking changes and update, use this +// in EnvironmentSpecification instead of individual fields type EnvironmentOptions struct { state protoimpl.MessageState `protogen:"open.v1"` Fetch *Fetch `protobuf:"bytes,1,opt,name=fetch,proto3,oneof" json:"fetch,omitempty"` @@ -219,6 +250,7 @@ type EnvironmentOptions struct { NetsimBt *bool `protobuf:"varint,4,opt,name=netsim_bt,json=netsimBt,proto3,oneof" json:"netsim_bt,omitempty"` NetsimUwb *bool `protobuf:"varint,5,opt,name=netsim_uwb,json=netsimUwb,proto3,oneof" json:"netsim_uwb,omitempty"` NetsimArgs []string `protobuf:"bytes,6,rep,name=netsim_args,json=netsimArgs,proto3" json:"netsim_args,omitempty"` + NetsimModem *bool `protobuf:"varint,7,opt,name=netsim_modem,json=netsimModem,proto3,oneof" json:"netsim_modem,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -295,6 +327,13 @@ func (x *EnvironmentOptions) GetNetsimArgs() []string { return nil } +func (x *EnvironmentOptions) GetNetsimModem() bool { + if x != nil && x.NetsimModem != nil { + return *x.NetsimModem + } + return false +} + type Common struct { state protoimpl.MessageState `protogen:"open.v1"` GroupName *string `protobuf:"bytes,1,opt,name=group_name,json=groupName,proto3,oneof" json:"group_name,omitempty"` @@ -432,17 +471,18 @@ func (x *Fetch) GetProjectId() string { } type Instance struct { - state protoimpl.MessageState `protogen:"open.v1"` - Name *string `protobuf:"bytes,1,opt,name=name,proto3,oneof" json:"name,omitempty"` - Vm *Vm `protobuf:"bytes,2,opt,name=vm,proto3,oneof" json:"vm,omitempty"` - Boot *Boot `protobuf:"bytes,3,opt,name=boot,proto3,oneof" json:"boot,omitempty"` - Security *Security `protobuf:"bytes,4,opt,name=security,proto3,oneof" json:"security,omitempty"` - Disk *Disk `protobuf:"bytes,5,opt,name=disk,proto3,oneof" json:"disk,omitempty"` - Graphics *Graphics `protobuf:"bytes,6,opt,name=graphics,proto3,oneof" json:"graphics,omitempty"` - Streaming *Streaming `protobuf:"bytes,7,opt,name=streaming,proto3,oneof" json:"streaming,omitempty"` - Connectivity *Connectivity `protobuf:"bytes,8,opt,name=connectivity,proto3,oneof" json:"connectivity,omitempty"` - ImportTemplate *string `protobuf:"bytes,9,opt,name=import_template,json=@import,proto3,oneof" json:"import_template,omitempty"` - Media *Media `protobuf:"bytes,10,opt,name=media,proto3,oneof" json:"media,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Name *string `protobuf:"bytes,1,opt,name=name,proto3,oneof" json:"name,omitempty"` + Vm *Vm `protobuf:"bytes,2,opt,name=vm,proto3,oneof" json:"vm,omitempty"` + Boot *Boot `protobuf:"bytes,3,opt,name=boot,proto3,oneof" json:"boot,omitempty"` + Security *Security `protobuf:"bytes,4,opt,name=security,proto3,oneof" json:"security,omitempty"` + Disk *Disk `protobuf:"bytes,5,opt,name=disk,proto3,oneof" json:"disk,omitempty"` + Graphics *Graphics `protobuf:"bytes,6,opt,name=graphics,proto3,oneof" json:"graphics,omitempty"` + Streaming *Streaming `protobuf:"bytes,7,opt,name=streaming,proto3,oneof" json:"streaming,omitempty"` + Connectivity *Connectivity `protobuf:"bytes,8,opt,name=connectivity,proto3,oneof" json:"connectivity,omitempty"` + // TODO: b/337089452 - handle outside of proto logic + ImportTemplate *string `protobuf:"bytes,9,opt,name=import_template,json=@import,proto3,oneof" json:"import_template,omitempty"` + Media *Media `protobuf:"bytes,10,opt,name=media,proto3,oneof" json:"media,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1362,8 +1402,9 @@ func (*V4L2EmulatedCameraMplane) Descriptor() ([]byte, []int) { } type V4L2Proxy struct { - state protoimpl.MessageState `protogen:"open.v1"` - DevicePath *string `protobuf:"bytes,1,opt,name=device_path,json=devicePath,proto3,oneof" json:"device_path,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + // Path to a V4L2 device to expose to the guest. E.g. `/dev/video0`. + DevicePath *string `protobuf:"bytes,1,opt,name=device_path,json=devicePath,proto3,oneof" json:"device_path,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1419,7 +1460,8 @@ type Vm struct { // *Vm_Qemu Vmm isVm_Vmm `protobuf_oneof:"vmm"` CustomActions []*CustomAction `protobuf:"bytes,9,rep,name=custom_actions,json=customActions,proto3" json:"custom_actions,omitempty"` - PageSize *UserPageSize `protobuf:"varint,10,opt,name=page_size,json=pageSize,proto3,enum=cuttlefish.cvd.config.UserPageSize,oneof" json:"page_size,omitempty"` + // Desired user space page size. + PageSize *UserPageSize `protobuf:"varint,10,opt,name=page_size,json=pageSize,proto3,enum=cuttlefish.cvd.config.UserPageSize,oneof" json:"page_size,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1987,7 +2029,7 @@ var File_cuttlefish_host_commands_cvd_cli_parser_load_config_proto protoreflect. const file_cuttlefish_host_commands_cvd_cli_parser_load_config_proto_rawDesc = "" + "\n" + - "9cuttlefish/host/commands/cvd/cli/parser/load_config.proto\x12\x15cuttlefish.cvd.config\"\xb2\x03\n" + + "9cuttlefish/host/commands/cvd/cli/parser/load_config.proto\x12\x15cuttlefish.cvd.config\"\xeb\x03\n" + "\x18EnvironmentSpecification\x12=\n" + "\tinstances\x18\x01 \x03(\v2\x1f.cuttlefish.cvd.config.InstanceR\tinstances\x127\n" + "\x05fetch\x18\x02 \x01(\v2\x1c.cuttlefish.cvd.config.FetchH\x00R\x05fetch\x88\x01\x01\x12=\n" + @@ -1997,14 +2039,16 @@ const file_cuttlefish_host_commands_cvd_cli_parser_load_config_proto_rawDesc = " "\n" + "netsim_uwb\x18\x06 \x01(\bH\x04R\tnetsimUwb\x88\x01\x01\x12\x1f\n" + "\vnetsim_args\x18\a \x03(\tR\n" + - "netsimArgsB\b\n" + + "netsimArgs\x12&\n" + + "\fnetsim_modem\x18\b \x01(\bH\x05R\vnetsimModem\x88\x01\x01B\b\n" + "\x06_fetchB\n" + "\n" + "\b_metricsB\t\n" + "\a_commonB\f\n" + "\n" + "_netsim_btB\r\n" + - "\v_netsim_uwb\"\xed\x02\n" + + "\v_netsim_uwbB\x0f\n" + + "\r_netsim_modem\"\xa6\x03\n" + "\x12EnvironmentOptions\x127\n" + "\x05fetch\x18\x01 \x01(\v2\x1c.cuttlefish.cvd.config.FetchH\x00R\x05fetch\x88\x01\x01\x12=\n" + "\ametrics\x18\x02 \x01(\v2\x1e.cuttlefish.cvd.config.MetricsH\x01R\ametrics\x88\x01\x01\x12:\n" + @@ -2013,14 +2057,16 @@ const file_cuttlefish_host_commands_cvd_cli_parser_load_config_proto_rawDesc = " "\n" + "netsim_uwb\x18\x05 \x01(\bH\x04R\tnetsimUwb\x88\x01\x01\x12\x1f\n" + "\vnetsim_args\x18\x06 \x03(\tR\n" + - "netsimArgsB\b\n" + + "netsimArgs\x12&\n" + + "\fnetsim_modem\x18\a \x01(\bH\x05R\vnetsimModem\x88\x01\x01B\b\n" + "\x06_fetchB\n" + "\n" + "\b_metricsB\t\n" + "\a_commonB\f\n" + "\n" + "_netsim_btB\r\n" + - "\v_netsim_uwb\"t\n" + + "\v_netsim_uwbB\x0f\n" + + "\r_netsim_modem\"t\n" + "\x06Common\x12\"\n" + "\n" + "group_name\x18\x01 \x01(\tH\x00R\tgroupName\x88\x01\x01\x12&\n" + diff --git a/base/cvd/cuttlefish/host/commands/cvd/cli/parser/launch_cvd_parser.cpp b/base/cvd/cuttlefish/host/commands/cvd/cli/parser/launch_cvd_parser.cpp index d27aef54467..6976ad952d6 100644 --- a/base/cvd/cuttlefish/host/commands/cvd/cli/parser/launch_cvd_parser.cpp +++ b/base/cvd/cuttlefish/host/commands/cvd/cli/parser/launch_cvd_parser.cpp @@ -67,6 +67,10 @@ Result> GenerateCfFlags( flags.emplace_back(GenerateFlag("netsim_uwb", launch.netsim_uwb())); } + if (launch.has_netsim_modem()) { + flags.emplace_back(GenerateFlag("netsim_modem", launch.netsim_modem())); + } + if (!launch.netsim_args().empty()) { for (const auto& arg : launch.netsim_args()) { CF_EXPECTF(arg.find_first_of(" \t\n\v\f\r") == std::string::npos, diff --git a/base/cvd/cuttlefish/host/commands/cvd/cli/parser/load_config.proto b/base/cvd/cuttlefish/host/commands/cvd/cli/parser/load_config.proto index 25ac3c436fb..51a1f9d137f 100644 --- a/base/cvd/cuttlefish/host/commands/cvd/cli/parser/load_config.proto +++ b/base/cvd/cuttlefish/host/commands/cvd/cli/parser/load_config.proto @@ -52,6 +52,7 @@ message EnvironmentSpecification { optional bool netsim_bt = 5; optional bool netsim_uwb = 6; repeated string netsim_args = 7; + optional bool netsim_modem = 8; } // TODO: chadreynolds - when we can make breaking changes and update, use this @@ -63,6 +64,7 @@ message EnvironmentOptions { optional bool netsim_bt = 4; optional bool netsim_uwb = 5; repeated string netsim_args = 6; + optional bool netsim_modem = 7; } message Common { diff --git a/base/cvd/cuttlefish/host/commands/run_cvd/launch/BUILD.bazel b/base/cvd/cuttlefish/host/commands/run_cvd/launch/BUILD.bazel index c1e2c15ee73..e7c63c41311 100644 --- a/base/cvd/cuttlefish/host/commands/run_cvd/launch/BUILD.bazel +++ b/base/cvd/cuttlefish/host/commands/run_cvd/launch/BUILD.bazel @@ -311,6 +311,7 @@ cf_cc_library( "//cuttlefish/host/libs/feature", "//cuttlefish/process:command_subprocess", "//cuttlefish/result", + "//libbase", "@fruit", ], ) 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 2c538f230b0..46d283619e9 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 @@ -15,6 +15,11 @@ #include "cuttlefish/host/commands/run_cvd/launch/netsim_server.h" +#include +#include + +#include +#include #include #include #include @@ -56,13 +61,24 @@ class Chip { public: SharedFD fd_in; SharedFD fd_out; + SharedFD vsock_fd; + 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, "}"); + if (vsock_fd->IsOpen()) { + c.AppendToLastParameter(R"({"kind":")", kind_, R"(","vsockFd":)", + vsock_fd); + } else { + c.AppendToLastParameter(R"({"kind":")", kind_, R"(","fdIn":)", fd_in, + R"(,"fdOut":)", fd_out); + } + if (kind_ == "CELLULAR") { + c.AppendToLastParameter(R"(,"simType":)", std::to_string(sim_type)); + } + c.AppendToLastParameter("}"); } private: @@ -192,27 +208,59 @@ class NetsimServer : public CommandSource { for (const auto& instance : config_.Instances()) { Device device(instance.adb_ip_and_port()); // Add bluetooth chip if enabled - if (config_.netsim_radio_enabled( - CuttlefishConfig::NetsimRadio::Bluetooth)) { + if (instance.has_bluetooth() && + !instance.enable_host_bluetooth_connector()) { Chip chip("BLUETOOTH"); chip.fd_in = CF_EXPECT(MakeFifo(instance, "bt_fifo_vm.in")); chip.fd_out = CF_EXPECT(MakeFifo(instance, "bt_fifo_vm.out")); device.chips.emplace_back(chip); } // Add uwb chip if enabled - if (config_.netsim_radio_enabled(CuttlefishConfig::NetsimRadio::Uwb)) { + if (config_.enable_host_uwb() && !instance.enable_host_uwb_connector()) { Chip chip("UWB"); chip.fd_in = CF_EXPECT(MakeFifo(instance, "uwb_fifo_vm.in")); chip.fd_out = CF_EXPECT(MakeFifo(instance, "uwb_fifo_vm.out")); device.chips.emplace_back(chip); } // Add nfc chip if enabled - if (config_.netsim_radio_enabled(CuttlefishConfig::NetsimRadio::Nfc)) { + if (config_.enable_host_nfc() && !config_.enable_host_nfc_connector()) { Chip chip("NFC"); chip.fd_in = CF_EXPECT(MakeFifo(instance, "nfc_fifo_vm.in")); chip.fd_out = CF_EXPECT(MakeFifo(instance, "nfc_fifo_vm.out")); device.chips.emplace_back(chip); } + // Add modem chip if enabled + if (instance.enable_modem_netsim()) { + // modem_count is the number of modems configured for this VM instance + int modem_count = instance.modem_simulator_instance_number(); + CF_EXPECT( + modem_count >= 0 && modem_count < 4, + "Modem simulator instance number should range between 0 and 3"); + auto port_strings = + android::base::Split(instance.modem_simulator_ports(), ","); + for (size_t i = 0; + i < static_cast(modem_count) && i < port_strings.size(); + ++i) { + int port = 0; + CF_EXPECT( + android::base::ParseInt(port_strings[i], &port), + "Failed to parse modem simulator port: " << port_strings[i]); + + auto vsock = SharedFD::VsockServer( + port, SOCK_STREAM, + instance.vhost_user_vsock() + ? std::make_optional(instance.vsock_guest_cid()) + : std::nullopt); + CF_EXPECT(vsock->IsOpen(), vsock->StrError() + << " (try `cvd reset`, or `pkill " + "run_cvd` and `pkill crosvm`)"); + + Chip chip("CELLULAR"); + chip.vsock_fd = vsock; + 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.cpp b/base/cvd/cuttlefish/host/libs/config/cuttlefish_config.cpp index a784dad5769..eb8d84e2185 100644 --- a/base/cvd/cuttlefish/host/libs/config/cuttlefish_config.cpp +++ b/base/cvd/cuttlefish/host/libs/config/cuttlefish_config.cpp @@ -270,22 +270,6 @@ int CuttlefishConfig::casimir_rf_port() const { return (*dictionary_)[kCasimirRfPort].asInt(); } -static constexpr char kNetsimRadios[] = "netsim_radios"; - -void CuttlefishConfig::netsim_radio_enable(NetsimRadio flag) { - if (dictionary_->isMember(kNetsimRadios)) { - // OR the radio to current set of radios - (*dictionary_)[kNetsimRadios] = - (*dictionary_)[kNetsimRadios].asInt() | flag; - } else { - (*dictionary_)[kNetsimRadios] = flag; - } -} - -bool CuttlefishConfig::netsim_radio_enabled(NetsimRadio flag) const { - return (*dictionary_)[kNetsimRadios].asInt() & flag; -} - static constexpr char kNetsimInstanceNum[] = "netsim_instance_num"; int CuttlefishConfig::netsim_instance_num() const { return (*dictionary_)[kNetsimInstanceNum].asInt(); diff --git a/base/cvd/cuttlefish/host/libs/config/cuttlefish_config.h b/base/cvd/cuttlefish/host/libs/config/cuttlefish_config.h index 0a667ab4473..4c40c4c788d 100644 --- a/base/cvd/cuttlefish/host/libs/config/cuttlefish_config.h +++ b/base/cvd/cuttlefish/host/libs/config/cuttlefish_config.h @@ -155,16 +155,6 @@ class CuttlefishConfig { void set_casimir_rf_port(int port); int casimir_rf_port() const; - // Flags for the set of radios that are connected to netsim - enum NetsimRadio { - Bluetooth = 0b00000001, - Wifi = 0b00000010, - Uwb = 0b00000100, - Nfc = 0b00001000, - }; - - void netsim_radio_enable(NetsimRadio flag); - bool netsim_radio_enabled(NetsimRadio flag) const; void set_netsim_instance_num(int netsim_instance_num); int netsim_instance_num() const; // Netsim has a built-in connector to forward packets to another daemon based @@ -512,6 +502,7 @@ class CuttlefishConfig { // Configuration flags for a minimal device bool enable_minimal_mode() const; bool enable_modem_simulator() const; + bool enable_modem_netsim() const; int modem_simulator_instance_number() const; int modem_simulator_sim_type() const; @@ -747,6 +738,7 @@ class CuttlefishConfig { // Configuration flags for a minimal device void set_enable_minimal_mode(bool enable_minimal_mode); void set_enable_modem_simulator(bool enable_modem_simulator); + void set_enable_modem_netsim(bool enable); void set_modem_simulator_instance_number(int instance_numbers); void set_modem_simulator_sim_type(int sim_type); 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 90742f64183..201d99e9ab4 100644 --- a/base/cvd/cuttlefish/host/libs/config/cuttlefish_config_instance.cpp +++ b/base/cvd/cuttlefish/host/libs/config/cuttlefish_config_instance.cpp @@ -1376,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)); }