wip: handle state after activating connections
This commit is contained in:
parent
cdca1d96ac
commit
6b5ce0f35f
3 changed files with 184 additions and 34 deletions
|
|
@ -38,6 +38,7 @@ pub fn run() -> cosmic::iced::Result {
|
||||||
CosmicNetworkApplet::run(helper.window_settings())
|
CosmicNetworkApplet::run(helper.window_settings())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
enum NewConnectionState {
|
enum NewConnectionState {
|
||||||
EnterPassword {
|
EnterPassword {
|
||||||
access_point: AccessPoint,
|
access_point: AccessPoint,
|
||||||
|
|
@ -216,19 +217,61 @@ impl Application for CosmicNetworkApplet {
|
||||||
airplane_mode,
|
airplane_mode,
|
||||||
},
|
},
|
||||||
success,
|
success,
|
||||||
..
|
req,
|
||||||
} => {
|
} => {
|
||||||
if success {
|
if success {
|
||||||
|
match req {
|
||||||
|
NetworkManagerRequest::SetAirplaneMode(_)
|
||||||
|
| NetworkManagerRequest::SetWiFi(_) => {}
|
||||||
|
NetworkManagerRequest::SelectAccessPoint(_)
|
||||||
|
| NetworkManagerRequest::Password(_, _) => {
|
||||||
|
self.new_connection.take();
|
||||||
|
self.show_visible_networks = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
self.wireless_access_points = wireless_access_points;
|
self.wireless_access_points = wireless_access_points;
|
||||||
self.active_conns = active_conns;
|
self.active_conns = active_conns;
|
||||||
self.known_access_points = known_access_points;
|
self.known_access_points = known_access_points;
|
||||||
self.airplane_mode = airplane_mode;
|
self.airplane_mode = airplane_mode;
|
||||||
self.wifi = wifi_enabled;
|
self.wifi = wifi_enabled;
|
||||||
self.update_icon_name();
|
self.update_icon_name();
|
||||||
|
} else {
|
||||||
|
match req {
|
||||||
|
NetworkManagerRequest::SetAirplaneMode(_)
|
||||||
|
| NetworkManagerRequest::SetWiFi(_) => {}
|
||||||
|
NetworkManagerRequest::SelectAccessPoint(_) => {
|
||||||
|
if let Some(NewConnectionState::Waiting(access_point)) =
|
||||||
|
self.new_connection.as_ref()
|
||||||
|
{
|
||||||
|
self.new_connection
|
||||||
|
.replace(NewConnectionState::Failure(access_point.clone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NetworkManagerRequest::Password(_, _) => {
|
||||||
|
if let Some(NewConnectionState::EnterPassword {
|
||||||
|
access_point,
|
||||||
|
..
|
||||||
|
}) = self.new_connection.as_ref()
|
||||||
|
{
|
||||||
|
self.new_connection
|
||||||
|
.replace(NewConnectionState::Failure(access_point.clone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Message::SelectWirelessAccessPoint(access_point) => {
|
Message::SelectWirelessAccessPoint(access_point) => {
|
||||||
|
let tx = if let Some(tx) = self.nm_sender.as_ref() {
|
||||||
|
tx
|
||||||
|
} else {
|
||||||
|
return Command::none();
|
||||||
|
};
|
||||||
|
|
||||||
|
let _ = tx.unbounded_send(NetworkManagerRequest::SelectAccessPoint(
|
||||||
|
access_point.ssid.clone(),
|
||||||
|
));
|
||||||
|
|
||||||
self.new_connection
|
self.new_connection
|
||||||
.replace(NewConnectionState::EnterPassword {
|
.replace(NewConnectionState::EnterPassword {
|
||||||
access_point,
|
access_point,
|
||||||
|
|
@ -263,12 +306,19 @@ impl Application for CosmicNetworkApplet {
|
||||||
password.to_string(),
|
password.to_string(),
|
||||||
));
|
));
|
||||||
self.new_connection
|
self.new_connection
|
||||||
.replace(NewConnectionState::Failure(access_point.clone()));
|
.replace(NewConnectionState::Waiting(access_point.clone()));
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Message::ActivateKnownWifi(ssid) => {}
|
Message::ActivateKnownWifi(ssid) => {
|
||||||
|
let tx = if let Some(tx) = self.nm_sender.as_ref() {
|
||||||
|
tx
|
||||||
|
} else {
|
||||||
|
return Command::none();
|
||||||
|
};
|
||||||
|
let _ = tx.unbounded_send(NetworkManagerRequest::SelectAccessPoint(ssid));
|
||||||
|
}
|
||||||
Message::CancelNewConnection => {
|
Message::CancelNewConnection => {
|
||||||
self.new_connection.take();
|
self.new_connection.take();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@ pub async fn handle_wireless_device(device: WirelessDevice<'_>) -> zbus::Result<
|
||||||
for ap in access_points {
|
for ap in access_points {
|
||||||
let ssid = String::from_utf8_lossy(&ap.ssid().await?.clone()).into_owned();
|
let ssid = String::from_utf8_lossy(&ap.ssid().await?.clone()).into_owned();
|
||||||
let strength = ap.strength().await?;
|
let strength = ap.strength().await?;
|
||||||
|
|
||||||
if let Some(access_point) = aps.get(&ssid) {
|
if let Some(access_point) = aps.get(&ssid) {
|
||||||
if access_point.strength > strength {
|
if access_point.strength > strength {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,12 @@ use std::{collections::HashMap, fmt::Debug, hash::Hash, ops::Deref, time::Durati
|
||||||
|
|
||||||
use cosmic::iced::{self, subscription};
|
use cosmic::iced::{self, subscription};
|
||||||
use cosmic_dbus_networkmanager::{
|
use cosmic_dbus_networkmanager::{
|
||||||
|
active_connection::ActiveConnection,
|
||||||
device::SpecificDevice,
|
device::SpecificDevice,
|
||||||
interface::{enums::DeviceType, settings::connection::ConnectionSettingsProxy},
|
interface::{
|
||||||
|
active_connection::ActiveConnectionProxy, enums, enums::DeviceType,
|
||||||
|
settings::connection::ConnectionSettingsProxy,
|
||||||
|
},
|
||||||
nm::{self, NetworkManager},
|
nm::{self, NetworkManager},
|
||||||
settings::{
|
settings::{
|
||||||
connection::{ConnectionSettings, Secrets, Settings},
|
connection::{ConnectionSettings, Secrets, Settings},
|
||||||
|
|
@ -46,7 +50,7 @@ pub enum State {
|
||||||
Finished,
|
Finished,
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn start_listening<I: Copy>(
|
async fn start_listening<I: Copy + Debug>(
|
||||||
id: I,
|
id: I,
|
||||||
state: State,
|
state: State,
|
||||||
) -> (Option<(I, NetworkManagerEvent)>, State) {
|
) -> (Option<(I, NetworkManagerEvent)>, State) {
|
||||||
|
|
@ -135,7 +139,6 @@ async fn start_listening<I: Copy>(
|
||||||
.cloned()
|
.cloned()
|
||||||
.and_then(|ssid| ssid.try_into().ok())
|
.and_then(|ssid| ssid.try_into().ok())
|
||||||
.and_then(|ssid| String::from_utf8(ssid).ok());
|
.and_then(|ssid| String::from_utf8(ssid).ok());
|
||||||
|
|
||||||
if cur_ssid.as_ref() != Some(&ssid) {
|
if cur_ssid.as_ref() != Some(&ssid) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -144,7 +147,10 @@ async fn start_listening<I: Copy>(
|
||||||
c.get_secrets("802-11-wireless-security")
|
c.get_secrets("802-11-wireless-security")
|
||||||
.await {
|
.await {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
_ => continue,
|
_ => HashMap::from([("802-11-wireless-security".into(), HashMap::from([
|
||||||
|
("psk".into(), Value::Str(password.as_str().into()).to_owned()),
|
||||||
|
("key-mgmt".into(), Value::Str("wpa-psk".into()).to_owned())
|
||||||
|
]))]),
|
||||||
};
|
};
|
||||||
if let Some(s) = secrets.get_mut("802-11-wireless-security") {
|
if let Some(s) = secrets.get_mut("802-11-wireless-security") {
|
||||||
s.insert("psk".into(), Value::Str(password.clone().into()).to_owned());
|
s.insert("psk".into(), Value::Str(password.clone().into()).to_owned());
|
||||||
|
|
@ -156,10 +162,22 @@ async fn start_listening<I: Copy>(
|
||||||
.collect::<HashMap<_, _>>());
|
.collect::<HashMap<_, _>>());
|
||||||
map
|
map
|
||||||
}).collect();
|
}).collect();
|
||||||
dbg!(settings.clone());
|
let updated = c.update(settings).await;
|
||||||
let updated = c.update(settings).await.is_ok();
|
if updated.is_ok() {
|
||||||
if updated {
|
let success = if let Ok(path) = network_manager.deref().activate_connection(c.deref().path(), &ObjectPath::try_from("/").unwrap(), &ObjectPath::try_from("/").unwrap()).await {
|
||||||
let success = network_manager.deref().activate_connection(c.deref().path(), &ObjectPath::try_from("/").unwrap(), &ObjectPath::try_from("/").unwrap()).await.is_ok();
|
// let active_conn = ActiveConnection::from(ActiveConnectionProxy::from(conn.1));
|
||||||
|
let dummy = ActiveConnectionProxy::new(&conn).await.unwrap();
|
||||||
|
let active = ActiveConnectionProxy::builder(&conn).path(path).unwrap().destination(dummy.destination()).unwrap().interface(dummy.interface()).unwrap().build().await.unwrap();
|
||||||
|
let state = enums::ActiveConnectionState::from(active.state().await.unwrap_or_default());
|
||||||
|
let s = if let enums::ActiveConnectionState::Activating = state {
|
||||||
|
enums::ActiveConnectionState::from(active.receive_state_changed().await.next().await.unwrap().get().await.unwrap_or_default())
|
||||||
|
} else {
|
||||||
|
state
|
||||||
|
};
|
||||||
|
matches!(s, enums::ActiveConnectionState::Activated)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
status = (Some((id, NetworkManagerEvent::RequestResponse {
|
status = (Some((id, NetworkManagerEvent::RequestResponse {
|
||||||
req: NetworkManagerRequest::Password(ssid.clone(), password.clone()),
|
req: NetworkManagerRequest::Password(ssid.clone(), password.clone()),
|
||||||
success,
|
success,
|
||||||
|
|
@ -172,28 +190,43 @@ async fn start_listening<I: Copy>(
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a connection
|
// create a connection
|
||||||
for device in network_manager.devices().await.ok().unwrap_or_default() {
|
if status.0.is_none() {
|
||||||
if matches!(device.device_type().await.unwrap_or(DeviceType::Other), DeviceType::Wifi) {
|
for device in network_manager.devices().await.ok().unwrap_or_default() {
|
||||||
let conn_settings: HashMap<&str, HashMap<&str, zvariant::Value>> = HashMap::from([
|
if matches!(device.device_type().await.unwrap_or(DeviceType::Other), DeviceType::Wifi) {
|
||||||
("802-11-wireless".into(), HashMap::from([
|
let conn_settings: HashMap<&str, HashMap<&str, zvariant::Value>> = HashMap::from([
|
||||||
("ssid".into(), Value::Str(ssid.as_str().into())),
|
("802-11-wireless".into(), HashMap::from([
|
||||||
])),
|
("ssid".into(), Value::Array(ssid.as_bytes().into())),
|
||||||
("connection".into(), HashMap::from([
|
])),
|
||||||
("id".into(), Value::Str(ssid.as_str().into())),
|
("connection".into(), HashMap::from([
|
||||||
("type".into(), Value::Str("802-11-wireless".into())),
|
("id".into(), Value::Str(ssid.as_str().into())),
|
||||||
])),
|
("type".into(), Value::Str("802-11-wireless".into())),
|
||||||
("802-11-wireless-security".into(), HashMap::from([
|
])),
|
||||||
("psk".into(), Value::Str(password.as_str().into())),
|
("802-11-wireless-security".into(), HashMap::from([
|
||||||
]))
|
("psk".into(), Value::Str(password.as_str().into())),
|
||||||
]);
|
("key-mgmt".into(), Value::Str("wpa-psk".into()))
|
||||||
let success = network_manager.add_and_activate_connection(conn_settings, device.path(), &ObjectPath::try_from("/").unwrap()).await.is_ok();
|
]))
|
||||||
status = (Some((id, NetworkManagerEvent::RequestResponse {
|
]);
|
||||||
req: NetworkManagerRequest::Password(ssid.clone(), password.clone()),
|
let success = if let Ok((_, path)) = network_manager.add_and_activate_connection(conn_settings, device.path(), &ObjectPath::try_from("/").unwrap()).await {
|
||||||
success,
|
let dummy = ActiveConnectionProxy::new(&conn).await.unwrap();
|
||||||
state: NetworkManagerState::new(&conn).await.unwrap_or_default(),
|
let active = ActiveConnectionProxy::builder(&conn).path(path).unwrap().destination(dummy.destination()).unwrap().interface(dummy.interface()).unwrap().build().await.unwrap();
|
||||||
})), false);
|
let state = enums::ActiveConnectionState::from(active.state().await.unwrap_or_default());
|
||||||
|
let s = if let enums::ActiveConnectionState::Activating = state {
|
||||||
|
enums::ActiveConnectionState::from(active.receive_state_changed().await.next().await.unwrap().get().await.unwrap_or_default())
|
||||||
|
} else {
|
||||||
|
state
|
||||||
|
};
|
||||||
|
matches!(s, enums::ActiveConnectionState::Activated)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
status = (Some((id, NetworkManagerEvent::RequestResponse {
|
||||||
|
req: NetworkManagerRequest::Password(ssid.clone(), password.clone()),
|
||||||
|
success,
|
||||||
|
state: NetworkManagerState::new(&conn).await.unwrap_or_default(),
|
||||||
|
})), false);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -215,6 +248,9 @@ async fn start_listening<I: Copy>(
|
||||||
// find known connection with matching ssid and activate
|
// find known connection with matching ssid and activate
|
||||||
let mut status = (None, false);
|
let mut status = (None, false);
|
||||||
|
|
||||||
|
let devices = network_manager.devices().await.ok().unwrap_or_default();
|
||||||
|
|
||||||
|
|
||||||
for c in s.list_connections().await.unwrap_or_default() {
|
for c in s.list_connections().await.unwrap_or_default() {
|
||||||
let settings = match c.get_settings().await.ok() {
|
let settings = match c.get_settings().await.ok() {
|
||||||
Some(s) => s,
|
Some(s) => s,
|
||||||
|
|
@ -232,7 +268,20 @@ async fn start_listening<I: Copy>(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let success = network_manager.deref().activate_connection(c.deref().path(), &ObjectPath::try_from("/").unwrap(), &ObjectPath::try_from("/").unwrap()).await.is_ok();
|
let success = if let Ok(path) = network_manager.deref().activate_connection(c.deref().path(), &ObjectPath::try_from("/").unwrap(), &ObjectPath::try_from("/").unwrap()).await {
|
||||||
|
let dummy = ActiveConnectionProxy::new(&conn).await.unwrap();
|
||||||
|
let active = ActiveConnectionProxy::builder(&conn).path(path).unwrap().destination(dummy.destination()).unwrap().interface(dummy.interface()).unwrap().build().await.unwrap();
|
||||||
|
let state = enums::ActiveConnectionState::from(active.state().await.unwrap_or_default());
|
||||||
|
let s = if let enums::ActiveConnectionState::Activating = state {
|
||||||
|
enums::ActiveConnectionState::from(active.receive_state_changed().await.next().await.unwrap().get().await.unwrap_or_default())
|
||||||
|
} else {
|
||||||
|
state
|
||||||
|
};
|
||||||
|
matches!(s, enums::ActiveConnectionState::Activated)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
// dbg!(&success);
|
||||||
status = (Some((id, NetworkManagerEvent::RequestResponse {
|
status = (Some((id, NetworkManagerEvent::RequestResponse {
|
||||||
req: NetworkManagerRequest::SelectAccessPoint(ssid.clone()),
|
req: NetworkManagerRequest::SelectAccessPoint(ssid.clone()),
|
||||||
success,
|
success,
|
||||||
|
|
@ -241,6 +290,58 @@ async fn start_listening<I: Copy>(
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// dbg!(&status);
|
||||||
|
let mut ap = None;
|
||||||
|
|
||||||
|
for d in &devices {
|
||||||
|
if let Ok(Some(SpecificDevice::Wireless(wireless_device))) =
|
||||||
|
d.downcast_to_device().await {
|
||||||
|
for a in wireless_device.access_points().await.ok().unwrap_or_default() {
|
||||||
|
if String::from_utf8(a.ssid().await.unwrap_or_default()).unwrap_or_default() == ssid {
|
||||||
|
ap = Some(a);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if status.0.is_none() {
|
||||||
|
|
||||||
|
for device in network_manager.devices().await.ok().unwrap_or_default() {
|
||||||
|
if matches!(device.device_type().await.unwrap_or(DeviceType::Other), DeviceType::Wifi) {
|
||||||
|
let conn_settings: HashMap<&str, HashMap<&str, zvariant::Value>> = HashMap::from([
|
||||||
|
("802-11-wireless".into(), HashMap::from([
|
||||||
|
("ssid".into(), Value::Array(ssid.as_bytes().into())),
|
||||||
|
])),
|
||||||
|
("connection".into(), HashMap::from([
|
||||||
|
("id".into(), Value::Str(ssid.as_str().into())),
|
||||||
|
("type".into(), Value::Str("802-11-wireless".into())),
|
||||||
|
])),
|
||||||
|
]);
|
||||||
|
let success = if let Ok((_, path)) = network_manager.add_and_activate_connection(conn_settings, device.path(), &ap.as_ref().map(|ap| ap.path().clone()).unwrap_or_else(||ObjectPath::try_from("/").unwrap().into_owned())).await {
|
||||||
|
let dummy = ActiveConnectionProxy::new(&conn).await.unwrap();
|
||||||
|
let active = ActiveConnectionProxy::builder(&conn).path(path).unwrap().destination(dummy.destination()).unwrap().interface(dummy.interface()).unwrap().build().await.unwrap();
|
||||||
|
let state = enums::ActiveConnectionState::from(active.state().await.unwrap_or_default());
|
||||||
|
let s = if let enums::ActiveConnectionState::Activating = state {
|
||||||
|
enums::ActiveConnectionState::from(active.receive_state_changed().await.next().await.unwrap().get().await.unwrap_or_default())
|
||||||
|
} else {
|
||||||
|
state
|
||||||
|
};
|
||||||
|
matches!(s, enums::ActiveConnectionState::Activated)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
status = (Some((id, NetworkManagerEvent::RequestResponse {
|
||||||
|
req: NetworkManagerRequest::SelectAccessPoint(ssid.clone()),
|
||||||
|
success,
|
||||||
|
state: NetworkManagerState::new(&conn).await.unwrap_or_default(),
|
||||||
|
})), false);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// dbg!(&status);
|
||||||
|
|
||||||
if status.0.is_none() {
|
if status.0.is_none() {
|
||||||
status = (Some((id, NetworkManagerEvent::RequestResponse {
|
status = (Some((id, NetworkManagerEvent::RequestResponse {
|
||||||
req: NetworkManagerRequest::SelectAccessPoint(ssid.clone()),
|
req: NetworkManagerRequest::SelectAccessPoint(ssid.clone()),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue