Skip to main content

firefly_types/
wifi.rs

1/// Wi-Fi connection status.
2#[derive(Clone, Copy, PartialEq)]
3pub enum Status {
4    /// Failed to connect to (or was disconnected from) an Access Point.
5    Disconnected(DisconnectReason),
6    /// Wifi peripheral is started but not doing anything.
7    Started,
8    /// Wifi peripheral is not started (or was stopped).
9    Stopped,
10    /// Connected to the Access Point, obtaining IP address.
11    Initializing,
12    /// IP address is obtained, ready to go.
13    Connected,
14}
15
16impl From<u8> for Status {
17    fn from(value: u8) -> Self {
18        match value {
19            252 => Self::Started,
20            253 => Self::Stopped,
21            254 => Self::Initializing,
22            255 => Self::Connected,
23            _ => Self::Disconnected(DisconnectReason::from(value)),
24        }
25    }
26}
27
28impl From<Status> for u8 {
29    fn from(value: Status) -> Self {
30        match value {
31            Status::Disconnected(r) => r.into(),
32            Status::Started => 252,
33            Status::Stopped => 253,
34            Status::Initializing => 254,
35            Status::Connected => 255,
36        }
37    }
38}
39
40#[derive(Clone, Copy, PartialEq)]
41pub enum DisconnectReason {
42    /// Unspecified reason
43    Unspecified,
44    /// Authentication expired
45    AuthExpire,
46    /// Deauthentication due to leaving
47    AuthLeave,
48    /// Disassociated due to inactivity
49    DisassocDueToInactivity,
50    /// Too many associated stations
51    AssocToomany,
52    /// Class 2 frame received from nonauthenticated STA
53    Class2FrameFromNonauthSta,
54    /// Class 3 frame received from nonassociated STA
55    Class3FrameFromNonassocSta,
56    /// Deassociated due to leaving
57    AssocLeave,
58    /// Association but not authenticated
59    AssocNotAuthed,
60    /// Disassociated due to poor power capability
61    DisassocPwrcapBad,
62    /// Disassociated due to unsupported channel
63    DisassocSupchanBad,
64    /// Disassociated due to BSS transition
65    BssTransitionDisassoc,
66    /// Invalid Information Element (IE)
67    IeInvalid,
68    /// MIC failure
69    MicFailure,
70    /// 4-way handshake timeout
71    FourWayHandshakeTimeout,
72    /// Group key update timeout
73    GroupKeyUpdateTimeout,
74    /// IE differs in 4-way handshake
75    IeIn4wayDiffers,
76    /// Invalid group cipher
77    GroupCipherInvalid,
78    /// Invalid pairwise cipher
79    PairwiseCipherInvalid,
80    /// Invalid AKMP
81    AkmpInvalid,
82    /// Unsupported RSN IE version
83    UnsuppRsnIeVersion,
84    /// Invalid RSN IE capabilities
85    InvalidRsnIeCap,
86    /// 802.1X authentication failed
87    AuthFailed,
88    /// Cipher suite rejected
89    CipherSuiteRejected,
90    /// TDLS peer unreachable
91    TdlsPeerUnreachable,
92    /// TDLS unspecified
93    TdlsUnspecified,
94    /// SSP requested disassociation
95    SspRequestedDisassoc,
96    /// No SSP roaming agreement
97    NoSspRoamingAgreement,
98    /// Bad cipher or AKM
99    BadCipherOrAkm,
100    /// Not authorized in this location
101    NotAuthorizedThisLocation,
102    /// Service change precludes TS
103    ServiceChangePercludesTs,
104    /// Unspecified Quality of Service reason
105    UnspecifiedQos,
106    /// Not enough bandwidth
107    NotEnoughBandwidth,
108    /// Missing ACKs
109    MissingAcks,
110    /// Exceeded TXOP
111    ExceededTxop,
112    /// Station leaving
113    StaLeaving,
114    /// End of Block Ack (BA)
115    EndBa,
116    /// Unknown Block Ack (BA)
117    UnknownBa,
118    /// Timeout
119    Timeout,
120    /// Peer initiated disassociation
121    PeerInitiated,
122    /// AP initiated disassociation
123    ApInitiated,
124    /// Invalid FT action frame count
125    InvalidFtActionFrameCount,
126    /// Invalid PMKID
127    InvalidPmkid,
128    /// Invalid MDE
129    InvalidMde,
130    /// Invalid FTE
131    InvalidFte,
132    /// Transmission link establishment failed
133    TransmissionLinkEstablishFailed,
134    /// Alternative channel occupied
135    AlterativeChannelOccupied,
136
137    /// Beacon timeout
138    BeaconTimeout,
139    /// No AP found
140    NoApFound,
141    /// Authentication failed
142    AuthFail,
143    /// Association failed
144    AssocFail,
145    /// Handshake timeout
146    HandshakeTimeout,
147    /// Connection failed
148    ConnectionFail,
149    /// AP TSF reset
150    ApTsfReset,
151    /// Roaming
152    Roaming,
153    /// Association comeback time too long
154    AssocComebackTimeTooLong,
155    /// SA query timeout
156    SaQueryTimeout,
157    /// No AP found with compatible security
158    NoApFoundWCompatibleSecurity,
159    /// No AP found in auth mode threshold
160    NoApFoundInAuthmodeThreshold,
161    /// No AP found in RSSI threshold
162    NoApFoundInRssiThreshold,
163}
164
165impl DisconnectReason {
166    /// Human-readable (but technical) message.
167    ///
168    /// The first letter is lowercase unless the first word is an abbreviation.
169    /// No punctuation at the end.
170    #[must_use]
171    pub const fn as_str(&self) -> &'static str {
172        match self {
173            Self::Unspecified => "unspecified reason",
174            Self::AuthExpire => "authentication expired",
175            Self::AuthLeave => "deauthentication due to leaving",
176            Self::DisassocDueToInactivity => "disassociated due to inactivity",
177            Self::AssocToomany => "too many associated stations",
178            Self::Class2FrameFromNonauthSta => "class 2 frame received from nonauthenticated STA",
179            Self::Class3FrameFromNonassocSta => "class 3 frame received from nonassociated STA",
180            Self::AssocLeave => "deassociated due to leaving",
181            Self::AssocNotAuthed => "association but not authenticated",
182            Self::DisassocPwrcapBad => "disassociated due to poor power capability",
183            Self::DisassocSupchanBad => "disassociated due to unsupported channel",
184            Self::BssTransitionDisassoc => "disassociated due to BSS transition",
185            Self::IeInvalid => "invalid Information Element (IE)",
186            Self::MicFailure => "MIC failure",
187            Self::FourWayHandshakeTimeout => "4-way handshake timeout",
188            Self::GroupKeyUpdateTimeout => "group key update timeout",
189            Self::IeIn4wayDiffers => "IE differs in 4-way handshake",
190            Self::GroupCipherInvalid => "invalid group cipher",
191            Self::PairwiseCipherInvalid => "invalid pairwise cipher",
192            Self::AkmpInvalid => "invalid AKMP",
193            Self::UnsuppRsnIeVersion => "unsupported RSN IE version",
194            Self::InvalidRsnIeCap => "invalid RSN IE capabilities",
195            Self::AuthFailed => "802.1X authentication failed",
196            Self::CipherSuiteRejected => "cipher suite rejected",
197            Self::TdlsPeerUnreachable => "TDLS peer unreachable",
198            Self::TdlsUnspecified => "TDLS unspecified",
199            Self::SspRequestedDisassoc => "SSP requested disassociation",
200            Self::NoSspRoamingAgreement => "no SSP roaming agreement",
201            Self::BadCipherOrAkm => "bad cipher or AKM",
202            Self::NotAuthorizedThisLocation => "not authorized in this location",
203            Self::ServiceChangePercludesTs => "service change precludes TS",
204            Self::UnspecifiedQos => "unspecified Quality of Service reason",
205            Self::NotEnoughBandwidth => "not enough bandwidth",
206            Self::MissingAcks => "missing ACKs",
207            Self::ExceededTxop => "exceeded TXOP",
208            Self::StaLeaving => "station leaving",
209            Self::EndBa => "end of Block Ack (BA)",
210            Self::UnknownBa => "unknown Block Ack (BA)",
211            Self::Timeout => "timeout",
212            Self::PeerInitiated => "peer initiated disassociation",
213            Self::ApInitiated => "AP initiated disassociation",
214            Self::InvalidFtActionFrameCount => "invalid FT action frame count",
215            Self::InvalidPmkid => "invalid PMKID",
216            Self::InvalidMde => "invalid MDE",
217            Self::InvalidFte => "invalid FTE",
218            Self::TransmissionLinkEstablishFailed => "transmission link establishment failed",
219            Self::AlterativeChannelOccupied => "alternative channel occupied",
220
221            Self::BeaconTimeout => "beacon timeout",
222            Self::NoApFound => "no AP found",
223            Self::AuthFail => "authentication failed",
224            Self::AssocFail => "association failed",
225            Self::HandshakeTimeout => "handshake timeout",
226            Self::ConnectionFail => "connection failed",
227            Self::ApTsfReset => "AP TSF reset",
228            Self::Roaming => "roaming",
229            Self::AssocComebackTimeTooLong => "association comeback time too long",
230            Self::SaQueryTimeout => "SA query timeout",
231            Self::NoApFoundWCompatibleSecurity => "no AP found with compatible security",
232            Self::NoApFoundInAuthmodeThreshold => "no AP found in auth mode threshold",
233            Self::NoApFoundInRssiThreshold => "no AP found in RSSI threshold",
234        }
235    }
236}
237
238impl From<u8> for DisconnectReason {
239    fn from(value: u8) -> Self {
240        // https://github.com/espressif/esp-idf/blob/master/components/esp_wifi/include/esp_wifi_types_generic.h
241        match value {
242            // 1 => Self::Unspecified,
243            2 => Self::AuthExpire,
244            3 => Self::AuthLeave,
245            4 => Self::DisassocDueToInactivity,
246            5 => Self::AssocToomany,
247            6 => Self::Class2FrameFromNonauthSta,
248            7 => Self::Class3FrameFromNonassocSta,
249            8 => Self::AssocLeave,
250            9 => Self::AssocNotAuthed,
251            10 => Self::DisassocPwrcapBad,
252            11 => Self::DisassocSupchanBad,
253            12 => Self::BssTransitionDisassoc,
254            13 => Self::IeInvalid,
255            14 => Self::MicFailure,
256            15 => Self::FourWayHandshakeTimeout,
257            16 => Self::GroupKeyUpdateTimeout,
258            17 => Self::IeIn4wayDiffers,
259            18 => Self::GroupCipherInvalid,
260            19 => Self::PairwiseCipherInvalid,
261            20 => Self::AkmpInvalid,
262            21 => Self::UnsuppRsnIeVersion,
263            22 => Self::InvalidRsnIeCap,
264            23 => Self::AuthFailed,
265            24 => Self::CipherSuiteRejected,
266            25 => Self::TdlsPeerUnreachable,
267            26 => Self::TdlsUnspecified,
268            27 => Self::SspRequestedDisassoc,
269            28 => Self::NoSspRoamingAgreement,
270            29 => Self::BadCipherOrAkm,
271            30 => Self::NotAuthorizedThisLocation,
272            31 => Self::ServiceChangePercludesTs,
273            32 => Self::UnspecifiedQos,
274            33 => Self::NotEnoughBandwidth,
275            34 => Self::MissingAcks,
276            35 => Self::ExceededTxop,
277            36 => Self::StaLeaving,
278            37 => Self::EndBa,
279            38 => Self::UnknownBa,
280            39 => Self::Timeout,
281            46 => Self::PeerInitiated,
282            47 => Self::ApInitiated,
283            48 => Self::InvalidFtActionFrameCount,
284            49 => Self::InvalidPmkid,
285            50 => Self::InvalidMde,
286            51 => Self::InvalidFte,
287            67 => Self::TransmissionLinkEstablishFailed,
288            68 => Self::AlterativeChannelOccupied,
289            200 => Self::BeaconTimeout,
290            201 => Self::NoApFound,
291            202 => Self::AuthFail,
292            203 => Self::AssocFail,
293            204 => Self::HandshakeTimeout,
294            205 => Self::ConnectionFail,
295            206 => Self::ApTsfReset,
296            207 => Self::Roaming,
297            208 => Self::AssocComebackTimeTooLong,
298            209 => Self::SaQueryTimeout,
299            210 => Self::NoApFoundWCompatibleSecurity,
300            211 => Self::NoApFoundInAuthmodeThreshold,
301            212 => Self::NoApFoundInRssiThreshold,
302            _ => Self::Unspecified,
303        }
304    }
305}
306
307impl From<DisconnectReason> for u8 {
308    fn from(value: DisconnectReason) -> Self {
309        match value {
310            DisconnectReason::Unspecified => 1,
311            DisconnectReason::AuthExpire => 2,
312            DisconnectReason::AuthLeave => 3,
313            DisconnectReason::DisassocDueToInactivity => 4,
314            DisconnectReason::AssocToomany => 5,
315            DisconnectReason::Class2FrameFromNonauthSta => 6,
316            DisconnectReason::Class3FrameFromNonassocSta => 7,
317            DisconnectReason::AssocLeave => 8,
318            DisconnectReason::AssocNotAuthed => 9,
319            DisconnectReason::DisassocPwrcapBad => 10,
320            DisconnectReason::DisassocSupchanBad => 11,
321            DisconnectReason::BssTransitionDisassoc => 12,
322            DisconnectReason::IeInvalid => 13,
323            DisconnectReason::MicFailure => 14,
324            DisconnectReason::FourWayHandshakeTimeout => 15,
325            DisconnectReason::GroupKeyUpdateTimeout => 16,
326            DisconnectReason::IeIn4wayDiffers => 17,
327            DisconnectReason::GroupCipherInvalid => 18,
328            DisconnectReason::PairwiseCipherInvalid => 19,
329            DisconnectReason::AkmpInvalid => 20,
330            DisconnectReason::UnsuppRsnIeVersion => 21,
331            DisconnectReason::InvalidRsnIeCap => 22,
332            DisconnectReason::AuthFailed => 23,
333            DisconnectReason::CipherSuiteRejected => 24,
334            DisconnectReason::TdlsPeerUnreachable => 25,
335            DisconnectReason::TdlsUnspecified => 26,
336            DisconnectReason::SspRequestedDisassoc => 27,
337            DisconnectReason::NoSspRoamingAgreement => 28,
338            DisconnectReason::BadCipherOrAkm => 29,
339            DisconnectReason::NotAuthorizedThisLocation => 30,
340            DisconnectReason::ServiceChangePercludesTs => 31,
341            DisconnectReason::UnspecifiedQos => 32,
342            DisconnectReason::NotEnoughBandwidth => 33,
343            DisconnectReason::MissingAcks => 34,
344            DisconnectReason::ExceededTxop => 35,
345            DisconnectReason::StaLeaving => 36,
346            DisconnectReason::EndBa => 37,
347            DisconnectReason::UnknownBa => 38,
348            DisconnectReason::Timeout => 39,
349            DisconnectReason::PeerInitiated => 46,
350            DisconnectReason::ApInitiated => 47,
351            DisconnectReason::InvalidFtActionFrameCount => 48,
352            DisconnectReason::InvalidPmkid => 49,
353            DisconnectReason::InvalidMde => 50,
354            DisconnectReason::InvalidFte => 51,
355            DisconnectReason::TransmissionLinkEstablishFailed => 67,
356            DisconnectReason::AlterativeChannelOccupied => 68,
357            DisconnectReason::BeaconTimeout => 200,
358            DisconnectReason::NoApFound => 201,
359            DisconnectReason::AuthFail => 202,
360            DisconnectReason::AssocFail => 203,
361            DisconnectReason::HandshakeTimeout => 204,
362            DisconnectReason::ConnectionFail => 205,
363            DisconnectReason::ApTsfReset => 206,
364            DisconnectReason::Roaming => 207,
365            DisconnectReason::AssocComebackTimeTooLong => 208,
366            DisconnectReason::SaQueryTimeout => 209,
367            DisconnectReason::NoApFoundWCompatibleSecurity => 210,
368            DisconnectReason::NoApFoundInAuthmodeThreshold => 211,
369            DisconnectReason::NoApFoundInRssiThreshold => 212,
370        }
371    }
372}