[wlan] Support `match` expressions in write_frame!
Supports match expressions in the write_frame! macro.
The expected return type is of: Option<&ValueType>
`match` expressions are supported for optional and
required IEs.
Bug: 43987
Test: Included
Change-Id: Ia921b5678db1c8a8df0ef0b547c290d13403c643
diff --git a/src/connectivity/wlan/lib/frame_writer/macro/src/ie.rs b/src/connectivity/wlan/lib/frame_writer/macro/src/ie.rs
index 4b23894..2c0cc52 100644
--- a/src/connectivity/wlan/lib/frame_writer/macro/src/ie.rs
+++ b/src/connectivity/wlan/lib/frame_writer/macro/src/ie.rs
@@ -7,7 +7,7 @@
quote::quote,
syn::{
parse::{Parse, ParseStream},
- Error, Expr, ExprIf, Ident, Result, Token,
+ Error, Expr, Ident, Result, Token,
},
};
@@ -61,7 +61,6 @@
($name:expr, $optional:expr, $expr:expr) => {
match $expr {
Expr::If(if_expr) => {
- let if_expr: &ExprIf = if_expr;
if if_expr.else_branch.is_some() {
if $optional {
quote!(let $name: Option<_> = #if_expr;)
@@ -219,7 +218,9 @@
Ie::DsssParamSet => {
apply_on!(dsss, &self.value, ie::write_dsss_param_set(&mut w, &dsss)?)
}
- Ie::Wpa1 => apply_on!(wpa1, &self.value, ie::write_wpa1_ie(&mut w, &wpa1)?),
+ Ie::Wpa1 => {
+ apply_on!(wpa1, self.optional, &self.value, ie::write_wpa1_ie(&mut w, &wpa1)?)
+ }
})
}
@@ -261,6 +262,7 @@
| Expr::Tuple(_)
| Expr::Unary(_)
| Expr::Index(_)
+ | Expr::Match(_)
| Expr::Path(_) => (),
other => {
return Err(Error::new(
diff --git a/src/connectivity/wlan/lib/frame_writer/src/lib.rs b/src/connectivity/wlan/lib/frame_writer/src/lib.rs
index b283f80..48f56db 100644
--- a/src/connectivity/wlan/lib/frame_writer/src/lib.rs
+++ b/src/connectivity/wlan/lib/frame_writer/src/lib.rs
@@ -271,7 +271,7 @@
0xdd, 0x16, // Vendor IE header
0x00, 0x50, 0xf2, // MSFT OUI
0x01, 0x01, 0x00, // WPA IE header
- 0x00, 0x50, 0xf2, 0x02, // multicast cipher: AKM
+ 0x00, 0x50, 0xf2, 0x02, // multicast cipher: TKIP
0x01, 0x00, 0x00, 0x50, 0xf2, 0x02, // 1 unicast cipher: TKIP
0x01, 0x00, 0x00, 0x50, 0xf2, 0x02, // 1 AKM: PSK
][..],
@@ -280,6 +280,122 @@
}
#[test]
+ fn write_match_optional_positive() {
+ let wpa_ie = wpa::WpaIe {
+ multicast_cipher: Cipher { oui: Oui::MSFT, suite_type: TKIP },
+ unicast_cipher_list: vec![Cipher { oui: Oui::MSFT, suite_type: TKIP }],
+ akm_list: vec![Akm { oui: Oui::MSFT, suite_type: PSK }],
+ };
+
+ let buffer_provider = BufferProvider;
+ let (buf, bytes_written) = write_frame!(buffer_provider, {
+ ies: {
+ wpa1?: match 2u8 {
+ 1 => None,
+ 2 => Some(&wpa_ie),
+ _ => None,
+ },
+ }
+ })
+ .expect("frame construction failed");
+ assert_eq!(bytes_written, 24);
+ assert_eq!(
+ &[
+ 0xdd, 0x16, // Vendor IE header
+ 0x00, 0x50, 0xf2, // MSFT OUI
+ 0x01, 0x01, 0x00, // WPA IE header
+ 0x00, 0x50, 0xf2, 0x02, // multicast cipher: TKIP
+ 0x01, 0x00, 0x00, 0x50, 0xf2, 0x02, // 1 unicast cipher: TKIP
+ 0x01, 0x00, 0x00, 0x50, 0xf2, 0x02, // 1 AKM: PSK
+ ][..],
+ &buf[..]
+ );
+ }
+
+ #[test]
+ fn write_match_optional_negative() {
+ let wpa_ie = wpa::WpaIe {
+ multicast_cipher: Cipher { oui: Oui::MSFT, suite_type: TKIP },
+ unicast_cipher_list: vec![Cipher { oui: Oui::MSFT, suite_type: TKIP }],
+ akm_list: vec![Akm { oui: Oui::MSFT, suite_type: PSK }],
+ };
+
+ let buffer_provider = BufferProvider;
+ let (buf, bytes_written) = write_frame!(buffer_provider, {
+ ies: {
+ wpa1?: match 1u8 {
+ 1 => None,
+ 2 => Some(&wpa_ie),
+ _ => None,
+ },
+ }
+ })
+ .expect("frame construction failed");
+ assert_eq!(bytes_written, 0);
+ assert!(buf.is_empty());
+ }
+
+ #[test]
+ fn write_match_required() {
+ let wpa_ie_first = wpa::WpaIe {
+ multicast_cipher: Cipher { oui: Oui::MSFT, suite_type: TKIP },
+ unicast_cipher_list: vec![Cipher { oui: Oui::MSFT, suite_type: TKIP }],
+ akm_list: vec![Akm { oui: Oui::MSFT, suite_type: PSK }],
+ };
+ let wpa_ie_second = wpa::WpaIe {
+ multicast_cipher: Cipher { oui: Oui::MSFT, suite_type: CCMP_128 },
+ unicast_cipher_list: vec![Cipher { oui: Oui::MSFT, suite_type: CCMP_128 }],
+ akm_list: vec![Akm { oui: Oui::MSFT, suite_type: PSK }],
+ };
+
+ let buffer_provider = BufferProvider;
+ let (buf, bytes_written) = write_frame!(buffer_provider, {
+ ies: {
+ wpa1: match 1u8 {
+ 1 => &wpa_ie_first,
+ _ => &wpa_ie_second,
+ },
+ }
+ })
+ .expect("frame construction failed");
+ assert_eq!(bytes_written, 24);
+ assert_eq!(
+ &[
+ 0xdd, 0x16, // Vendor IE header
+ 0x00, 0x50, 0xf2, // MSFT OUI
+ 0x01, 0x01, 0x00, // WPA IE header
+ 0x00, 0x50, 0xf2, 0x02, // multicast cipher: TKIP
+ 0x01, 0x00, 0x00, 0x50, 0xf2, 0x02, // 1 unicast cipher: TKIP
+ 0x01, 0x00, 0x00, 0x50, 0xf2, 0x02, // 1 AKM: PSK
+ ][..],
+ &buf[..]
+ );
+
+ let buffer_provider = BufferProvider;
+ let (buf, bytes_written) = write_frame!(buffer_provider, {
+ ies: {
+ wpa1: match 2u8 {
+ 1 => &wpa_ie_first,
+ _ => &wpa_ie_second,
+ },
+ }
+ })
+ .expect("frame construction failed");
+ assert_eq!(bytes_written, 24);
+ assert_eq!(
+ &[
+ 0xdd, 0x16, // Vendor IE header
+ 0x00, 0x50, 0xf2, // MSFT OUI
+ 0x01, 0x01, 0x00, // WPA IE header
+ 0x00, 0x50, 0xf2, 0x04, // multicast cipher: CCMP_128
+ 0x01, 0x00, 0x00, 0x50, 0xf2, 0x04, // 1 unicast cipher: CCMP_128
+ 0x01, 0x00, 0x00, 0x50, 0xf2, 0x02, // 1 AKM: PSK
+ ][..],
+ &buf[..]
+ );
+ }
+
+ #[test]
fn write_ht_caps() {
let buffer_provider = BufferProvider;
let (buf, bytes_written) = write_frame!(buffer_provider, {