use super::*;
pub type ScanResults = Arc<Vec<ScanResult>>;
#[derive(Debug)]
pub enum SelectResult {
Success,
WrongPsk,
NotFound,
PendingSelect,
InvalidNetworkId,
Timeout,
AlreadyConnected,
}
use std::fmt;
impl fmt::Display for SelectResult {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let s = match self {
SelectResult::Success => "success",
SelectResult::WrongPsk => "wrong_psk",
SelectResult::NotFound => "network_not_found",
SelectResult::PendingSelect => "select_already_pending",
SelectResult::InvalidNetworkId => "invalid_network_id",
SelectResult::Timeout => "select_timeout",
SelectResult::AlreadyConnected => "already_connected",
};
write!(f, "{s}")
}
}
#[derive(Debug)]
pub(crate) enum Request {
Custom(String, oneshot::Sender<Result<String>>),
Status(oneshot::Sender<Result<Status>>),
Networks(oneshot::Sender<Result<Vec<NetworkResult>>>),
Scan(oneshot::Sender<Result<ScanResults>>),
AddNetwork(oneshot::Sender<Result<usize>>),
SetNetwork(usize, SetNetwork, oneshot::Sender<Result>),
SaveConfig(oneshot::Sender<Result>),
RemoveNetwork(usize, oneshot::Sender<Result>),
RemoveAllNetworks(oneshot::Sender<Result>),
SelectNetwork(usize, oneshot::Sender<Result<SelectResult>>),
Shutdown,
SelectTimeout,
}
impl ShutdownSignal for Request {
fn is_shutdown(&self) -> bool {
matches!(self, Request::Shutdown)
}
fn inform_of_shutdown(self) {
match self {
Request::Custom(_, response) => {
let _ = response.send(Err(error::Error::StartupAborted));
}
Request::Status(response) => {
let _ = response.send(Err(error::Error::StartupAborted));
}
Request::Networks(response) => {
let _ = response.send(Err(error::Error::StartupAborted));
}
Request::Scan(response) => {
let _ = response.send(Err(error::Error::StartupAborted));
}
Request::AddNetwork(response) => {
let _ = response.send(Err(error::Error::StartupAborted));
}
Request::SetNetwork(_, _, response) => {
let _ = response.send(Err(error::Error::StartupAborted));
}
Request::SaveConfig(response) => {
let _ = response.send(Err(error::Error::StartupAborted));
}
Request::RemoveNetwork(_, response) => {
let _ = response.send(Err(error::Error::StartupAborted));
}
Request::RemoveAllNetworks(response) => {
let _ = response.send(Err(error::Error::StartupAborted));
}
Request::SelectNetwork(_, response) => {
let _ = response.send(Err(error::Error::StartupAborted));
}
Request::Shutdown => {}
Request::SelectTimeout => {}
}
}
}
#[derive(Debug)]
pub(crate) enum SetNetwork {
Ssid(String),
Bssid(String),
Psk(String),
KeyMgmt(KeyMgmt),
}
#[derive(Clone)]
pub struct RequestClient {
sender: mpsc::Sender<Request>,
}
impl RequestClient {
pub(crate) fn new(sender: mpsc::Sender<Request>) -> RequestClient {
RequestClient { sender }
}
async fn send_request(&self, request: Request) -> Result {
self.sender
.send(request)
.await
.map_err(|_| error::Error::WifiStationRequestChannelClosed)?;
Ok(())
}
pub async fn send_custom(&self, custom: String) -> Result<String> {
let (response, request) = oneshot::channel();
self.send_request(Request::Custom(custom, response)).await?;
request.await?
}
pub async fn get_scan(&self) -> Result<Arc<Vec<ScanResult>>> {
let (response, request) = oneshot::channel();
self.send_request(Request::Scan(response)).await?;
request.await?
}
pub async fn get_networks(&self) -> Result<Vec<NetworkResult>> {
let (response, request) = oneshot::channel();
self.send_request(Request::Networks(response)).await?;
request.await?
}
pub async fn get_status(&self) -> Result<Status> {
let (response, request) = oneshot::channel();
self.send_request(Request::Status(response)).await?;
request.await?
}
pub async fn add_network(&self) -> Result<usize> {
let (response, request) = oneshot::channel();
self.send_request(Request::AddNetwork(response)).await?;
request.await?
}
pub async fn set_network_psk(&self, network_id: usize, psk: String) -> Result {
let (response, request) = oneshot::channel();
self.send_request(Request::SetNetwork(
network_id,
SetNetwork::Psk(psk),
response,
))
.await?;
request.await?
}
pub async fn set_network_ssid(&self, network_id: usize, ssid: String) -> Result {
let (response, request) = oneshot::channel();
self.send_request(Request::SetNetwork(
network_id,
SetNetwork::Ssid(ssid),
response,
))
.await?;
request.await?
}
pub async fn set_network_bssid(&self, network_id: usize, bssid: String) -> Result {
let (response, request) = oneshot::channel();
self.send_request(Request::SetNetwork(
network_id,
SetNetwork::Bssid(bssid),
response,
))
.await?;
request.await?
}
pub async fn set_network_keymgmt(&self, network_id: usize, mgmt: KeyMgmt) -> Result {
let (response, request) = oneshot::channel();
self.send_request(Request::SetNetwork(
network_id,
SetNetwork::KeyMgmt(mgmt),
response,
))
.await?;
request.await?
}
pub async fn save_config(&self) -> Result {
let (response, request) = oneshot::channel();
self.send_request(Request::SaveConfig(response)).await?;
request.await?
}
pub async fn remove_network(&self, network_id: usize) -> Result {
let (response, request) = oneshot::channel();
self.send_request(Request::RemoveNetwork(network_id, response))
.await?;
request.await?
}
pub async fn remove_all_networks(&self) -> Result {
let (response, request) = oneshot::channel();
self.send_request(Request::RemoveAllNetworks(response))
.await?;
request.await?
}
pub async fn select_network(&self, network_id: usize) -> Result<SelectResult> {
let (response, request) = oneshot::channel();
self.send_request(Request::SelectNetwork(network_id, response))
.await?;
request.await?
}
pub async fn shutdown(&self) -> Result {
self.send_request(Request::Shutdown).await?;
Ok(())
}
}
#[derive(Debug, Clone)]
pub enum Broadcast {
Connected,
Disconnected,
NetworkNotFound,
WrongPsk,
Ready,
Unknown(String),
}
pub type BroadcastReceiver = broadcast::Receiver<Broadcast>;