Implement wifi options route

This commit is contained in:
takotori 2023-12-02 15:17:20 +01:00 committed by Fabio Lenherr / DashieTM
parent 1578fc3dac
commit 2e034f848e
10 changed files with 326 additions and 75 deletions

View file

@ -32,7 +32,7 @@ impl WifiAddressEntry {
entryImp.resetAddressAddress.set_text(&*address.address);
entryImp.resetAddressPrefix.set_text(&*address.prefix_length.to_string());
entryImp.resetAddressRow.set_title(&format!("{}, {}", &*address.address, address.prefix_length));
entryImp.resetAddressRow.set_title(&format!("{}/{}", &*address.address, address.prefix_length));
}
entryImp.protocol.set(protocol);
entry.setupCallbacks(conn);
@ -43,7 +43,7 @@ impl WifiAddressEntry {
let selfImp = self.imp();
let conn = connection.clone();
selfImp.resetAddressAddress.connect_changed(clone!(@weak selfImp, @weak self as what => move |entry| {
selfImp.resetAddressAddress.connect_changed(clone!(@weak selfImp => move |entry| {
let addressInput = entry.text();
let mut conn = conn.borrow_mut();
@ -57,14 +57,14 @@ impl WifiAddressEntry {
IpProtocol::IPv6 => Ipv6Addr::from_str(addressInput.as_str()).map(|a| IpAddr::V6(a)),
};
match result {
Ok(ip_addr) => {
Ok(ipAddr) => {
selfImp.resetAddressAddress.remove_css_class("error");
let addressData = match selfImp.protocol.get() {
IpProtocol::IPv4 => &mut conn.ipv4.address_data,
IpProtocol::IPv6 => &mut conn.ipv6.address_data,
};
addressData.push(Address::theBetterNew(ip_addr.to_string(), selfImp.prefix.get().1 as u32));
*selfImp.address.borrow_mut() = (true, ip_addr.to_string());
addressData.push(Address::theBetterNew(ipAddr.to_string(), selfImp.prefix.get().1 as u32));
*selfImp.address.borrow_mut() = (true, ipAddr.to_string());
}
Err(_) => {
selfImp.resetAddressAddress.add_css_class("error");
@ -98,7 +98,7 @@ impl WifiAddressEntry {
let prefix = prefix.unwrap();
match selfImp.protocol.get() {
IpProtocol::IPv4 if prefix < 32 => {
IpProtocol::IPv4 if prefix <= 32 => {
selfImp.prefix.set((true, prefix as u32));
selfImp.resetAddressPrefix.remove_css_class("error");
if let Ok(address2) = Ipv4Addr::from_str(selfImp.resetAddressAddress.text().as_str()) {
@ -108,7 +108,7 @@ impl WifiAddressEntry {
}
}
}
IpProtocol::IPv6 if prefix < 128 => {
IpProtocol::IPv6 if prefix <= 128 => {
selfImp.prefix.set((true, prefix as u32));
selfImp.resetAddressPrefix.remove_css_class("error");
if let Ok(address2) = Ipv6Addr::from_str(selfImp.resetAddressAddress.text().as_str()) {

View file

@ -6,11 +6,10 @@ use adw::glib;
use adw::glib::Object;
use adw::prelude::{ActionRowExt, ComboRowExt, PreferencesGroupExt};
use adw::subclass::prelude::ObjectSubclassIsExt;
use dbus::arg::PropMap;
use glib::{clone, closure_local, ObjectExt, PropertySet};
use glib::{clone, PropertySet};
use gtk::prelude::{ButtonExt, EditableExt, WidgetExt};
use gtk::Widget;
use ReSet_Lib::network::connection::{Connection, DNSMethod4, DNSMethod6, Enum, TypeSettings};
use IpProtocol::{IPv4, IPv6};
use crate::components::wifi::utils::IpProtocol;
use crate::components::wifi::wifiAddressEntry::WifiAddressEntry;
@ -96,34 +95,33 @@ impl WifiOptions {
}
// IPv4
for i in 0..ip4AddressLength {
let address = &WifiAddressEntry::new(Some(i), selfImp.connection.clone(), IpProtocol::IPv4);
let address = &WifiAddressEntry::new(Some(i), selfImp.connection.clone(), IPv4);
selfImp.resetIP4AddressGroup.add(address);
}
let address = &WifiAddressEntry::new(None, selfImp.connection.clone(), IpProtocol::IPv4);
let address = &WifiAddressEntry::new(None, selfImp.connection.clone(), IPv4);
selfImp.resetIP4AddressGroup.add(address);
if ip4RouteLength == 0 {
selfImp.resetIP4RoutesGroup.add(&WifiRouteEntry::new(None, selfImp.connection.clone(), IpProtocol::IPv4))
} else {
for address in 0..ip4RouteLength {
selfImp.resetIP4RoutesGroup.add(&WifiRouteEntry::new(Some(address), selfImp.connection.clone(), IpProtocol::IPv4))
}
for i in 0..ip4RouteLength {
let route = &WifiRouteEntry::new(Some(i), selfImp.connection.clone(), IPv4);
selfImp.resetIP4RoutesGroup.add(route)
}
let route = &WifiRouteEntry::new(None, selfImp.connection.clone(), IPv4);
selfImp.resetIP4RoutesGroup.add(route);
// IPv6
for address in 0..ip6AddressLength {
let address = &WifiAddressEntry::new(Some(address), selfImp.connection.clone(), IpProtocol::IPv6);
for i in 0..ip6AddressLength {
let address = &WifiAddressEntry::new(Some(i), selfImp.connection.clone(), IPv6);
selfImp.resetIP6AddressGroup.add(address);
}
let address = &WifiAddressEntry::new(None, selfImp.connection.clone(), IpProtocol::IPv6);
let address = &WifiAddressEntry::new(None, selfImp.connection.clone(), IPv6);
selfImp.resetIP6AddressGroup.add(address);
if ip6RouteLength == 0 {
selfImp.resetIP6RoutesGroup.add(&WifiRouteEntry::new(None, selfImp.connection.clone(), IpProtocol::IPv6))
} else {
for address in 0..ip6RouteLength {
selfImp.resetIP6RoutesGroup.add(&WifiRouteEntry::new(Some(address), selfImp.connection.clone(), IpProtocol::IPv6))
}
for i in 0..ip6RouteLength {
let route = &WifiRouteEntry::new(Some(i), selfImp.connection.clone(), IPv6);
selfImp.resetIP6RoutesGroup.add(route)
}
let route = &WifiRouteEntry::new(None, selfImp.connection.clone(), IPv6);
selfImp.resetIP6RoutesGroup.add(route)
// Security
}
@ -182,6 +180,7 @@ fn setupCallbacks(wifiOptions: &Arc<WifiOptions>) {
}));
imp.wifiOptionsApplyButton.connect_clicked(clone!(@weak imp => move |_| {
let prop = imp.connection.borrow().convert_to_propmap();
// todo send to daemon somehow
}));
// IPv4
let wifiOptionsIP4 = wifiOptions.clone();
@ -255,6 +254,11 @@ fn setupCallbacks(wifiOptions: &Arc<WifiOptions>) {
}
}
}));
imp.resetIP6AddressAddButton.connect_clicked(clone!(@weak imp => move |_| {
let address = &WifiAddressEntry::new(None, imp.connection.clone(), IpProtocol::IPv4);
imp.resetIP6AddressGroup.add(address);
}));
imp.resetIP6Gateway.connect_changed(clone!(@weak imp => move |entry| {
let gatewayInput = entry.text();
let mut conn = imp.connection.borrow_mut();

View file

@ -45,6 +45,8 @@ pub struct WifiOptions {
pub resetIP4AddressAddButton: TemplateChild<Button>,
#[template_child]
pub resetIP4RoutesGroup: TemplateChild<PreferencesGroup>,
#[template_child]
pub resetIP4RouteAddButton: TemplateChild<Button>,
// IPv6
#[template_child]
pub resetIP6Method: TemplateChild<ComboRow>,
@ -55,7 +57,11 @@ pub struct WifiOptions {
#[template_child]
pub resetIP6AddressGroup: TemplateChild<PreferencesGroup>,
#[template_child]
pub resetIP6AddressAddButton: TemplateChild<Button>,
#[template_child]
pub resetIP6RoutesGroup: TemplateChild<PreferencesGroup>,
#[template_child]
pub resetIP6RouteAddButton: TemplateChild<Button>,
// Security
// Misc
#[template_child]

View file

@ -1,11 +1,19 @@
use std::cell::RefCell;
use std::cell::{Ref, RefCell};
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::rc::Rc;
use std::str::FromStr;
use adw::glib;
use adw::glib::Object;
use ReSet_Lib::network::connection::{Connection};
use adw::prelude::{ExpanderRowExt, PreferencesRowExt};
use glib::clone;
use glib::subclass::prelude::ObjectSubclassIsExt;
use gtk::prelude::{EditableExt, WidgetExt};
use ReSet_Lib::network::connection::{Address, Connection};
use crate::components::wifi::utils::IpProtocol;
use crate::components::wifi::utils::IpProtocol::IPv4;
use crate::components::wifi::wifiRouteEntryImpl;
use crate::components::wifi::wifiRouteEntryImpl::WifiRouteEntryImpl;
glib::wrapper! {
pub struct WifiRouteEntry(ObjectSubclass<wifiRouteEntryImpl::WifiRouteEntryImpl>)
@ -14,24 +22,206 @@ glib::wrapper! {
}
impl WifiRouteEntry {
pub fn new(address: Option<usize>, rc: Rc<RefCell<Connection>>, protocol: IpProtocol) -> Self {
pub fn new(address: Option<usize>, conn : Rc<RefCell<Connection>>, protocol: IpProtocol) -> Self {
let entry: WifiRouteEntry = Object::builder().build();
// if let Some(address) = address {
// let entryImp = entry.imp();
// let map = address.to_map();
//
// let addr = getValueFromKey(&map, "address");
// let prefix = getValueFromKey(&map, "prefix-length");
// let gateway = getValueFromKey(&map, "gateway");
// let metric = getValueFromKey(&map, "metric");
//
// entryImp.resetRouteAddress.set_text(&addr);
// entryImp.resetRouteNetmask.set_text(&prefix);
// entryImp.resetRouteGateway.set_text(&gateway);
// entryImp.resetRouteMetric.set_text(&metric);
// entryImp.resetRouteRow.set_title(&format!("{}, {}, {}, {}", addr, prefix, gateway, metric));
// }
let entryImp = entry.imp();
if let Some(address) = address {
let conn = conn.borrow();
let address = unsafe { conn.ipv4.route_data.get_unchecked(address) };
entryImp.resetRouteAddress.set_text(&*address.address);
entryImp.resetRoutePrefix.set_text(&*address.prefix_length.to_string());
if let Some(gateway) = &address.gateway {
entryImp.resetRouteGateway.set_text(&*gateway);
}
if let Some(metric) = address.metric {
entryImp.resetRouteMetric.set_text(&*metric.to_string());
}
entryImp.resetRouteRow.set_title(&format!("{}/{}", &*address.address, address.prefix_length));
}
entryImp.protocol.set(protocol);
entry.setupCallbacks(conn);
entry
}
fn setupCallbacks(&self, connection: Rc<RefCell<Connection>>) {
let selfImp = self.imp();
let conn = connection.clone();
selfImp.resetRouteAddress.connect_changed(clone!(@weak selfImp => move |entry| {
let addressInput = entry.text();
let mut conn = conn.borrow_mut();
if addressInput.is_empty() {
selfImp.resetRouteAddress.remove_css_class("error");
selfImp.resetRouteRow.set_title("Add new address");
return;
}
let result = match selfImp.protocol.get() {
IpProtocol::IPv4 => Ipv4Addr::from_str(addressInput.as_str()).map(|a| IpAddr::V4(a)),
IpProtocol::IPv6 => Ipv6Addr::from_str(addressInput.as_str()).map(|a| IpAddr::V6(a)),
};
match result {
Ok(ipAddr) => {
selfImp.resetRouteAddress.remove_css_class("error");
let addressData = match selfImp.protocol.get() {
IpProtocol::IPv4 => &mut conn.ipv4.route_data,
IpProtocol::IPv6 => &mut conn.ipv6.route_data,
};
addressData.push(Address::new(ipAddr.to_string(), selfImp.prefix.get().1 as u32, selfImp.gateway.borrow().clone(), selfImp.metric.get()));
*selfImp.address.borrow_mut() = (true, ipAddr.to_string());
}
Err(_) => {
selfImp.resetRouteAddress.add_css_class("error");
*selfImp.address.borrow_mut() = (false, String::default());
}
}
setRowTitle(&selfImp);
}));
let conn = connection.clone();
selfImp.resetRoutePrefix.connect_changed(clone!(@weak selfImp => move |entry| {
let prefixInput = entry.text();
let prefix = prefixInput.parse::<u8>();
let mut conn = conn.borrow_mut();
let handleError = || {
if selfImp.resetRoutePrefix.text().is_empty() {
selfImp.resetRoutePrefix.remove_css_class("error");
} else {
selfImp.resetRoutePrefix.add_css_class("error");
}
selfImp.prefix.set((false, 0));
setRowTitle(&selfImp);
return;
};
if prefixInput.is_empty() || !prefix.is_ok() {
handleError();
return;
}
let prefix = prefix.unwrap();
match selfImp.protocol.get() {
IpProtocol::IPv4 if prefix <= 32 => {
selfImp.prefix.set((true, prefix as u32));
selfImp.resetRoutePrefix.remove_css_class("error");
if let Ok(address2) = Ipv4Addr::from_str(selfImp.resetRouteAddress.text().as_str()) {
if let Some(addr) = conn.ipv4.route_data.iter_mut()
.find(|connAddr| *connAddr.address == address2.to_string()) {
addr.prefix_length = prefix as u32;
}
}
}
IpProtocol::IPv6 if prefix <= 128 => {
selfImp.prefix.set((true, prefix as u32));
selfImp.resetRoutePrefix.remove_css_class("error");
if let Ok(address2) = Ipv6Addr::from_str(selfImp.resetRouteAddress.text().as_str()) {
if let Some(addr) = conn.ipv6.route_data.iter_mut()
.find(|connAddr| *connAddr.address == address2.to_string()) {
addr.prefix_length = prefix as u32;
}
}
}
_ => handleError()
}
setRowTitle(&selfImp);
}));
let conn = connection.clone();
selfImp.resetRouteGateway.connect_changed(clone!(@weak selfImp => move |entry| {
let gatewayInput = entry.text();
let mut conn = conn.borrow_mut();
if gatewayInput.is_empty() {
selfImp.resetRouteGateway.remove_css_class("error");
*selfImp.gateway.borrow_mut() = None;
setRowSubtitle(&selfImp);
return;
}
let result = match selfImp.protocol.get() {
IpProtocol::IPv4 => Ipv4Addr::from_str(gatewayInput.as_str()).map(|a| IpAddr::V4(a)),
IpProtocol::IPv6 => Ipv6Addr::from_str(gatewayInput.as_str()).map(|a| IpAddr::V6(a)),
};
match result {
Ok(ipAddr) => {
selfImp.resetRouteGateway.remove_css_class("error");
let addressData = match selfImp.protocol.get() {
IpProtocol::IPv4 => &mut conn.ipv4.route_data,
IpProtocol::IPv6 => &mut conn.ipv6.route_data,
};
if let Some(address) = addressData.iter_mut()
.find(|connAddr| *connAddr.address == selfImp.resetRouteAddress.text()) {
address.gateway = Some(ipAddr.to_string());
}
*selfImp.gateway.borrow_mut() = Some(ipAddr.to_string());
}
Err(_) => {
selfImp.resetRouteGateway.add_css_class("error");
*selfImp.gateway.borrow_mut() = None;
}
}
setRowSubtitle(&selfImp);
}));
let conn = connection.clone();
selfImp.resetRouteMetric.connect_changed(clone!(@weak selfImp => move |entry| {
let metricInput = entry.text();
let mut conn = conn.borrow_mut();
if metricInput.is_empty() {
selfImp.resetRouteMetric.remove_css_class("error");
selfImp.metric.set(None);
setRowSubtitle(&selfImp);
return;
}
let result = metricInput.parse::<u32>();
match result {
Ok(metric) => {
selfImp.resetRouteMetric.remove_css_class("error");
let addressData = match selfImp.protocol.get() {
IpProtocol::IPv4 => &mut conn.ipv4.route_data,
IpProtocol::IPv6 => &mut conn.ipv6.route_data,
};
if let Some(address) = addressData.iter_mut()
.find(|connAddr| *connAddr.address == selfImp.resetRouteAddress.text()) {
address.metric = Some(metric);
}
selfImp.metric.set(Some(metric));
}
Err(_) => {
selfImp.resetRouteMetric.add_css_class("error");
selfImp.metric.set(None);
}
}
setRowSubtitle(&selfImp);
}));
}
}
fn setRowTitle(selfImp: &WifiRouteEntryImpl) {
if selfImp.resetRouteAddress.text().is_empty() { return; }
let address = selfImp.address.borrow();
let prefix = selfImp.prefix.get();
let title = match (address.0, prefix.0) {
(true, true) => { format!("{}/{}", address.1, prefix.1) },
(true, false) => "Prefix wrong".to_string(),
(false, true) => "Address wrong".to_string(),
(false, false) => "Address and Prefix wrong".to_string(),
};
selfImp.resetRouteRow.set_title(&*title);
}
fn setRowSubtitle(selfImp: &WifiRouteEntryImpl) {
let gateway = selfImp.gateway.borrow().clone();
let metric = selfImp.metric.get();
let title = match (gateway, metric) {
(Some(gateway), Some(metric)) => { format!("{}, {}", gateway, metric) },
(Some(gateway), None) => gateway,
(None, Some(metric)) => metric.to_string(),
(None, None) => String::default(),
};
selfImp.resetRouteRow.set_subtitle(&*title);
}

View file

@ -1,7 +1,9 @@
use std::cell::{Cell, RefCell};
use crate::components::wifi::wifiRouteEntry;
use adw::{EntryRow, ExpanderRow};
use gtk::subclass::prelude::*;
use gtk::{glib, Button, CompositeTemplate};
use crate::components::wifi::utils::IpProtocol;
#[allow(non_snake_case)]
#[derive(Default, CompositeTemplate)]
@ -12,13 +14,18 @@ pub struct WifiRouteEntryImpl {
#[template_child]
pub resetRouteAddress: TemplateChild<EntryRow>,
#[template_child]
pub resetRouteNetmask: TemplateChild<EntryRow>,
pub resetRoutePrefix: TemplateChild<EntryRow>,
#[template_child]
pub resetRouteGateway: TemplateChild<EntryRow>,
#[template_child]
pub resetRouteMetric: TemplateChild<EntryRow>,
#[template_child]
pub resetRouteRemove: TemplateChild<Button>,
pub address: RefCell<(bool, String)>,
pub prefix: Cell<(bool, u32)>,
pub gateway: RefCell<Option<String>>,
pub metric: Cell<Option<u32>>,
pub protocol: Cell<IpProtocol>,
}
#[glib::object_subclass]