diff --git a/repos/gems/src/app/sculpt_manager/main.cc b/repos/gems/src/app/sculpt_manager/main.cc index 16167168ea..0fb89b8298 100644 --- a/repos/gems/src/app/sculpt_manager/main.cc +++ b/repos/gems/src/app/sculpt_manager/main.cc @@ -171,7 +171,9 @@ struct Sculpt::Main : Input_event_handler, void _handle_pci_devices() { _pci_devices.update(); - _pci_info.wifi_present = false; + _pci_info.wifi_present = false; + _pci_info.lan_present = true; + _pci_info.modem_present = false; _pci_devices.xml().for_each_sub_node("device", [&] (Xml_node device) { @@ -799,6 +801,11 @@ struct Sculpt::Main : Input_event_handler, _network.restart_wifi_drv_on_next_runtime_cfg(); generate_runtime_config(); + } else if (name == "usb_net") { + + _network.restart_usb_net_on_next_runtime_cfg(); + generate_runtime_config(); + } else { _runtime_state.restart(name); diff --git a/repos/gems/src/app/sculpt_manager/model/nic_target.h b/repos/gems/src/app/sculpt_manager/model/nic_target.h index 0ecd282262..712533aca6 100644 --- a/repos/gems/src/app/sculpt_manager/model/nic_target.h +++ b/repos/gems/src/app/sculpt_manager/model/nic_target.h @@ -32,7 +32,7 @@ struct Sculpt::Nic_target : Noncopyable * config is provided, it takes precedence over the 'UNDEFINED' managed * state. */ - enum Type { UNDEFINED, OFF, LOCAL, WIRED, WIFI }; + enum Type { UNDEFINED, OFF, DISCONNECTED, WIRED, WIFI, MODEM }; /** * Interactive selection by the user, used when managed policy is in effect @@ -68,15 +68,17 @@ struct Sculpt::Nic_target : Noncopyable return (result == UNDEFINED) ? OFF : result; } - bool local() const { return type() == LOCAL; } + bool local() const { return type() == DISCONNECTED; } bool wired() const { return type() == WIRED; } bool wifi() const { return type() == WIFI; } + bool modem() const { return type() == MODEM; } bool nic_router_needed() const { return type() != OFF; } bool ready() const { return type() == WIRED || type() == WIFI || - type() == LOCAL; } + type() == MODEM || + type() == DISCONNECTED; } }; #endif /* _MODEL__NIC_TARGET_H_ */ diff --git a/repos/gems/src/app/sculpt_manager/model/pci_info.h b/repos/gems/src/app/sculpt_manager/model/pci_info.h index e36b59e6f7..19b2b8977c 100644 --- a/repos/gems/src/app/sculpt_manager/model/pci_info.h +++ b/repos/gems/src/app/sculpt_manager/model/pci_info.h @@ -20,7 +20,9 @@ namespace Sculpt { struct Pci_info; } struct Sculpt::Pci_info { - bool wifi_present = false; + bool wifi_present = false; + bool lan_present = false; + bool modem_present = false; }; #endif /* _MODEL__PCI_INFO_H_ */ diff --git a/repos/gems/src/app/sculpt_manager/network.cc b/repos/gems/src/app/sculpt_manager/network.cc index 66b9b1e0b6..b386fad5a9 100644 --- a/repos/gems/src/app/sculpt_manager/network.cc +++ b/repos/gems/src/app/sculpt_manager/network.cc @@ -80,8 +80,9 @@ void Sculpt::Network::_generate_nic_router_config() bool uplink_exists = true; switch (_nic_target.type()) { - case Nic_target::WIRED: _generate_nic_router_uplink(xml, "nic_drv -> "); break; - case Nic_target::WIFI: _generate_nic_router_uplink(xml, "wifi_drv -> "); break; + case Nic_target::WIRED: _generate_nic_router_uplink(xml, "nic_drv -> "); break; + case Nic_target::WIFI: _generate_nic_router_uplink(xml, "wifi_drv -> "); break; + case Nic_target::MODEM: _generate_nic_router_uplink(xml, "usb_net -> "); break; default: uplink_exists = false; } gen_named_node(xml, "domain", "default", [&] () { @@ -90,7 +91,7 @@ void Sculpt::Network::_generate_nic_router_config() xml.node("dhcp-server", [&] () { xml.attribute("ip_first", "10.0.1.2"); xml.attribute("ip_last", "10.0.1.200"); - if (_nic_target.type() != Nic_target::LOCAL) { + if (_nic_target.type() != Nic_target::DISCONNECTED) { xml.attribute("dns_config_from", "uplink"); } }); @@ -165,7 +166,7 @@ void Sculpt::Network::_update_nic_target_from_config(Xml_node const &config) if (!config.has_sub_node("domain")) return Nic_target::OFF; - Nic_target::Type result = Nic_target::LOCAL; + Nic_target::Type result = Nic_target::DISCONNECTED; config.for_each_sub_node("policy", [&] (Xml_node uplink) { @@ -178,6 +179,9 @@ void Sculpt::Network::_update_nic_target_from_config(Xml_node const &config) if (uplink.attribute_value("label", String<16>()) == "wifi_drv -> ") result = Nic_target::WIFI; + + if (uplink.attribute_value("label", String<16>()) == "usb_net -> ") + result = Nic_target::MODEM; }); return result; }; @@ -218,7 +222,16 @@ void Sculpt::Network::gen_runtime_start_nodes(Xml_generator &xml) const xml.node("start", [&] () { gen_nic_router_start_content(xml); }); break; - case Nic_target::LOCAL: + case Nic_target::MODEM: + + xml.node("start", [&] () { + xml.attribute("version", _usb_net_version); + gen_usb_net_start_content(xml); + }); + xml.node("start", [&] () { gen_nic_router_start_content(xml); }); + break; + + case Nic_target::DISCONNECTED: xml.node("start", [&] () { gen_nic_router_start_content(xml); }); break; diff --git a/repos/gems/src/app/sculpt_manager/network.h b/repos/gems/src/app/sculpt_manager/network.h index c30758ebc5..bfbdff0d60 100644 --- a/repos/gems/src/app/sculpt_manager/network.h +++ b/repos/gems/src/app/sculpt_manager/network.h @@ -55,8 +55,9 @@ struct Sculpt::Network : Network_dialog::Action Wpa_passphrase wpa_passphrase { }; - unsigned _nic_drv_version = 0; + unsigned _nic_drv_version = 0; unsigned _wifi_drv_version = 0; + unsigned _usb_net_version = 0; Attached_rom_dataspace _wlan_accesspoints_rom { _env, "report -> runtime/wifi_drv/accesspoints" }; @@ -174,15 +175,9 @@ struct Sculpt::Network : Network_dialog::Action }); } - void restart_nic_drv_on_next_runtime_cfg() - { - _nic_drv_version++; - } - - void restart_wifi_drv_on_next_runtime_cfg() - { - _wifi_drv_version++; - } + void restart_nic_drv_on_next_runtime_cfg() { _nic_drv_version++; } + void restart_wifi_drv_on_next_runtime_cfg() { _wifi_drv_version++; } + void restart_usb_net_on_next_runtime_cfg() { _usb_net_version++; } void wifi_disconnect() override { diff --git a/repos/gems/src/app/sculpt_manager/runtime.cc b/repos/gems/src/app/sculpt_manager/runtime.cc index 2e9f767aaf..d1455a6035 100644 --- a/repos/gems/src/app/sculpt_manager/runtime.cc +++ b/repos/gems/src/app/sculpt_manager/runtime.cc @@ -30,3 +30,4 @@ #include #include #include +#include diff --git a/repos/gems/src/app/sculpt_manager/runtime.h b/repos/gems/src/app/sculpt_manager/runtime.h index e61cc092d1..837c920109 100644 --- a/repos/gems/src/app/sculpt_manager/runtime.h +++ b/repos/gems/src/app/sculpt_manager/runtime.h @@ -71,6 +71,7 @@ namespace Sculpt { void gen_nic_drv_start_content(Xml_generator &); void gen_wifi_drv_start_content(Xml_generator &); + void gen_usb_net_start_content(Xml_generator &); void gen_nic_router_start_content(Xml_generator &); void gen_nic_router_uplink(Xml_generator &, char const *); diff --git a/repos/gems/src/app/sculpt_manager/runtime/usb_net.cc b/repos/gems/src/app/sculpt_manager/runtime/usb_net.cc new file mode 100644 index 0000000000..5f8c5810ab --- /dev/null +++ b/repos/gems/src/app/sculpt_manager/runtime/usb_net.cc @@ -0,0 +1,52 @@ +/* + * \brief XML configuration for USB network driver + * \author Norman Feske + * \date 2022-08-24 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#include + +void Sculpt::gen_usb_net_start_content(Xml_generator &xml) +{ + gen_common_start_content(xml, "usb_net", + Cap_quota{200}, Ram_quota{20*1024*1024}, + Priority::NETWORK); + + xml.node("binary", [&] () { + xml.attribute("name", "usb_net_drv"); + }); + + xml.node("config", [&] () { + xml.attribute("mac", "02:00:00:00:01:05"); + }); + + xml.node("route", [&] () { + + xml.node("service", [&] () { + xml.attribute("name", "Uplink"); + xml.node("child", [&] () { + xml.attribute("name", "nic_router"); + xml.attribute("label", "usb_net -> "); + }); + }); + + gen_service_node(xml, [&] () { + xml.node("parent", [&] () { + xml.attribute("label", "usb_net"); }); }); + + gen_parent_rom_route(xml, "usb_net_drv"); + gen_parent_rom_route(xml, "ld.lib.so"); + gen_parent_route (xml); + gen_parent_route (xml); + gen_parent_route (xml); + gen_parent_route (xml); + gen_parent_route(xml); + }); +} diff --git a/repos/gems/src/app/sculpt_manager/view/network_dialog.cc b/repos/gems/src/app/sculpt_manager/view/network_dialog.cc index 49bd64b578..3e1b0baa38 100644 --- a/repos/gems/src/app/sculpt_manager/view/network_dialog.cc +++ b/repos/gems/src/app/sculpt_manager/view/network_dialog.cc @@ -211,7 +211,7 @@ void Network_dialog::generate(Xml_generator &xml) const auto gen_nic_button = [&] (Hoverable_item::Id const &id, Nic_target::Type const type, - String<10> const &label) { + String<20> const &label) { gen_named_node(xml, "button", id, [&] () { _nic_item.gen_button_attr(xml, id); @@ -229,18 +229,23 @@ void Network_dialog::generate(Xml_generator &xml) const * Allow interactive selection only if NIC-router configuration * is not manually maintained. */ - if (_nic_target.managed() || _nic_target.manual_type == Nic_target::LOCAL) - gen_nic_button("local", Nic_target::LOCAL, "Local"); + if (_nic_target.managed() || _nic_target.manual_type == Nic_target::DISCONNECTED) + gen_nic_button("disconnected", Nic_target::DISCONNECTED, "Disconnected"); if (_nic_target.managed() || _nic_target.manual_type == Nic_target::WIRED) - gen_nic_button("wired", Nic_target::WIRED, "Wired"); + if (_pci_info.lan_present) + gen_nic_button("wired", Nic_target::WIRED, "Wired"); if (_nic_target.managed() || _nic_target.manual_type == Nic_target::WIFI) if (_pci_info.wifi_present) gen_nic_button("wifi", Nic_target::WIFI, "Wifi"); + + if (_nic_target.managed() || _nic_target.manual_type == Nic_target::MODEM) + if (_pci_info.modem_present) + gen_nic_button("modem", Nic_target::MODEM, "Mobile data"); }); - if (_nic_target.wifi() || _nic_target.wired()) { + if (_nic_target.wifi() || _nic_target.wired() || _nic_target.modem()) { gen_named_node(xml, "frame", "nic_info", [&] () { xml.node("vbox", [&] () { @@ -287,10 +292,11 @@ Dialog::Hover_result Network_dialog::hover(Xml_node hover) void Network_dialog::click(Action &action) { - if (_nic_item.hovered("off")) action.nic_target(Nic_target::OFF); - if (_nic_item.hovered("local")) action.nic_target(Nic_target::LOCAL); - if (_nic_item.hovered("wired")) action.nic_target(Nic_target::WIRED); - if (_nic_item.hovered("wifi")) action.nic_target(Nic_target::WIFI); + if (_nic_item.hovered("off")) action.nic_target(Nic_target::OFF); + if (_nic_item.hovered("disconnected")) action.nic_target(Nic_target::DISCONNECTED); + if (_nic_item.hovered("wired")) action.nic_target(Nic_target::WIRED); + if (_nic_item.hovered("wifi")) action.nic_target(Nic_target::WIFI); + if (_nic_item.hovered("modem")) action.nic_target(Nic_target::MODEM); if (_wifi_connection.connected() && _ap_item.hovered(_wifi_connection.bssid)) { action.wifi_disconnect();