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(Parser, Debug, PartialEq)]
109pub enum Opt {
110    #[command(subcommand, name = "phy")]
111    /// commands for wlan phy devices
112    Phy(PhyCmd),
113
114    #[command(subcommand, name = "iface")]
115    /// commands for wlan iface devices
116    Iface(IfaceCmd),
117
118    /// commands for client stations
119    #[command(subcommand, name = "client")]
120    Client(ClientCmd),
121    #[command(name = "connect")]
122    Connect(ClientConnectCmd),
123    #[command(name = "disconnect")]
124    Disconnect(ClientDisconnectCmd),
125    #[command(name = "scan")]
126    Scan(ClientScanCmd),
127    #[command(name = "status")]
128    Status(IfaceStatusCmd),
129    #[command(name = "wmm_status")]
130    WmmStatus(ClientWmmStatusCmd),
131
132    #[command(subcommand, name = "ap")]
133    /// commands for AP stations
134    Ap(ApCmd),
135
136    #[command(subcommand, name = "rsn")]
137    #[cfg(target_os = "fuchsia")]
138    /// commands for verifying RSN behavior
139    Rsn(RsnCmd),
140}
141
142#[derive(Parser, Clone, Debug, PartialEq)]
143pub enum PhyCmd {
144    #[command(name = "list")]
145    /// lists phy devices
146    List,
147    #[command(name = "query")]
148    /// queries a phy device
149    Query {
150        /// id of the phy to query
151        phy_id: u16,
152    },
153    #[command(name = "get-country")]
154    /// gets the phy's country used for WLAN regulatory purposes
155    GetCountry {
156        /// id of the phy to query
157        phy_id: u16,
158    },
159    #[command(name = "set-country")]
160    /// sets the phy's country for WLAN regulatory purpose
161    SetCountry {
162        /// id of the phy to query
163        phy_id: u16,
164        country: String,
165    },
166    #[command(name = "clear-country")]
167    /// sets the phy's country code to world-safe value
168    ClearCountry {
169        /// id of the phy to query
170        phy_id: u16,
171    },
172    #[command(name = "reset")]
173    Reset {
174        /// id of the phy to reset
175        phy_id: u16,
176    },
177    #[command(name = "get-power-state")]
178    /// gets the on/off state of the phy
179    GetPowerState {
180        /// id of the phy to get its power state
181        phy_id: u16,
182    },
183    #[command(name = "set-power-state")]
184    /// sets the on/off state of the phy
185    SetPowerState {
186        /// id of the phy to get its power state
187        phy_id: u16,
188        /// desired state of the phy
189        state: OnOffArg,
190    },
191    #[command(name = "get-powersave-mode")]
192    /// gets the power save mode of the phy
193    GetPowerSaveMode {
194        /// id of the phy to get its power save mode
195        phy_id: u16,
196    },
197    #[command(name = "set-powersave-mode")]
198    /// sets the power save mode of the phy
199    SetPowerSaveMode {
200        /// id of the phy to set its power save mode
201        phy_id: u16,
202        #[arg(value_enum, ignore_case = true)]
203        /// desired power save mode of the phy
204        mode: PsModeArg,
205    },
206}
207
208#[derive(Parser, Clone, Debug, PartialEq)]
209pub enum IfaceCmd {
210    #[command(name = "new")]
211    /// creates a new iface device
212    New {
213        #[arg(short = 'p', long = "phy")]
214        /// id of the phy that will host the iface
215        phy_id: u16,
216
217        #[arg(
218            short = 'r',
219            long = "role",
220            value_enum,
221            default_value = "Client",
222            ignore_case = true
223        )]
224        /// role of the new iface
225        role: RoleArg,
226
227        #[arg(short = 'm', long = "sta_addr", help = "Optional sta addr when we create an iface")]
228        /// initial sta address for this iface
229        sta_addr: Option<String>,
230    },
231
232    #[command(name = "del")]
233    /// destroys an iface device
234    Delete {
235        /// iface id to destroy
236        iface_id: u16,
237    },
238
239    #[command(name = "list")]
240    List,
241    #[command(name = "query")]
242    Query { iface_id: u16 },
243    #[command(subcommand, name = "minstrel")]
244    Minstrel(MinstrelCmd),
245    #[command(name = "status")]
246    Status(IfaceStatusCmd),
247}
248
249#[derive(Parser, Clone, Debug, PartialEq)]
250pub enum MinstrelCmd {
251    #[command(name = "list")]
252    List { iface_id: Option<u16> },
253    #[command(name = "show")]
254    Show { iface_id: Option<u16>, peer_addr: Option<String> },
255}
256
257#[derive(Parser, Clone, Debug, PartialEq)]
258pub struct ClientConnectCmd {
259    #[arg(short = 'i', long = "iface", default_value = "0")]
260    pub iface_id: u16,
261    #[arg(short = 'p', long = "password", help = "Password")]
262    pub password: Option<String>,
263    #[arg(short = 'h', long = "hash", help = "WPA2 PSK as hex string")]
264    pub psk: Option<String>,
265    #[arg(
266        short = 's',
267        long = "scan-type",
268        default_value = "passive",
269        value_enum,
270        ignore_case = true,
271        help = "Determines the type of scan performed on non-DFS channels when connecting."
272    )]
273    pub scan_type: ScanTypeArg,
274    #[arg(short = 'b', long = "bssid", help = "Specific BSSID to connect to")]
275    pub bssid: Option<String>,
276    #[arg(
277        help = "SSID of the target network. Connecting via only an SSID is deprecated and will be \
278                removed; use the `donut` tool instead."
279    )]
280    pub ssid: String,
281}
282
283#[derive(Parser, Clone, Debug, PartialEq)]
284pub struct ClientDisconnectCmd {
285    #[arg(short = 'i', long = "iface", default_value = "0")]
286    pub iface_id: u16,
287}
288
289#[derive(Parser, Clone, Debug, PartialEq)]
290pub struct ClientScanCmd {
291    #[arg(short = 'i', long = "iface", default_value = "0")]
292    pub iface_id: u16,
293    #[arg(
294        short = 's',
295        long = "scan-type",
296        default_value = "passive",
297        value_enum,
298        ignore_case = true,
299        help = "Experimental. Default scan type on each channel. \
300                Behavior may differ on DFS channel"
301    )]
302    pub scan_type: ScanTypeArg,
303}
304
305#[derive(Parser, Clone, Debug, PartialEq)]
306pub struct ClientWmmStatusCmd {
307    #[arg(short = 'i', long = "iface", default_value = "0")]
308    pub iface_id: u16,
309}
310
311#[derive(Parser, Clone, Debug, PartialEq)]
312pub struct IfaceStatusCmd {
313    #[arg(short = 'i', long = "iface")]
314    pub iface_id: Option<u16>,
315}
316
317#[derive(Parser, Clone, Debug, PartialEq)]
318pub enum ClientCmd {
319    #[command(name = "scan")]
320    Scan(ClientScanCmd),
321    #[command(name = "connect")]
322    Connect(ClientConnectCmd),
323    #[command(name = "disconnect")]
324    Disconnect(ClientDisconnectCmd),
325    #[command(name = "wmm_status")]
326    WmmStatus(ClientWmmStatusCmd),
327}
328
329#[derive(Parser, Clone, Debug, PartialEq)]
330pub enum ApCmd {
331    #[command(name = "start")]
332    Start {
333        #[arg(short = 'i', long = "iface", default_value = "0")]
334        iface_id: u16,
335        #[arg(short = 's', long = "ssid")]
336        ssid: String,
337        #[arg(short = 'p', long = "password")]
338        password: Option<String>,
339        #[arg(short = 'c', long = "channel")]
340        // TODO(porce): Expand to support PHY and CBW
341        channel: u8,
342    },
343    #[command(name = "stop")]
344    Stop {
345        #[arg(short = 'i', long = "iface", default_value = "0")]
346        iface_id: u16,
347    },
348}
349
350#[derive(Parser, Clone, Debug, PartialEq)]
351pub enum RsnCmd {
352    #[command(name = "generate-psk")]
353    GeneratePsk {
354        #[arg(short = 'p', long = "passphrase")]
355        passphrase: String,
356        #[arg(short = 's', long = "ssid")]
357        ssid: String,
358    },
359}