1use clap::{Parser, ValueEnum};
6use fidl_fuchsia_wlan_common as wlan_common;
7use fidl_fuchsia_wlan_common::PowerSaveType;
8use fidl_fuchsia_wlan_ieee80211 as fidl_ieee80211;
9
10#[derive(ValueEnum, PartialEq, Copy, Clone, Debug)]
11pub enum RoleArg {
12 Client,
13 Ap,
14}
15
16#[derive(ValueEnum, PartialEq, Copy, Clone, Debug)]
17pub enum PhyArg {
18 Erp,
19 Ht,
20 Vht,
21}
22
23#[derive(ValueEnum, PartialEq, Copy, Clone, Debug)]
24pub enum CbwArg {
25 Cbw20,
26 Cbw40,
27 Cbw80,
28}
29
30#[derive(ValueEnum, PartialEq, Copy, Clone, Debug)]
31pub enum ScanTypeArg {
32 Active,
33 Passive,
34}
35
36#[derive(ValueEnum, PartialEq, Copy, Clone, Debug)]
37pub enum PsModeArg {
38 PsModeUltraLowPower,
39 PsModeLowPower,
40 PsModeBalanced,
41 PsModePerformance,
42}
43
44#[derive(ValueEnum, PartialEq, Copy, Clone, Debug)]
45pub enum OnOffArg {
46 On,
47 Off,
48}
49
50impl ::std::convert::From<RoleArg> for wlan_common::WlanMacRole {
51 fn from(arg: RoleArg) -> Self {
52 match arg {
53 RoleArg::Client => wlan_common::WlanMacRole::Client,
54 RoleArg::Ap => wlan_common::WlanMacRole::Ap,
55 }
56 }
57}
58
59impl ::std::convert::From<PhyArg> for fidl_ieee80211::WlanPhyType {
60 fn from(arg: PhyArg) -> Self {
61 match arg {
62 PhyArg::Erp => fidl_ieee80211::WlanPhyType::Erp,
63 PhyArg::Ht => fidl_ieee80211::WlanPhyType::Ht,
64 PhyArg::Vht => fidl_ieee80211::WlanPhyType::Vht,
65 }
66 }
67}
68
69impl ::std::convert::From<CbwArg> for fidl_ieee80211::ChannelBandwidth {
70 fn from(arg: CbwArg) -> Self {
71 match arg {
72 CbwArg::Cbw20 => fidl_ieee80211::ChannelBandwidth::Cbw20,
73 CbwArg::Cbw40 => fidl_ieee80211::ChannelBandwidth::Cbw40,
74 CbwArg::Cbw80 => fidl_ieee80211::ChannelBandwidth::Cbw80,
75 }
76 }
77}
78
79impl ::std::convert::From<ScanTypeArg> for wlan_common::ScanType {
80 fn from(arg: ScanTypeArg) -> Self {
81 match arg {
82 ScanTypeArg::Active => wlan_common::ScanType::Active,
83 ScanTypeArg::Passive => wlan_common::ScanType::Passive,
84 }
85 }
86}
87
88impl ::std::convert::From<PsModeArg> for PowerSaveType {
89 fn from(arg: PsModeArg) -> Self {
90 match arg {
91 PsModeArg::PsModePerformance => PowerSaveType::PsModePerformance,
92 PsModeArg::PsModeBalanced => PowerSaveType::PsModeBalanced,
93 PsModeArg::PsModeLowPower => PowerSaveType::PsModeLowPower,
94 PsModeArg::PsModeUltraLowPower => PowerSaveType::PsModeUltraLowPower,
95 }
96 }
97}
98
99impl ::std::convert::From<OnOffArg> for bool {
100 fn from(arg: OnOffArg) -> Self {
101 match arg {
102 OnOffArg::On => true,
103 OnOffArg::Off => false,
104 }
105 }
106}
107
108#[derive(ValueEnum, PartialEq, Copy, Clone, Debug)]
109pub enum BandArg {
110 #[value(name = "2g")]
111 TwoGhz,
112 #[value(name = "5g")]
113 FiveGhz,
114}
115
116impl ::std::convert::From<BandArg> for fidl_ieee80211::WlanBand {
117 fn from(arg: BandArg) -> Self {
118 match arg {
119 BandArg::TwoGhz => fidl_ieee80211::WlanBand::TwoGhz,
120 BandArg::FiveGhz => fidl_ieee80211::WlanBand::FiveGhz,
121 }
122 }
123}
124
125#[derive(Parser, Debug, PartialEq)]
126pub enum Opt {
127 #[command(subcommand, name = "phy")]
128 Phy(PhyCmd),
130
131 #[command(subcommand, name = "iface")]
132 Iface(IfaceCmd),
134
135 #[command(subcommand, name = "client")]
137 Client(ClientCmd),
138 #[command(name = "connect")]
139 Connect(ClientConnectCmd),
140 #[command(name = "disconnect")]
141 Disconnect(ClientDisconnectCmd),
142 #[command(name = "scan")]
143 Scan(ClientScanCmd),
144 #[command(name = "status")]
145 Status(IfaceStatusCmd),
146 #[command(name = "wmm_status")]
147 WmmStatus(ClientWmmStatusCmd),
148
149 #[command(subcommand, name = "ap")]
150 Ap(ApCmd),
152
153 #[command(subcommand, name = "rsn")]
154 #[cfg(target_os = "fuchsia")]
155 Rsn(RsnCmd),
157}
158
159#[derive(Parser, Clone, Debug, PartialEq)]
160pub enum PhyCmd {
161 #[command(name = "list")]
162 List,
164 #[command(name = "query")]
165 Query {
167 phy_id: u16,
169 },
170 #[command(name = "get-country")]
171 GetCountry {
173 phy_id: u16,
175 },
176 #[command(name = "set-country")]
177 SetCountry {
179 phy_id: u16,
181 country: String,
182 },
183 #[command(name = "clear-country")]
184 ClearCountry {
186 phy_id: u16,
188 },
189 #[command(name = "reset")]
190 Reset {
191 phy_id: u16,
193 },
194 #[command(name = "get-power-state")]
195 GetPowerState {
197 phy_id: u16,
199 },
200 #[command(name = "set-power-state")]
201 SetPowerState {
203 phy_id: u16,
205 state: OnOffArg,
207 },
208 #[command(name = "get-powersave-mode")]
209 GetPowerSaveMode {
211 phy_id: u16,
213 },
214 #[command(name = "set-powersave-mode")]
215 SetPowerSaveMode {
217 phy_id: u16,
219 #[arg(value_enum, ignore_case = true)]
220 mode: PsModeArg,
222 },
223}
224
225#[derive(Parser, Clone, Debug, PartialEq)]
226pub enum IfaceCmd {
227 #[command(name = "new")]
228 New {
230 #[arg(short = 'p', long = "phy")]
231 phy_id: u16,
233
234 #[arg(
235 short = 'r',
236 long = "role",
237 value_enum,
238 default_value = "Client",
239 ignore_case = true
240 )]
241 role: RoleArg,
243
244 #[arg(short = 'm', long = "sta_addr", help = "Optional sta addr when we create an iface")]
245 sta_addr: Option<String>,
247 },
248
249 #[command(name = "del")]
250 Delete {
252 iface_id: u16,
254 },
255
256 #[command(name = "list")]
257 List,
258 #[command(name = "query")]
259 Query { iface_id: u16 },
260 #[command(subcommand, name = "minstrel")]
261 Minstrel(MinstrelCmd),
262 #[command(name = "status")]
263 Status(IfaceStatusCmd),
264}
265
266#[derive(Parser, Clone, Debug, PartialEq)]
267pub enum MinstrelCmd {
268 #[command(name = "list")]
269 List { iface_id: Option<u16> },
270 #[command(name = "show")]
271 Show { iface_id: Option<u16>, peer_addr: Option<String> },
272}
273
274#[derive(Parser, Clone, Debug, PartialEq)]
275pub struct ClientConnectCmd {
276 #[arg(short = 'i', long = "iface", default_value = "0")]
277 pub iface_id: u16,
278 #[arg(short = 'p', long = "password", help = "Password")]
279 pub password: Option<String>,
280 #[arg(short = 'h', long = "hash", help = "WPA2 PSK as hex string")]
281 pub psk: Option<String>,
282 #[arg(
283 short = 's',
284 long = "scan-type",
285 default_value = "passive",
286 value_enum,
287 ignore_case = true,
288 help = "Determines the type of scan performed on non-DFS channels when connecting."
289 )]
290 pub scan_type: ScanTypeArg,
291 #[arg(short = 'b', long = "bssid", help = "Specific BSSID to connect to")]
292 pub bssid: Option<String>,
293 #[arg(
294 help = "SSID of the target network. Connecting via only an SSID is deprecated and will be \
295 removed; use the `donut` tool instead."
296 )]
297 pub ssid: String,
298}
299
300#[derive(Parser, Clone, Debug, PartialEq)]
301pub struct ClientDisconnectCmd {
302 #[arg(short = 'i', long = "iface", default_value = "0")]
303 pub iface_id: u16,
304}
305
306#[derive(Parser, Clone, Debug, PartialEq)]
307pub struct ClientScanCmd {
308 #[arg(short = 'i', long = "iface", default_value = "0")]
309 pub iface_id: u16,
310 #[arg(
311 short = 's',
312 long = "scan-type",
313 default_value = "passive",
314 value_enum,
315 ignore_case = true,
316 help = "Experimental. Default scan type on each channel. \
317 Behavior may differ on DFS channel"
318 )]
319 pub scan_type: ScanTypeArg,
320}
321
322#[derive(Parser, Clone, Debug, PartialEq)]
323pub struct ClientWmmStatusCmd {
324 #[arg(short = 'i', long = "iface", default_value = "0")]
325 pub iface_id: u16,
326}
327
328#[derive(Parser, Clone, Debug, PartialEq)]
329pub struct IfaceStatusCmd {
330 #[arg(short = 'i', long = "iface")]
331 pub iface_id: Option<u16>,
332}
333
334#[derive(Parser, Clone, Debug, PartialEq)]
335pub enum ClientCmd {
336 #[command(name = "scan")]
337 Scan(ClientScanCmd),
338 #[command(name = "connect")]
339 Connect(ClientConnectCmd),
340 #[command(name = "disconnect")]
341 Disconnect(ClientDisconnectCmd),
342 #[command(name = "wmm_status")]
343 WmmStatus(ClientWmmStatusCmd),
344}
345
346#[derive(Parser, Clone, Debug, PartialEq)]
347pub enum ApCmd {
348 #[command(name = "start")]
349 Start {
350 #[arg(short = 'i', long = "iface", default_value = "0")]
351 iface_id: u16,
352 #[arg(short = 's', long = "ssid")]
353 ssid: String,
354 #[arg(short = 'p', long = "password")]
355 password: Option<String>,
356 #[arg(short = 'c', long = "channel")]
357 channel: u8,
359 #[arg(short = 'b', long = "band", value_enum, ignore_case = true)]
360 band: BandArg,
361 },
362 #[command(name = "stop")]
363 Stop {
364 #[arg(short = 'i', long = "iface", default_value = "0")]
365 iface_id: u16,
366 },
367}
368
369#[derive(Parser, Clone, Debug, PartialEq)]
370pub enum RsnCmd {
371 #[command(name = "generate-psk")]
372 GeneratePsk {
373 #[arg(short = 'p', long = "passphrase")]
374 passphrase: String,
375 #[arg(short = 's', long = "ssid")]
376 ssid: String,
377 },
378}