1#![no_std]
2use heapless::String;
3use no_std_net::Ipv4Addr;
4
5#[macro_use]
6extern crate bitflags;
7
8mod codec;
9mod ids;
10
11#[derive(Debug, Clone, PartialEq)]
13pub enum Err<E> {
14 Parsing(nom::Err<()>),
16 CRCMismatch,
18 TXErr,
20 NotOurs,
23 RPCErr(E),
25 ResponseOverrun,
27 Unknown,
28}
29
30impl<E> From<nom::Err<()>> for Err<E> {
31 fn from(nom_err: nom::Err<()>) -> Self {
32 Err::Parsing::<E>(nom_err)
33 }
34}
35
36pub use codec::{FrameHeader, Header};
37
38pub trait RPC {
40 type ReturnValue;
41 type Error;
42
43 fn header(&self, seq: u32) -> Header;
44 fn args(&self, _buff: &mut heapless::Vec<u8, 64>) {}
45
46 fn parse(&mut self, data: &[u8]) -> Result<Self::ReturnValue, Err<Self::Error>>;
47}
48
49mod system_rpcs;
50mod tcpip_rpcs;
51mod wifi_rpcs;
52
53pub mod rpcs {
55 pub use crate::system_rpcs::*;
56 pub use crate::tcpip_rpcs::*;
57 pub use crate::wifi_rpcs::*;
58}
59
60#[derive(Debug, Clone, Copy)]
62#[repr(u32)]
63pub enum L3Interface {
64 Station = 0,
65 AP = 1,
66}
67
68#[derive(Debug, Copy, Clone)]
70#[repr(u32)]
71pub enum WifiMode {
72 None = 0,
73 Station = 1,
74 AP = 2,
75 StationAndAP = 3,
76 Promiscuous = 4,
77 P2P = 5,
78}
79
80#[derive(Debug, Copy, Clone)]
82#[allow(dead_code)]
83#[repr(u32)]
84pub enum BssType {
85 Infra = 0,
86 Adhoc = 1,
87 Any = 2,
88 Unknown = core::u32::MAX,
89}
90
91impl From<u32> for BssType {
92 fn from(orig: u32) -> Self {
93 match orig {
94 0 => return BssType::Infra,
95 1 => return BssType::Adhoc,
96 2 => return BssType::Any,
97 _ => return BssType::Unknown,
98 };
99 }
100}
101
102bitflags! {
103 pub struct Security: u32 {
105 const WEP_ENABLED = 1;
106 const TKIP_ENABLED = 2;
107 const AES_ENABLED = 4;
108 const AES_CMAC_ENABLED = 0x10;
109 const SHARED_ENABLED = 0x00008000;
110 const WPA_SECURITY = 0x00200000;
111 const WPA2_SECURITY = 0x00400000;
112 const WPA3_SECURITY = 0x00800000;
113 const WPS_ENABLED = 0x10000000;
114 const WEP_PSK = Self::WEP_ENABLED.bits;
115 const WEP_SHARED = Self::WEP_ENABLED.bits | Self::SHARED_ENABLED.bits;
116 const WPA_TKIP_PSK = Self::WPA_SECURITY.bits | Self::TKIP_ENABLED.bits;
117 const WPA_AES_PSK = Self::WPA_SECURITY.bits | Self::AES_ENABLED.bits;
118 const WPA2_AES_PSK = Self::WPA2_SECURITY.bits | Self::AES_ENABLED.bits;
119 const WPA2_TKIP_PSK = Self::WPA2_SECURITY.bits | Self::TKIP_ENABLED.bits;
120 const WPA2_MIXED_PSK = Self::WPA2_SECURITY.bits | Self::AES_ENABLED.bits | Self::TKIP_ENABLED.bits;
121 const WPA_WPA2_MIXED = Self::WPA_SECURITY.bits | Self::WPA2_SECURITY.bits;
122 const WPA2_AES_CMAC = Self::WPA2_SECURITY.bits | Self::AES_CMAC_ENABLED.bits;
123 const WPS_OPEN = Self::WPS_ENABLED.bits;
124 const WPS_SECURE = Self::WPS_ENABLED.bits | Self::AES_ENABLED.bits;
125 const WPS3_AES_PSK = Self::WPA3_SECURITY.bits | Self::AES_ENABLED.bits;
126 }
127}
128
129#[derive(Debug, Copy, Clone)]
131#[allow(dead_code)]
132#[repr(u32)]
133pub enum WPS {
134 Default = 0x0000,
135 UserSpecifed = 0x0001,
136 MachineSpecified = 0x0002,
137 Rekey = 0x0003,
138 Pushbutton = 0x0004,
139 RegistrarSpecified = 0x0005,
140 None = 0x0006,
141 Wsc = 0x0007,
142 Unknown = 0xffff,
143}
144
145impl From<u32> for WPS {
146 fn from(orig: u32) -> Self {
147 match orig {
148 0 => return WPS::Default,
149 1 => return WPS::UserSpecifed,
150 2 => return WPS::MachineSpecified,
151 3 => return WPS::Rekey,
152 4 => return WPS::Pushbutton,
153 5 => return WPS::RegistrarSpecified,
154 6 => return WPS::None,
155 7 => return WPS::Wsc,
156 _ => return WPS::Unknown,
157 };
158 }
159}
160
161#[derive(Debug, Copy, Clone, PartialEq)]
163#[allow(dead_code)]
164#[repr(u32)]
165pub enum Band {
166 _5Ghz = 0,
167 _24Ghz = 1,
168 Unknown = 0xffff,
169}
170
171impl From<u32> for Band {
172 fn from(orig: u32) -> Self {
173 match orig {
174 0 => return Band::_5Ghz,
175 1 => return Band::_24Ghz,
176 _ => return Band::Unknown,
177 };
178 }
179}
180
181#[derive(Copy, Clone)]
183#[repr(packed)]
184pub struct BSSID(pub [u8; 6]);
185
186impl core::fmt::Debug for BSSID {
187 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
188 let table = b"0123456789abcdef";
189
190 let mut out = [0u8; 12 + 6 - 1];
191 for i in 0..(12 + 6 - 1) {
192 let b = self.0[i / 3];
193 out[i] = match (i + 1) % 3 {
194 0 => ':' as u8,
195 1 => table[(b >> 4) as usize],
196 2 => table[(b & 0xf) as usize],
197 _ => '?' as u8,
198 }
199 }
200
201 f.write_str(core::str::from_utf8(&out).unwrap())
202 }
203}
204
205#[derive(Copy, Clone)]
207#[repr(packed)]
208pub struct SSID {
209 len: u8,
210 value: [u8; 33],
211}
212
213impl core::fmt::Debug for SSID {
214 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
215 #[allow(unused_unsafe)]
217 unsafe {
218 f.write_str(core::str::from_utf8(&self.value[..self.len as usize]).unwrap())
219 }
220 }
221}
222
223impl<const N: usize> Into<String<N>> for SSID {
224 fn into(self) -> String<N> {
225 let mut out = String::new();
226 #[allow(unused_unsafe)]
228 unsafe {
229 for i in 0..self.len as usize {
230 out.push(self.value[i] as char).ok();
231 }
232 }
233 out
234 }
235}
236
237#[derive(Debug, Clone)]
239pub struct IPInfo {
240 pub ip: Ipv4Addr,
241 pub netmask: Ipv4Addr,
242 pub gateway: Ipv4Addr,
243}