Skip to main content

wlan_dev/
opts.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use 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    /// commands for wlan phy devices
129    Phy(PhyCmd),
130
131    #[command(subcommand, name = "iface")]
132    /// commands for wlan iface devices
133    Iface(IfaceCmd),
134
135    /// commands for client stations
136    #[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    /// commands for AP stations
151    Ap(ApCmd),
152
153    #[command(subcommand, name = "rsn")]
154    #[cfg(target_os = "fuchsia")]
155    /// commands for verifying RSN behavior
156    Rsn(RsnCmd),
157}
158
159#[derive(Parser, Clone, Debug, PartialEq)]
160pub enum PhyCmd {
161    #[command(name = "list")]
162    /// lists phy devices
163    List,
164    #[command(name = "query")]
165    /// queries a phy device
166    Query {
167        /// id of the phy to query
168        phy_id: u16,
169    },
170    #[command(name = "get-country")]
171    /// gets the phy's country used for WLAN regulatory purposes
172    GetCountry {
173        /// id of the phy to query
174        phy_id: u16,
175    },
176    #[command(name = "set-country")]
177    /// sets the phy's country for WLAN regulatory purpose
178    SetCountry {
179        /// id of the phy to query
180        phy_id: u16,
181        country: String,
182    },
183    #[command(name = "clear-country")]
184    /// sets the phy's country code to world-safe value
185    ClearCountry {
186        /// id of the phy to query
187        phy_id: u16,
188    },
189    #[command(name = "reset")]
190    Reset {
191        /// id of the phy to reset
192        phy_id: u16,
193    },
194    #[command(name = "get-power-state")]
195    /// gets the on/off state of the phy
196    GetPowerState {
197        /// id of the phy to get its power state
198        phy_id: u16,
199    },
200    #[command(name = "set-power-state")]
201    /// sets the on/off state of the phy
202    SetPowerState {
203        /// id of the phy to get its power state
204        phy_id: u16,
205        /// desired state of the phy
206        state: OnOffArg,
207    },
208    #[command(name = "get-powersave-mode")]
209    /// gets the power save mode of the phy
210    GetPowerSaveMode {
211        /// id of the phy to get its power save mode
212        phy_id: u16,
213    },
214    #[command(name = "set-powersave-mode")]
215    /// sets the power save mode of the phy
216    SetPowerSaveMode {
217        /// id of the phy to set its power save mode
218        phy_id: u16,
219        #[arg(value_enum, ignore_case = true)]
220        /// desired power save mode of the phy
221        mode: PsModeArg,
222    },
223}
224
225#[derive(Parser, Clone, Debug, PartialEq)]
226pub enum IfaceCmd {
227    #[command(name = "new")]
228    /// creates a new iface device
229    New {
230        #[arg(short = 'p', long = "phy")]
231        /// id of the phy that will host the iface
232        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 of the new iface
242        role: RoleArg,
243
244        #[arg(short = 'm', long = "sta_addr", help = "Optional sta addr when we create an iface")]
245        /// initial sta address for this iface
246        sta_addr: Option<String>,
247    },
248
249    #[command(name = "del")]
250    /// destroys an iface device
251    Delete {
252        /// iface id to destroy
253        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        // TODO(porce): Expand to support PHY and CBW
358        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}