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 TxPowerScenarioArg {
110 Default,
111 VoiceCall,
112 HeadCellOff,
113 HeadCellOn,
114 BodyCellOff,
115 BodyCellOn,
116 BodyBtActive,
117}
118
119impl ::std::convert::From<TxPowerScenarioArg> for fidl_fuchsia_wlan_internal::TxPowerScenario {
120 fn from(arg: TxPowerScenarioArg) -> Self {
121 match arg {
122 TxPowerScenarioArg::Default => fidl_fuchsia_wlan_internal::TxPowerScenario::Default,
123 TxPowerScenarioArg::VoiceCall => fidl_fuchsia_wlan_internal::TxPowerScenario::VoiceCall,
124 TxPowerScenarioArg::HeadCellOff => {
125 fidl_fuchsia_wlan_internal::TxPowerScenario::HeadCellOff
126 }
127 TxPowerScenarioArg::HeadCellOn => {
128 fidl_fuchsia_wlan_internal::TxPowerScenario::HeadCellOn
129 }
130 TxPowerScenarioArg::BodyCellOff => {
131 fidl_fuchsia_wlan_internal::TxPowerScenario::BodyCellOff
132 }
133 TxPowerScenarioArg::BodyCellOn => {
134 fidl_fuchsia_wlan_internal::TxPowerScenario::BodyCellOn
135 }
136 TxPowerScenarioArg::BodyBtActive => {
137 fidl_fuchsia_wlan_internal::TxPowerScenario::BodyBtActive
138 }
139 }
140 }
141}
142
143#[derive(ValueEnum, PartialEq, Copy, Clone, Debug)]
144pub enum BandArg {
145 #[value(name = "2g")]
146 TwoGhz,
147 #[value(name = "5g")]
148 FiveGhz,
149}
150
151impl ::std::convert::From<BandArg> for fidl_ieee80211::WlanBand {
152 fn from(arg: BandArg) -> Self {
153 match arg {
154 BandArg::TwoGhz => fidl_ieee80211::WlanBand::TwoGhz,
155 BandArg::FiveGhz => fidl_ieee80211::WlanBand::FiveGhz,
156 }
157 }
158}
159
160#[derive(Parser, Debug, PartialEq)]
161pub enum Opt {
162 #[command(subcommand, name = "phy")]
163 Phy(PhyCmd),
165
166 #[command(subcommand, name = "iface")]
167 Iface(IfaceCmd),
169
170 #[command(subcommand, name = "client")]
172 Client(ClientCmd),
173 #[command(name = "connect")]
174 Connect(ClientConnectCmd),
175 #[command(name = "disconnect")]
176 Disconnect(ClientDisconnectCmd),
177 #[command(name = "scan")]
178 Scan(ClientScanCmd),
179 #[command(name = "status")]
180 Status(IfaceStatusCmd),
181 #[command(name = "wmm_status")]
182 WmmStatus(ClientWmmStatusCmd),
183
184 #[command(subcommand, name = "ap")]
185 Ap(ApCmd),
187
188 #[command(subcommand, name = "rsn")]
189 #[cfg(target_os = "fuchsia")]
190 Rsn(RsnCmd),
192}
193
194#[derive(Parser, Clone, Debug, PartialEq)]
195pub enum PhyCmd {
196 #[command(name = "list")]
197 List,
199 #[command(name = "query")]
200 Query {
202 phy_id: u16,
204 },
205 #[command(name = "get-country")]
206 GetCountry {
208 phy_id: u16,
210 },
211 #[command(name = "set-country")]
212 SetCountry {
214 phy_id: u16,
216 country: String,
217 },
218 #[command(name = "clear-country")]
219 ClearCountry {
221 phy_id: u16,
223 },
224 #[command(name = "reset")]
225 Reset {
226 phy_id: u16,
228 },
229 #[command(name = "get-power-state")]
230 GetPowerState {
232 phy_id: u16,
234 },
235 #[command(name = "set-power-state")]
236 SetPowerState {
238 phy_id: u16,
240 state: OnOffArg,
242 },
243 #[command(name = "get-powersave-mode")]
244 GetPowerSaveMode {
246 phy_id: u16,
248 },
249 #[command(name = "set-powersave-mode")]
250 SetPowerSaveMode {
252 phy_id: u16,
254 #[arg(value_enum, ignore_case = true)]
255 mode: PsModeArg,
257 },
258 #[command(name = "set-tx-power-scenario")]
259 SetTxPowerScenario {
261 phy_id: u16,
263 #[arg(value_enum, ignore_case = true)]
264 mode: TxPowerScenarioArg,
266 },
267 #[command(name = "get-tx-power-scenario")]
268 GetTxPowerScenario {
270 phy_id: u16,
272 },
273
274 #[command(name = "reset-tx-power-scenario")]
275 ResetTxPowerScenario {
276 phy_id: u16,
278 },
279}
280
281#[derive(Parser, Clone, Debug, PartialEq)]
282pub enum IfaceCmd {
283 #[command(name = "new")]
284 New {
286 #[arg(short = 'p', long = "phy")]
287 phy_id: u16,
289
290 #[arg(
291 short = 'r',
292 long = "role",
293 value_enum,
294 default_value = "Client",
295 ignore_case = true
296 )]
297 role: RoleArg,
299
300 #[arg(short = 'm', long = "sta_addr", help = "Optional sta addr when we create an iface")]
301 sta_addr: Option<String>,
303 },
304
305 #[command(name = "del")]
306 Delete {
308 iface_id: u16,
310 },
311
312 #[command(name = "list")]
313 List,
314 #[command(name = "query")]
315 Query { iface_id: u16 },
316 #[command(subcommand, name = "minstrel")]
317 Minstrel(MinstrelCmd),
318 #[command(name = "status")]
319 Status(IfaceStatusCmd),
320}
321
322#[derive(Parser, Clone, Debug, PartialEq)]
323pub enum MinstrelCmd {
324 #[command(name = "list")]
325 List { iface_id: Option<u16> },
326 #[command(name = "show")]
327 Show { iface_id: Option<u16>, peer_addr: Option<String> },
328}
329
330#[derive(Parser, Clone, Debug, PartialEq)]
331pub struct ClientConnectCmd {
332 #[arg(short = 'i', long = "iface", default_value = "0")]
333 pub iface_id: u16,
334 #[arg(short = 'p', long = "password", help = "Password")]
335 pub password: Option<String>,
336 #[arg(long = "hash", help = "WPA2 PSK as hex string")]
337 pub psk: Option<String>,
338 #[arg(
339 short = 's',
340 long = "scan-type",
341 default_value = "passive",
342 value_enum,
343 ignore_case = true,
344 help = "Determines the type of scan performed on non-DFS channels when connecting."
345 )]
346 pub scan_type: ScanTypeArg,
347 #[arg(short = 'b', long = "bssid", help = "Specific BSSID to connect to")]
348 pub bssid: Option<String>,
349 #[arg(
350 help = "SSID of the target network. Connecting via only an SSID is deprecated and will be \
351 removed; use the `donut` tool instead."
352 )]
353 pub ssid: String,
354}
355
356#[derive(Parser, Clone, Debug, PartialEq)]
357pub struct ClientDisconnectCmd {
358 #[arg(short = 'i', long = "iface", default_value = "0")]
359 pub iface_id: u16,
360}
361
362#[derive(Parser, Clone, Debug, PartialEq)]
363pub struct ClientScanCmd {
364 #[arg(short = 'i', long = "iface", default_value = "0")]
365 pub iface_id: u16,
366 #[arg(
367 short = 's',
368 long = "scan-type",
369 default_value = "passive",
370 value_enum,
371 ignore_case = true,
372 help = "Experimental. Default scan type on each channel. \
373 Behavior may differ on DFS channel"
374 )]
375 pub scan_type: ScanTypeArg,
376}
377
378#[derive(Parser, Clone, Debug, PartialEq)]
379pub struct ClientWmmStatusCmd {
380 #[arg(short = 'i', long = "iface", default_value = "0")]
381 pub iface_id: u16,
382}
383
384#[derive(Parser, Clone, Debug, PartialEq)]
385pub struct IfaceStatusCmd {
386 #[arg(short = 'i', long = "iface")]
387 pub iface_id: Option<u16>,
388}
389
390#[derive(Parser, Clone, Debug, PartialEq)]
391pub enum ClientCmd {
392 #[command(name = "scan")]
393 Scan(ClientScanCmd),
394 #[command(name = "connect")]
395 Connect(ClientConnectCmd),
396 #[command(name = "disconnect")]
397 Disconnect(ClientDisconnectCmd),
398 #[command(name = "wmm_status")]
399 WmmStatus(ClientWmmStatusCmd),
400}
401
402#[derive(Parser, Clone, Debug, PartialEq)]
403pub enum ApCmd {
404 #[command(name = "start")]
405 Start {
406 #[arg(short = 'i', long = "iface", default_value = "0")]
407 iface_id: u16,
408 #[arg(short = 's', long = "ssid")]
409 ssid: String,
410 #[arg(short = 'p', long = "password")]
411 password: Option<String>,
412 #[arg(short = 'c', long = "channel")]
413 channel: u8,
415 #[arg(short = 'b', long = "band", value_enum, ignore_case = true)]
416 band: BandArg,
417 },
418 #[command(name = "stop")]
419 Stop {
420 #[arg(short = 'i', long = "iface", default_value = "0")]
421 iface_id: u16,
422 },
423}
424
425#[derive(Parser, Clone, Debug, PartialEq)]
426pub enum RsnCmd {
427 #[command(name = "generate-psk")]
428 GeneratePsk {
429 #[arg(short = 'p', long = "passphrase")]
430 passphrase: String,
431 #[arg(short = 's', long = "ssid")]
432 ssid: String,
433 },
434}