Skip to main content

wifi_ctrl/
error.rs

1use super::*;
2use std::convert::Infallible;
3use thiserror::Error;
4use tokio::sync::mpsc::error::SendError;
5use tokio::sync::oneshot::error::RecvError;
6
7/// Error returned by [access point](crate::ap::WifiAp::run) and [station](crate::sta::WifiStation::run) runners if there is
8/// a problem with the control socket. e.g. if `wpa_supplicant` is restarted
9#[derive(Error, Debug)]
10pub enum SocketError {
11    /// IO error from control socket
12    #[error("io error: {0}")]
13    Io(#[from] std::io::Error),
14    /// Client asked runner to shutdown
15    #[error("start-up aborted")]
16    StartupAborted,
17    /// `RequestClient` dropped without shutting down runner
18    #[error("internal client channel unexpectedly closed")]
19    ClientChannelClosed,
20    /// Timeout trying to open the control socket even after retrying
21    #[error("timeout opening socket {0}")]
22    TimeoutOpeningSocket(String),
23    /// Permission denied opening control socket
24    #[error("permission denied opening socket {0}")]
25    PermissionDeniedOpeningSocket(String),
26    /// A control command kept failing while registering the event stream, even after retrying
27    #[error("gave up retrying command {0} while attaching to event stream")]
28    AttachFailed(String),
29}
30
31/// Error returned by [access point](crate::ap::RequestClient) and [station](crate::sta::RequestClient) clients if there is
32/// a problem with the request e.g. asking to select a network you have not created a config for
33#[derive(Error, Debug, Clone)]
34pub enum ClientError {
35    /// Request failed  e.g. asking to select a network you have not created a config for
36    #[error("Supplicant reported request failed")]
37    Failed,
38    /// Error parsing the response from the socket. This is probably a bug in the [`wifi_ctrl`](crate) code.
39    #[error("error {error} parsing response: \n{failed_response}")]
40    ParsingResponse {
41        #[source]
42        error: ParseError,
43        failed_response: String,
44    },
45    /// Timeout waiting for response to request on control socket
46    #[error("timeout waiting for response")]
47    Timeout,
48    /// Request was too big to fit in a datagram, most likely seen on bad custom requests
49    #[error("Request was too big only sent {0} of {1} bytes")]
50    DidNotWriteAllBytes(usize, usize),
51    /// The control socket is not connected at the moment, reconnect and try again
52    #[error("Runner task not running")]
53    RunnerNotRunning,
54    /// A select request is already pending; wait for it to resolve before selecting again
55    #[error("Select already pending")]
56    PendingSelect,
57    /// A PSK passphrase was not 8-63 printable-ASCII characters, or contained
58    /// a double-quote, which cannot be safely encoded for wpa_supplicant
59    #[error("PSK is not a valid WPA passphrase")]
60    InvalidPsk,
61    /// A BSSID was not a well-formed `xx:xx:xx:xx:xx:xx` MAC address
62    #[error("BSSID is not a valid MAC address")]
63    InvalidBssid,
64}
65
66/// A sub error of [`ClientError`] returned when there is a problem parsing the response from
67/// the socket. This is probably a bug in the [`wifi_ctrl`](crate) code.
68#[derive(Error, Debug, Clone)]
69pub enum ParseError {
70    #[error("Didn't get expected literal \"OK\" response")]
71    NotOK,
72    #[error("error parsing config: {0}")]
73    ParseConfig(#[from] config::ConfigError),
74    #[error("error parsing int: {0}")]
75    ParseInt(#[from] std::num::ParseIntError),
76    #[error("utf8 error: {0}")]
77    Utf8Parse(#[from] std::str::Utf8Error),
78}
79
80// Needed to make TryFrom happy when it can't fail
81impl From<Infallible> for ParseError {
82    fn from(_: Infallible) -> Self {
83        unreachable!()
84    }
85}
86
87// Happens when the runner half of a request channel gets dropped
88// e.g. if it is asked to shut down, or the socket dies
89impl<T> From<SendError<T>> for ClientError {
90    fn from(_: SendError<T>) -> Self {
91        ClientError::RunnerNotRunning
92    }
93}
94
95// Happens when the runner half of a response channel gets dropped
96// e.g. if it is asked to shut down, or the socket dies
97impl From<RecvError> for ClientError {
98    fn from(_: RecvError) -> Self {
99        ClientError::RunnerNotRunning
100    }
101}