[wlan][common] Generate C bindings for ReasonCode

Adds support to generate C bindings for wlan-common.
Note: For safety Fuchsia will make use of the
num-derive crate for using enums in C wrappers.

Test=CQ

Change-Id: I2631bcb754305aec1c26e5a280cb939f423569ec
diff --git a/garnet/lib/rust/wlan-common/src/mac.rs b/garnet/lib/rust/wlan-common/src/mac.rs
index 32b2a01..0afe381 100644
--- a/garnet/lib/rust/wlan-common/src/mac.rs
+++ b/garnet/lib/rust/wlan-common/src/mac.rs
@@ -446,8 +446,8 @@
     _VendorSpecific = 65535,
 }
 
-// IEEE Std 802.11-2016, 9.4.1.7
-#[repr(u16)]
+/// IEEE Std 802.11-2016, 9.4.1.7
+#[repr(C)]
 pub enum ReasonCode {
     // 0 Reserved
     UnspecifiedReason = 1,
@@ -489,6 +489,7 @@
     EndTsBaDls = 37,
     UnknownTsBa = 38,
     Timeout = 39,
+    // 40 - 44 Reserved.
     PeerkeyMismatch = 45,
     PeerInitiated = 46,
     ApInitiated = 47,
diff --git a/garnet/lib/rust/wlan-mlme-c/BUILD.gn b/garnet/lib/rust/wlan-mlme-c/BUILD.gn
index f309a0f..053f8c5 100644
--- a/garnet/lib/rust/wlan-mlme-c/BUILD.gn
+++ b/garnet/lib/rust/wlan-mlme-c/BUILD.gn
@@ -13,6 +13,7 @@
   edition = "2018"
 
   deps = [
+    "//garnet/lib/rust/wlan-common",
     "//garnet/lib/rust/wlan-mlme",
     "//garnet/public/rust/fuchsia-zircon",
     "//garnet/public/rust/zerocopy",
diff --git a/garnet/lib/rust/wlan-mlme-c/README.md b/garnet/lib/rust/wlan-mlme-c/README.md
index bf9eff6..e96a060 100644
--- a/garnet/lib/rust/wlan-mlme-c/README.md
+++ b/garnet/lib/rust/wlan-mlme-c/README.md
@@ -8,10 +8,28 @@
 cargo install cbindgen
 ```
 
+## Generate Cargo.toml files
+
+Generate `wlan-common`, `wlan-mlme` and `wlan-mlme-c` Cargo.toml files by running the following command from each directory:
+```
+fx gen-cargo .
+```
+
 ## Command line
 
 ```
 cbindgen $FUCHSIA_DIR/garnet/lib/rust/wlan-mlme-c/ -o $FUCHSIA_DIR/garnet/lib/rust/wlan-mlme-c/bindings.h
 ```
 
-After re-generating the bindings also run `fx format-code` to format the generated bindings.
\ No newline at end of file
+After re-generating the bindings also run `fx format-code` to format the generated bindings.
+
+## Troubleshooting
+
+* `cbindgen` fails when running `cargo metadata`:
+ Remove the Cargo.toml and Cargo.lock files from `wlan-mlme-c` folder and re-run `fx gen-cargo .`.
+
+* ERROR: Parsing crate `wlan_mlme_c`: can't find dependency version for `xyz`:
+Rebuild Fuchsia and re-run `fx gen-cargo .`
+
+* A binding is not generated:
+Run `cbindgen` with `-v` argument to get a better understand what types and functions were found and if they've been rejected.
\ No newline at end of file
diff --git a/garnet/lib/rust/wlan-mlme-c/bindings.h b/garnet/lib/rust/wlan-mlme-c/bindings.h
index 7bc25a5..fa263b9 100644
--- a/garnet/lib/rust/wlan-mlme-c/bindings.h
+++ b/garnet/lib/rust/wlan-mlme-c/bindings.h
@@ -15,6 +15,73 @@
 #include <stdlib.h>
 
 /**
+ * IEEE Std 802.11-2016, 9.4.1.7
+ */
+typedef enum {
+  WLAN_REASON_CODE_UNSPECIFIED_REASON = 1,
+  WLAN_REASON_CODE_INVALID_AUTHENTICATION = 2,
+  WLAN_REASON_CODE_LEAVING_NETWORK_DEAUTH = 3,
+  WLAN_REASON_CODE_REASON_INACTIVITY = 4,
+  WLAN_REASON_CODE_NO_MORE_STAS = 5,
+  WLAN_REASON_CODE_INVALID_CLASS2_FRAME = 6,
+  WLAN_REASON_CODE_INVALID_CLASS3_FRAME = 7,
+  WLAN_REASON_CODE_LEAVING_NETWORK_DISASSOC = 8,
+  WLAN_REASON_CODE_NOT_AUTHENTICATED = 9,
+  WLAN_REASON_CODE_UNACCEPTABLE_POWER_CAPABILITY = 10,
+  WLAN_REASON_CODE_UNACCEPTABLE_SUPPORTED_CHANNELS = 11,
+  WLAN_REASON_CODE_BSS_TRANSITION_DISASSOC = 12,
+  WLAN_REASON_CODE_REASON_INVALID_ELEMENT = 13,
+  WLAN_REASON_CODE_MIC_FAILURE = 14,
+  WLAN_REASON_CODE_FOURWAY_HANDSHAKE_TIMEOUT = 15,
+  WLAN_REASON_CODE_GK_HANDSHAKE_TIMEOUT = 16,
+  WLAN_REASON_CODE_HANDSHAKE_ELEMENT_MISMATCH = 17,
+  WLAN_REASON_CODE_REASON_INVALID_GROUP_CIPHER = 18,
+  WLAN_REASON_CODE_REASON_INVALID_PAIRWISE_CIPHER = 19,
+  WLAN_REASON_CODE_REASON_INVALID_AKMP = 20,
+  WLAN_REASON_CODE_UNSUPPORTED_RSNE_VERSION = 21,
+  WLAN_REASON_CODE_INVALID_RSNE_CAPABILITIES = 22,
+  WLAN_REASON_CODE_IEEE8021_XAUTH_FAILED = 23,
+  WLAN_REASON_CODE_REASON_CIPHER_OUT_OF_POLICY = 24,
+  WLAN_REASON_CODE_TDLS_PEER_UNREACHABLE = 25,
+  WLAN_REASON_CODE_TDLS_UNSPECIFIED_REASON = 26,
+  WLAN_REASON_CODE_SSP_REQUESTED_DISASSOC = 27,
+  WLAN_REASON_CODE_NO_SSP_ROAMING_AGREEMENT = 28,
+  WLAN_REASON_CODE_BAD_CIPHER_OR_AKM = 29,
+  WLAN_REASON_CODE_NOT_AUTHORIZED_THIS_LOCATION = 30,
+  WLAN_REASON_CODE_SERVICE_CHANGE_PRECLUDES_TS = 31,
+  WLAN_REASON_CODE_UNSPECIFIED_QOS_REASON = 32,
+  WLAN_REASON_CODE_NOT_ENOUGH_BANDWIDTH = 33,
+  WLAN_REASON_CODE_MISSING_ACKS = 34,
+  WLAN_REASON_CODE_EXCEEDED_TXOP = 35,
+  WLAN_REASON_CODE_STA_LEAVING = 36,
+  WLAN_REASON_CODE_END_TS_BA_DLS = 37,
+  WLAN_REASON_CODE_UNKNOWN_TS_BA = 38,
+  WLAN_REASON_CODE_TIMEOUT = 39,
+  WLAN_REASON_CODE_PEERKEY_MISMATCH = 45,
+  WLAN_REASON_CODE_PEER_INITIATED = 46,
+  WLAN_REASON_CODE_AP_INITIATED = 47,
+  WLAN_REASON_CODE_REASON_INVALID_FT_ACTION_FRAME_COUNT = 48,
+  WLAN_REASON_CODE_REASON_INVALID_PMKID = 49,
+  WLAN_REASON_CODE_REASON_INVALID_MDE = 50,
+  WLAN_REASON_CODE_REASON_INVALID_FTE = 51,
+  WLAN_REASON_CODE_MESH_PEERING_CANCELED = 52,
+  WLAN_REASON_CODE_MESH_MAX_PEERS = 53,
+  WLAN_REASON_CODE_MESH_CONFIGURATION_POLICY_VIOLATION = 54,
+  WLAN_REASON_CODE_MESH_CLOSE_RCVD = 55,
+  WLAN_REASON_CODE_MESH_MAX_RETRIES = 56,
+  WLAN_REASON_CODE_MESH_CONFIRM_TIMEOUT = 57,
+  WLAN_REASON_CODE_MESH_INVALID_GTK = 58,
+  WLAN_REASON_CODE_MESH_INCONSISTENT_PARAMETERS = 59,
+  WLAN_REASON_CODE_MESH_INVALID_SECURITY_CAPABILITY = 60,
+  WLAN_REASON_CODE_MESH_PATH_ERROR_NO_PROXY_INFORMATION = 61,
+  WLAN_REASON_CODE_MESH_PATH_ERROR_NO_FORWARDING_INFORMATION = 62,
+  WLAN_REASON_CODE_MESH_PATH_ERROR_DESTINATION_UNREACHABLE = 63,
+  WLAN_REASON_CODE_MAC_ADDRESS_ALREADY_EXISTS_IN_MBSS = 64,
+  WLAN_REASON_CODE_MESH_CHANNEL_SWITCH_REGULATORY_REQUIREMENTS = 65,
+  WLAN_REASON_CODE_MESH_CHANNEL_SWITCH_UNSPECIFIED = 66,
+} wlan_reason_code;
+
+/**
  * An input buffer will always be returned to its original owner when no longer
  * being used. An input buffer is used for every buffer handed from C++ to Rust.
  */
@@ -65,12 +132,12 @@
 extern "C" int32_t rust_mlme_is_valid_open_auth_resp(const uint8_t *data,
                                                      uintptr_t len);
 
-extern "C" int32_t rust_mlme_write_open_auth_frame(
+extern "C" int32_t rust_mlme_write_keep_alive_resp_frame(
     rust_mlme_buffer_provider_ops_t provider, const uint8_t (*bssid)[6],
     const uint8_t (*client_addr)[6], uint16_t seq_ctrl,
     rust_mlme_out_buf_t *out_buf);
 
-extern "C" int32_t rust_mlme_write_keep_alive_resp_frame(
+extern "C" int32_t rust_mlme_write_open_auth_frame(
     rust_mlme_buffer_provider_ops_t provider, const uint8_t (*bssid)[6],
     const uint8_t (*client_addr)[6], uint16_t seq_ctrl,
     rust_mlme_out_buf_t *out_buf);
diff --git a/garnet/lib/rust/wlan-mlme-c/cbindgen.toml b/garnet/lib/rust/wlan-mlme-c/cbindgen.toml
index 690749e..b95dfb0 100644
--- a/garnet/lib/rust/wlan-mlme-c/cbindgen.toml
+++ b/garnet/lib/rust/wlan-mlme-c/cbindgen.toml
@@ -14,21 +14,25 @@
 
 [parse]
 parse_deps = true
-include = ["wlan_mlme"]
+include = ["wlan_mlme", "wlan_common"]
 
 [export]
 # These types are not used yet but we want to generate
 # bindings for them already.
-include = ["BufferProvider", "InBuf", "OutBuf"]
-prefix = "rust_mlme_"
+include = ["BufferProvider", "InBuf", "OutBuf", "ReasonCode"]
 
 [export.rename]
 # Unfortunately cbindgen's rename machinery is rather simple
 # and doesn't accomodate our needs. As a result we have to
 # explicitly declare the items which should get renamed
-"BufferProvider" = "buffer_provider_ops_t"
-"InBuf" = "in_buf_t"
-"OutBuf" = "out_buf_t"
+"BufferProvider" = "rust_mlme_buffer_provider_ops_t"
+"InBuf" = "rust_mlme_in_buf_t"
+"OutBuf" = "rust_mlme_out_buf_t"
+"ReasonCode" = "wlan_reason_code"
 
 [fn]
-prefix = 'extern "C"'
\ No newline at end of file
+prefix = 'extern "C"'
+
+[enum]
+rename_variants = "ScreamingSnakeCase"
+prefix_with_name = true
\ No newline at end of file
diff --git a/garnet/lib/rust/wlan-mlme-c/src/lib.rs b/garnet/lib/rust/wlan-mlme-c/src/lib.rs
index 9355433..3f95d17 100644
--- a/garnet/lib/rust/wlan-mlme-c/src/lib.rs
+++ b/garnet/lib/rust/wlan-mlme-c/src/lib.rs
@@ -10,6 +10,7 @@
 #[macro_use]
 extern crate log;
 // Explicitly declare usage for cbindgen.
+extern crate wlan_common;
 extern crate wlan_mlme;
 
 #[macro_use]