Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add: ModifyDevice method and change ip option #17

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 63 additions & 1 deletion src/device/manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize};
use std::{
collections::{hash_map::DefaultHasher, HashMap},
hash::{Hash, Hasher},
net::{Ipv4Addr, SocketAddrV4},
net::{Ipv4Addr, SocketAddrV4, UdpSocket},
ops::Deref,
};
use tokio::sync::{mpsc, oneshot};
Expand Down Expand Up @@ -157,10 +157,22 @@ pub enum Request {
Search,
Ping(DeviceRequestStruct),
GetDeviceHandler(UuidWrapper),
ModifyDevice(ModifyDevice),
EnableContinuousMode(UuidWrapper),
DisableContinuousMode(UuidWrapper),
}

#[derive(Debug, Clone, Serialize, Deserialize, Apiv2Schema)]
pub enum ModifyDeviceCommand {
Ip(Ipv4Addr),
}

#[derive(Debug, Clone, Serialize, Deserialize, Apiv2Schema)]
pub struct ModifyDevice {
pub uuid: Uuid,
pub modify: ModifyDeviceCommand,
}

#[derive(Debug, Clone, Serialize, Deserialize, Apiv2Schema)]
pub struct UuidWrapper {
pub uuid: Uuid,
Expand Down Expand Up @@ -237,6 +249,12 @@ impl DeviceManager {
error!("DeviceManager: Failed to return GetDeviceHandler response: {e:?}");
}
}
Request::ModifyDevice(request) => {
let answer = self.modify_device(request).await;
if let Err(err) = actor_request.respond_to.send(answer) {
error!("DeviceManager: Failed to return ModifyDevice response: {err:?}");
}
}
_ => {
if let Err(e) = actor_request
.respond_to
Expand Down Expand Up @@ -519,6 +537,50 @@ impl DeviceManager {

Ok(Answer::DeviceInfo(vec![updated_device_info]))
}

pub async fn modify_device(&mut self, request: ModifyDevice) -> Result<Answer, ManagerError> {
match request.modify {
ModifyDeviceCommand::Ip(ip) => {
let device_info = self.info(request.uuid).await?;
let Answer::DeviceInfo(data) = device_info else {
return Err(ManagerError::NoDevices);
};

let Some(info) = data.first() else {
return Err(ManagerError::NoDevices);
};

let SourceSelection::UdpStream(inner) = &info.source else {
return Err(ManagerError::Other(format!(
"modify_device : invalid request for device : {request:?}"
)));
};

self.modify_device_ip(ip, inner.ip).await?;
return self.delete(request.uuid).await;
}
}
Err(ManagerError::NoDevices)
}

pub async fn modify_device_ip(
&mut self,
ip: Ipv4Addr,
destination: Ipv4Addr,
) -> Result<(), ManagerError> {
let socket =
UdpSocket::bind("0.0.0.0:0").map_err(|err| ManagerError::Other(err.to_string()))?; // Bind to any available port
socket
.set_broadcast(true)
.map_err(|err| ManagerError::Other(err.to_string()))?;

let command = format!("SetSS1IP {}", ip);

socket
.send_to(command.as_bytes(), format!("{destination}:30303"))
.map_err(|err| ManagerError::Other(err.to_string()))?;
Ok(())
}
}

impl ManagerActorHandler {
Expand Down