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::arg_enum;
6use fidl_fuchsia_wlan_common as wlan_common;
7use fidl_fuchsia_wlan_common::PowerSaveType;
8use structopt::StructOpt;
9
10arg_enum! {
11    #[derive(PartialEq, Copy, Clone, Debug)]
12    pub enum RoleArg {
13        Client,
14        Ap
15    }
16}
17
18arg_enum! {
19    #[derive(PartialEq, Copy, Clone, Debug)]
20    pub enum PhyArg {
21        Erp,
22        Ht,
23        Vht,
24    }
25}
26
27arg_enum! {
28    #[derive(PartialEq, Copy, Clone, Debug)]
29    pub enum CbwArg {
30        Cbw20,
31        Cbw40,
32        Cbw80,
33    }
34}
35
36arg_enum! {
37    #[derive(PartialEq, Copy, Clone, Debug)]
38    pub enum ScanTypeArg {
39        Active,
40        Passive,
41    }
42}
43
44arg_enum! {
45    #[derive(PartialEq, Copy, Clone, Debug)]
46    pub enum PsModeArg {
47        PsModeUltraLowPower,
48        PsModeLowPower,
49        PsModeBalanced,
50        PsModePerformance,
51    }
52}
53
54impl ::std::convert::From<RoleArg> for wlan_common::WlanMacRole {
55    fn from(arg: RoleArg) -> Self {
56        match arg {
57            RoleArg::Client => wlan_common::WlanMacRole::Client,
58            RoleArg::Ap => wlan_common::WlanMacRole::Ap,
59        }
60    }
61}
62
63impl ::std::convert::From<PhyArg> for wlan_common::WlanPhyType {
64    fn from(arg: PhyArg) -> Self {
65        match arg {
66            PhyArg::Erp => wlan_common::WlanPhyType::Erp,
67            PhyArg::Ht => wlan_common::WlanPhyType::Ht,
68            PhyArg::Vht => wlan_common::WlanPhyType::Vht,
69        }
70    }
71}
72
73impl ::std::convert::From<CbwArg> for wlan_common::ChannelBandwidth {
74    fn from(arg: CbwArg) -> Self {
75        match arg {
76            CbwArg::Cbw20 => wlan_common::ChannelBandwidth::Cbw20,
77            CbwArg::Cbw40 => wlan_common::ChannelBandwidth::Cbw40,
78            CbwArg::Cbw80 => wlan_common::ChannelBandwidth::Cbw80,
79        }
80    }
81}
82
83impl ::std::convert::From<ScanTypeArg> for wlan_common::ScanType {
84    fn from(arg: ScanTypeArg) -> Self {
85        match arg {
86            ScanTypeArg::Active => wlan_common::ScanType::Active,
87            ScanTypeArg::Passive => wlan_common::ScanType::Passive,
88        }
89    }
90}
91
92impl ::std::convert::From<PsModeArg> for PowerSaveType {
93    fn from(arg: PsModeArg) -> Self {
94        match arg {
95            PsModeArg::PsModePerformance => PowerSaveType::PsModePerformance,
96            PsModeArg::PsModeBalanced => PowerSaveType::PsModeBalanced,
97            PsModeArg::PsModeLowPower => PowerSaveType::PsModeLowPower,
98            PsModeArg::PsModeUltraLowPower => PowerSaveType::PsModeUltraLowPower,
99        }
100    }
101}
102
103#[derive(StructOpt, Debug, PartialEq)]
104pub enum Opt {
105    #[structopt(name = "phy")]
106    /// commands for wlan phy devices
107    Phy(PhyCmd),
108
109    #[structopt(name = "iface")]
110    /// commands for wlan iface devices
111    Iface(IfaceCmd),
112
113    /// commands for client stations
114    #[structopt(name = "client")]
115    Client(ClientCmd),
116    #[structopt(name = "connect")]
117    Connect(ClientConnectCmd),
118    #[structopt(name = "disconnect")]
119    Disconnect(ClientDisconnectCmd),
120    #[structopt(name = "scan")]
121    Scan(ClientScanCmd),
122    #[structopt(name = "status")]
123    Status(IfaceStatusCmd),
124    #[structopt(name = "wmm_status")]
125    WmmStatus(ClientWmmStatusCmd),
126
127    #[structopt(name = "ap")]
128    /// commands for AP stations
129    Ap(ApCmd),
130
131    #[structopt(name = "rsn")]
132    #[cfg(target_os = "fuchsia")]
133    /// commands for verifying RSN behavior
134    Rsn(RsnCmd),
135}
136
137#[derive(StructOpt, Clone, Debug, PartialEq)]
138pub enum PhyCmd {
139    #[structopt(name = "list")]
140    /// lists phy devices
141    List,
142    #[structopt(name = "query")]
143    /// queries a phy device
144    Query {
145        #[structopt(required = true)]
146        /// id of the phy to query
147        phy_id: u16,
148    },
149    #[structopt(name = "get-country")]
150    /// gets the phy's country used for WLAN regulatory purposes
151    GetCountry {
152        #[structopt(required = true)]
153        /// id of the phy to query
154        phy_id: u16,
155    },
156    #[structopt(name = "set-country")]
157    /// sets the phy's country for WLAN regulatory purpose
158    SetCountry {
159        #[structopt(required = true)]
160        /// id of the phy to query
161        phy_id: u16,
162        #[structopt(required = true)]
163        country: String,
164    },
165    #[structopt(name = "clear-country")]
166    /// sets the phy's country code to world-safe value
167    ClearCountry {
168        #[structopt(required = true)]
169        /// id of the phy to query
170        phy_id: u16,
171    },
172}
173
174#[derive(StructOpt, Clone, Debug, PartialEq)]
175pub enum IfaceCmd {
176    #[structopt(name = "new")]
177    /// creates a new iface device
178    New {
179        #[structopt(short = "p", long = "phy", required = true)]
180        /// id of the phy that will host the iface
181        phy_id: u16,
182
183        #[structopt(
184            short = "r",
185            long = "role",
186            possible_values = &RoleArg::variants(),
187            default_value = "Client",
188            case_insensitive = true,
189        )]
190        /// role of the new iface
191        role: RoleArg,
192
193        #[structopt(
194            short = "m",
195            long = "sta_addr",
196            help = "Optional sta addr when we create an iface"
197        )]
198        /// initial sta address for this iface
199        sta_addr: Option<String>,
200    },
201
202    #[structopt(name = "del")]
203    /// destroys an iface device
204    Delete {
205        #[structopt(required = true)]
206        /// iface id to destroy
207        iface_id: u16,
208    },
209
210    #[structopt(name = "list")]
211    List,
212    #[structopt(name = "query")]
213    Query {
214        #[structopt(required = true)]
215        iface_id: u16,
216    },
217    #[structopt(name = "minstrel")]
218    Minstrel(MinstrelCmd),
219    #[structopt(name = "status")]
220    Status(IfaceStatusCmd),
221}
222
223#[derive(StructOpt, Clone, Debug, PartialEq)]
224pub enum MinstrelCmd {
225    #[structopt(name = "list")]
226    List { iface_id: Option<u16> },
227    #[structopt(name = "show")]
228    Show { iface_id: Option<u16>, peer_addr: Option<String> },
229}
230
231#[derive(StructOpt, Clone, Debug, PartialEq)]
232pub struct ClientConnectCmd {
233    #[structopt(short = "i", long = "iface", default_value = "0")]
234    pub iface_id: u16,
235    #[structopt(short = "p", long = "password", help = "Password")]
236    pub password: Option<String>,
237    #[structopt(short = "hash", long = "hash", help = "WPA2 PSK as hex string")]
238    pub psk: Option<String>,
239    #[structopt(
240        short = "s",
241        long = "scan-type",
242        default_value = "passive",
243        possible_values = &ScanTypeArg::variants(),
244        case_insensitive = true,
245        help = "Determines the type of scan performed on non-DFS channels when connecting."
246    )]
247    pub scan_type: ScanTypeArg,
248    #[structopt(short = "b", long = "bssid", help = "Specific BSSID to connect to")]
249    pub bssid: Option<String>,
250    #[structopt(
251        required = true,
252        help = "SSID of the target network. Connecting via only an SSID is deprecated and will be \
253                removed; use the `donut` tool instead."
254    )]
255    pub ssid: String,
256}
257
258#[derive(StructOpt, Clone, Debug, PartialEq)]
259pub struct ClientDisconnectCmd {
260    #[structopt(short = "i", long = "iface", default_value = "0")]
261    pub iface_id: u16,
262}
263
264#[derive(StructOpt, Clone, Debug, PartialEq)]
265pub struct ClientScanCmd {
266    #[structopt(short = "i", long = "iface", default_value = "0")]
267    pub iface_id: u16,
268    #[structopt(
269        short = "s",
270        long = "scan-type",
271        default_value = "passive",
272        possible_values = &ScanTypeArg::variants(),
273        case_insensitive = true,
274        help = "Experimental. Default scan type on each channel. \
275                Behavior may differ on DFS channel"
276    )]
277    pub scan_type: ScanTypeArg,
278}
279
280#[derive(StructOpt, Clone, Debug, PartialEq)]
281pub struct ClientWmmStatusCmd {
282    #[structopt(short = "i", long = "iface", default_value = "0")]
283    pub iface_id: u16,
284}
285
286#[derive(StructOpt, Clone, Debug, PartialEq)]
287pub struct IfaceStatusCmd {
288    #[structopt(short = "i", long = "iface")]
289    pub iface_id: Option<u16>,
290}
291
292#[derive(StructOpt, Clone, Debug, PartialEq)]
293pub enum ClientCmd {
294    #[structopt(name = "scan")]
295    Scan(ClientScanCmd),
296    #[structopt(name = "connect")]
297    Connect(ClientConnectCmd),
298    #[structopt(name = "disconnect")]
299    Disconnect(ClientDisconnectCmd),
300    #[structopt(name = "wmm_status")]
301    WmmStatus(ClientWmmStatusCmd),
302}
303
304#[derive(StructOpt, Clone, Debug, PartialEq)]
305pub enum ApCmd {
306    #[structopt(name = "start")]
307    Start {
308        #[structopt(short = "i", long = "iface", default_value = "0")]
309        iface_id: u16,
310        #[structopt(short = "s", long = "ssid")]
311        ssid: String,
312        #[structopt(short = "p", long = "password")]
313        password: Option<String>,
314        #[structopt(short = "c", long = "channel")]
315        // TODO(porce): Expand to support PHY and CBW
316        channel: u8,
317    },
318    #[structopt(name = "stop")]
319    Stop {
320        #[structopt(short = "i", long = "iface", default_value = "0")]
321        iface_id: u16,
322    },
323}
324
325#[derive(StructOpt, Clone, Debug, PartialEq)]
326pub enum RsnCmd {
327    #[structopt(name = "generate-psk")]
328    GeneratePsk {
329        #[structopt(short = "p", long = "passphrase")]
330        passphrase: String,
331        #[structopt(short = "s", long = "ssid")]
332        ssid: String,
333    },
334}