| // Copyright 2017 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| library fuchsia.wlan.mlme; |
| |
| using fuchsia.wlan.common; |
| using fuchsia.wlan.ieee80211 as ieee80211; |
| using fuchsia.wlan.mesh; |
| using fuchsia.wlan.internal as internal; |
| |
| // Stub types for communicating between the wlan service and the MLME drivers. Based on the 802.11 |
| // MLME SAP interface (IEEE Std 802.11-2016 section 6.3). |
| |
| // TODO(fxbug.dev/21133): restore the commented out enum aliases |
| |
| // MLME-SCAN.request (IEEE Std 802.11-2016 6.3.3.2) |
| |
| enum ScanTypes { |
| ACTIVE = 1; |
| PASSIVE = 2; |
| //LAST = PASSIVE; |
| }; |
| |
| const uint32 MAX_SSIDS_PER_SCAN_REQUEST = 32; |
| |
| struct ScanRequest { |
| uint64 txn_id; |
| internal.BssTypes bss_type; |
| array<uint8>:6 bssid; |
| bytes:ieee80211.MAX_SSID_BYTE_LEN ssid; |
| ScanTypes scan_type; |
| uint32 probe_delay; // in TimeUnits |
| vector<uint8>? channel_list; |
| uint32 min_channel_time; // in TimeUnits |
| uint32 max_channel_time; // in TimeUnits |
| // RequestInformation |
| vector<bytes:ieee80211.MAX_SSID_BYTE_LEN>:MAX_SSIDS_PER_SCAN_REQUEST? ssid_list; |
| // ChannelUsage |
| // AccessNetworkType |
| // HESSID |
| // Mesh ID |
| // DiscoveryMode |
| // VendorSpecificInfo |
| }; |
| |
| // MLME-SCAN.confirm (IEEE Std 802.11-2016 6.3.3.3) |
| |
| // LINT.IfChange |
| |
| /// WFA WMM v1.2, 2.2.2 Table 5 |
| /// Length of the WMM Parameter Element body. This does not include IE and vendor IE headers, |
| /// and only includes the QoS Info, reserved, and AC parameters fields. |
| const uint8 WMM_PARAM_LEN = 18; |
| |
| // LINT.ThenChange(//sdk/banjo/fuchsia.hardware.wlanif/wlanif.banjo) |
| |
| /// WFA WMM v1.2, 2.2.1 |
| alias QosInfo = uint8; |
| |
| struct WmmParameter { |
| array<uint8>:WMM_PARAM_LEN bytes; |
| }; |
| |
| enum ScanResultCode { |
| SUCCESS = 0; |
| NOT_SUPPORTED = 1; |
| INVALID_ARGS = 2; |
| INTERNAL_ERROR = 3; |
| SHOULD_WAIT = 4; |
| CANCELED_BY_DRIVER_OR_FIRMWARE = 5; |
| }; |
| |
| struct ScanResult { |
| uint64 txn_id; |
| internal.BssDescription bss; |
| }; |
| |
| struct ScanEnd { |
| uint64 txn_id; |
| ScanResultCode code; |
| }; |
| |
| // MLME-JOIN.request (IEEE Std 802.11-2016, 6.3.4.2) |
| |
| struct JoinRequest { |
| internal.BssDescription selected_bss; |
| uint32 join_failure_timeout; |
| uint32 nav_sync_delay; |
| bytes:internal.RATES_MAX_LEN op_rates; |
| |
| // Combined with what MLME knows about the device capabilities, |
| // following parameters determine what to be advertised to the peer |
| // (in AssociationRequest). Effectively this way replaces the following |
| // fields originally defined in MLME-JOIN.request |
| // - Capability Information |
| // - HT Capabilities |
| // - VHT Capabilities |
| // - Extended Capabilities |
| fuchsia.wlan.common.PHY phy; |
| fuchsia.wlan.common.CBW cbw; |
| }; |
| |
| // MLME-JOIN.confirm (IEEE Std 802.11-2016, 6.3.4.3) |
| |
| enum JoinResultCode { |
| SUCCESS = 0; |
| JOIN_FAILURE_TIMEOUT = 1; |
| //LAST = JOIN_FAILURE_TIMEOUT; |
| }; |
| |
| struct JoinConfirm { |
| JoinResultCode result_code; |
| }; |
| |
| // MLME-AUTHENTICATE.request (IEEE Std 802.11-2016, 6.3.5.2) |
| |
| enum AuthenticationTypes { |
| OPEN_SYSTEM = 1; |
| SHARED_KEY = 2; |
| FAST_BSS_TRANSITION = 3; |
| SAE = 4; |
| //LAST = SAE; |
| }; |
| |
| struct AuthenticateRequest { |
| array<uint8>:6 peer_sta_address; |
| AuthenticationTypes auth_type; |
| uint32 auth_failure_timeout; |
| |
| // If populated, use this password to perform SAE in the driver/firmware. |
| vector<uint8>? sae_password; |
| |
| // etc |
| }; |
| |
| // MLME-AUTHENTICATE.confirm (IEEE Std 802.11-2016, 6.3.5.3) |
| |
| enum AuthenticateResultCode { |
| SUCCESS = 0; |
| REFUSED = 1; |
| ANTI_CLOGGING_TOKEN_REQUIRED = 2; |
| FINITE_CYCLIC_GROUP_NOT_SUPPORTED = 3; |
| AUTHENTICATION_REJECTED = 4; |
| AUTH_FAILURE_TIMEOUT = 5; |
| }; |
| |
| struct AuthenticateConfirm { |
| array<uint8>:6 peer_sta_address; |
| AuthenticationTypes auth_type; |
| AuthenticateResultCode result_code; |
| |
| // etc |
| }; |
| |
| // MLME-AUTHENTICATE.indication (IEEE Std 802.11-2016, 6.3.5.4) |
| |
| struct AuthenticateIndication { |
| array<uint8>:6 peer_sta_address; |
| AuthenticationTypes auth_type; |
| |
| // etc |
| }; |
| |
| // MLME-AUTHENTICATE.response (IEEE Std 802.11-2016, 6.3.5.5) |
| |
| struct AuthenticateResponse { |
| array<uint8>:6 peer_sta_address; |
| AuthenticateResultCode result_code; |
| |
| // etc |
| }; |
| |
| // MLME-DEAUTHENTICATE.request (IEEE Std 802.11-2016, 6.3.6.2) |
| |
| struct DeauthenticateRequest { |
| array<uint8>:6 peer_sta_address; |
| ieee80211.ReasonCode reason_code; |
| // VendorSpecificInfo |
| }; |
| |
| // MLME-DEAUTHENTICATE.confirm (IEEE Std 802.11-2016, 6.3.6.3) |
| |
| struct DeauthenticateConfirm { |
| array<uint8>:6 peer_sta_address; |
| }; |
| |
| // MLME-DEAUTHENTICATE.indication (IEEE Std 802.11-2016, 6.3.6.4) |
| |
| struct DeauthenticateIndication { |
| array<uint8>:6 peer_sta_address; |
| ieee80211.ReasonCode reason_code; |
| /// locally_initiated is true if deauth is initiated from the device, |
| /// and is false if it's initiated remotely (e.g. due to deauth frame) |
| bool locally_initiated; |
| // VendorSpecificInfo |
| }; |
| |
| // MLME-ASSOCIATE.request (IEEE Std 802.11-2016, 6.3.7.2) |
| |
| struct AssociateRequest { |
| array<uint8>:6 peer_sta_address; |
| internal.CapabilityInfo cap_info; |
| bytes:internal.RATES_MAX_LEN rates; |
| bool qos_capable; |
| QosInfo qos_info; |
| internal.HtCapabilities? ht_cap; |
| internal.VhtCapabilities? vht_cap; |
| bytes? rsne; |
| // Serialized list of vendor IEs to be appended after all other associate request IEs. |
| bytes? vendor_ies; |
| |
| // etc |
| }; |
| |
| // MLME-ASSOCIATE.confrm (IEEE Std 802.11-2016, 6.3.7.3) |
| |
| enum AssociateResultCode { |
| SUCCESS = 0; |
| REFUSED_REASON_UNSPECIFIED = 1; |
| REFUSED_NOT_AUTHENTICATED = 2; |
| REFUSED_CAPABILITIES_MISMATCH = 3; |
| REFUSED_EXTERNAL_REASON = 4; |
| REFUSED_AP_OUT_OF_MEMORY = 5; |
| REFUSED_BASIC_RATES_MISMATCH = 6; |
| REJECTED_EMERGENCY_SERVICES_NOT_SUPPORTED = 7; |
| REFUSED_TEMPORARILY = 8; |
| }; |
| |
| struct AssociateConfirm { |
| AssociateResultCode result_code; |
| // CapabilityInformation |
| uint16 association_id; |
| |
| // TODO(fxbug.dev/43063): If we are able to intersect the capabilities with beacon before associating, |
| // remove these fields. |
| internal.CapabilityInfo cap_info; |
| bytes:internal.RATES_MAX_LEN rates; |
| WmmParameter? wmm_param; |
| internal.HtCapabilities? ht_cap; |
| internal.VhtCapabilities? vht_cap; |
| |
| // etc |
| }; |
| |
| // MLME-ASSOCIATE.indication (IEEE Std 802.11-2016, 6.3.7.4) |
| |
| struct AssociateIndication { |
| array<uint8>:6 peer_sta_address; |
| internal.CapabilityInfo cap; |
| uint16 listen_interval; |
| bytes? ssid; |
| bytes:internal.RATES_MAX_LEN rates; |
| // BSSMembershipSelectorSet |
| bytes? rsne; |
| |
| // etc |
| }; |
| |
| // MLME-ASSOCIATE.response (IEEE Std 802.11-2016, 6.3.7.5) |
| |
| struct AssociateResponse { |
| array<uint8>:6 peer_sta_address; |
| AssociateResultCode result_code; |
| |
| uint16 association_id; |
| |
| // This is not part of the MLME SAP, but we need this to set the association context state in |
| // the MLME. |
| internal.CapabilityInfo cap; |
| |
| // This combines both the BSSBasicRateSet and the OperationalRateSet, as the MLME will split |
| // them up. |
| bytes:internal.RATES_MAX_LEN rates; |
| |
| // etc |
| }; |
| |
| // MLME-DISASSOCIATE.request (IEEE Std 802.11-2016, 6.3.9.1) |
| |
| struct DisassociateRequest { |
| array<uint8>:6 peer_sta_address; |
| ieee80211.ReasonCode reason_code; |
| // VendorSpecificInfo |
| }; |
| |
| // MLME-DISASSOCIATE.confirm (IEEE Std 802.11-2016, 6.3.9.2) |
| |
| struct DisassociateConfirm { |
| int32 status; |
| }; |
| |
| // MLME-DISASSOCIATE.indication (IEEE Std 802.11-2016, 6.3.9.3) |
| |
| struct DisassociateIndication { |
| array<uint8>:6 peer_sta_address; |
| ieee80211.ReasonCode reason_code; |
| /// locally_initiated is true if diassoc is initiated from the device, |
| /// and is false if it's initiated remotely (e.g. due to disassoc frame) |
| bool locally_initiated; |
| // VendorSpecificInfo |
| }; |
| |
| // MLME-RESET.request (IEEE Std 802.11-2016, 6.3.10.2) |
| |
| struct ResetRequest { |
| array<uint8>:6 sta_address; |
| bool set_default_mib; |
| }; |
| |
| // MLME-START.request (IEEE Std 802.11-2016, 6.3.11.2) |
| |
| // See dot11CountryString of IEEE Std 802.11-2016, Annex C |
| const uint8 countryEnvironAll = 32; // an ASCII ' ' character |
| const uint8 countryEnvironOutdoor = 79; // an ASCII 'O' character |
| const uint8 countryEnvironIndoor = 73; // an ASCII 'I' character |
| const uint8 countryEnvironNonCountry = 88; // an ASCII 'X' character |
| |
| // Information derived from Country Element, IEEE Std 802.11-2016, 9.4.2.9. |
| struct Country { |
| array<uint8>:2 alpha2; // ISO 3116-1 |
| |
| // countryEnviron constant from above |
| // or Operating Class Table number from IEEE Std 802.11-2016 Annex D. |
| uint8 suffix; |
| }; |
| |
| struct StartRequest { |
| bytes:ieee80211.MAX_SSID_BYTE_LEN ssid; |
| internal.BssTypes bss_type; |
| uint16 beacon_period; // in TU |
| uint8 dtim_period; |
| |
| // PHY parameter sets |
| uint8 channel; |
| |
| // Capability information. |
| internal.CapabilityInfo cap; |
| |
| // This combines both the BSSBasicRateSet and the OperationalRateSet, as the MLME will split |
| // them up. |
| bytes:internal.RATES_MAX_LEN rates; |
| |
| // TODO(porce): Conditionally present. See IEEE Std 802.11-2016, 10.2, 11.8, 11.10. |
| // See also dot11MultiDomainCapabilityActivated. |
| Country country; |
| |
| bytes:ieee80211.MAX_MESH_ID_BYTE_LEN mesh_id; |
| |
| // TODO(hahnr): Add additional elements. |
| |
| // Although MLME-START.request is used to start a BSS, IEEE does not include an RSNE in this |
| // primitive. However, IEEE doesn't define any other primitive to configure the RSN after its |
| // BSS was started. The RSNE must be available when the BSS is started, and thus, this is the |
| // right place to transfer the RSNE to the MLME. |
| bytes? rsne; |
| |
| // Combined with what MLME knows about the device capabilities, |
| // following parameters determine what to be advertised to the peer |
| // (in Beacons/ProbeResponse/AssociationResponse). Effectively this way replaces the following |
| // fields originally defined in MLME-START.request. |
| // TODO(fxbug.dev/29529): Replace phy and cbw with full-fledged parameters below. |
| // - Capability Information |
| // - HT Capabilities |
| // - HT Operation |
| // - VHT Capabilities |
| // - VHT Operation |
| // - Extended Capabilities |
| fuchsia.wlan.common.PHY phy; |
| fuchsia.wlan.common.CBW cbw; |
| }; |
| |
| // MLME-START.confirm (IEEE Std 802.11-2016, 6.3.11.3) |
| |
| enum StartResultCode { |
| SUCCESS = 0; |
| BSS_ALREADY_STARTED_OR_JOINED = 1; |
| RESET_REQUIRED_BEFORE_START = 2; |
| NOT_SUPPORTED = 3; |
| INTERNAL_ERROR = 4; |
| }; |
| |
| struct StartConfirm { |
| StartResultCode result_code; |
| }; |
| |
| // MLME-STOP.request (IEEE Std 802.11-2016, 6.3.12.2) |
| |
| struct StopRequest { |
| bytes:ieee80211.MAX_SSID_BYTE_LEN ssid; |
| }; |
| |
| enum StopResultCode { |
| SUCCESS = 0; |
| BSS_ALREADY_STOPPED = 1; |
| INTERNAL_ERROR = 2; |
| }; |
| |
| struct StopConfirm { |
| StopResultCode result_code; |
| }; |
| |
| // MLME-SETKEYS.request (IEEE Std 802.11-2016 6.3.19.1) |
| |
| enum KeyType { |
| GROUP = 1; |
| PAIRWISE = 2; |
| PEER_KEY = 3; |
| IGTK = 4; |
| }; |
| |
| struct SetKeyDescriptor { |
| // Specs specify a bit string, we use byte array. |
| bytes key; |
| uint16 key_id; |
| KeyType key_type; |
| array<uint8>:6 address; |
| uint64 rsc; |
| array<uint8>:3 cipher_suite_oui; |
| uint8 cipher_suite_type; |
| }; |
| |
| struct SetKeysRequest { |
| vector<SetKeyDescriptor> keylist; |
| }; |
| |
| // MLME-DELETEKEYS.request (IEEE Std 802.11-2016 6.3.20.1) |
| |
| struct DeleteKeyDescriptor { |
| uint16 key_id; |
| KeyType key_type; |
| array<uint8>:6 address; |
| }; |
| |
| struct DeleteKeysRequest { |
| vector<DeleteKeyDescriptor> keylist; |
| }; |
| |
| // MLME-EAPOL.request (IEEE Std 802.11-2016 6.3.22.1) |
| |
| struct EapolRequest { |
| array<uint8>:6 src_addr; |
| array<uint8>:6 dst_addr; |
| bytes data; |
| }; |
| |
| // MLME-EAPOL.confirm (IEEE Std 802.11-2016 6.3.22.2) |
| |
| enum EapolResultCode { |
| SUCCESS = 0; |
| TRANSMISSION_FAILURE = 1; |
| //LAST = TRANSMISSION_FAILURE; |
| }; |
| |
| struct EapolConfirm { |
| EapolResultCode result_code; |
| /// This value corresponds to the dst_addr in the EapolRequest we're confirming. |
| /// IEEE 802.11-2016 does not include this field, but we need it to disambiguate |
| /// if multiple EAPoL handshakes are ongoing. |
| array<uint8>:6 dst_addr; |
| }; |
| |
| // IEEE Std 802.11-2016, 9.4.2.98 |
| struct MeshConfiguration { |
| uint8 active_path_sel_proto_id; |
| uint8 active_path_sel_metric_id; |
| uint8 congest_ctrl_method_id; |
| uint8 sync_method_id; |
| uint8 auth_proto_id; |
| uint8 mesh_formation_info; |
| uint8 mesh_capability; |
| }; |
| |
| // Fields that are common between the MPM Open and Confirm actions |
| struct MeshPeeringCommon { |
| array<uint8>:6 peer_sta_address; |
| uint16 protocol_id; |
| uint16 local_link_id; |
| bytes:32 mesh_id; |
| vector<uint8> rates; |
| MeshConfiguration mesh_config; |
| internal.HtCapabilities? ht_cap; |
| internal.HtOperation? ht_op; |
| internal.VhtCapabilities? vht_cap; |
| internal.VhtOperation? vht_op; |
| }; |
| |
| // IEEE Std 802.11-2016, 9.6.16.2.2 |
| struct MeshPeeringOpenAction { |
| MeshPeeringCommon common; |
| }; |
| |
| // IEEE Std 802.11-2016, 9.6.16.3.2 |
| struct MeshPeeringConfirmAction { |
| MeshPeeringCommon common; |
| uint16 aid; |
| uint16 peer_link_id; |
| }; |
| |
| struct MeshPeeringParams { |
| array<uint8>:6 peer_sta_address; |
| uint16 local_aid; |
| vector<uint8> rates; |
| // TODO(gbonik): HT/VHT caps |
| }; |
| |
| struct GetMeshPathTableRequest { |
| uint8 dummy; |
| }; |
| |
| // Because these methods rely on an external entity to provide a response, events are used instead |
| // of return values. |
| protocol MLME { |
| // ==== 01xxxx: scanning ==== |
| // We deviate from the spec here in order to support incremental scan |
| // results easily. We could stay closer to 802.11ai, but the protocol |
| // that is described there is more difficult to implement correctly. |
| |
| // Initiate a scan transaction. The caller is responsible for filling |
| // the `txn_id` field in `req` with a unique number that will be used |
| // to identify the transaction. |
| // |
| // Zero or more `OnScanResult` events with a matching `txn_id` will be sent |
| // in response. |
| // |
| // At the end on the transaction, whether it is successful or not, |
| // a `OnScanEnd` event with a matching `txn_id` is guaranteed to be sent |
| // in response (unless the channel is closed first). |
| // |
| // After `OnScanEnd`, no further events with the same `txn_id` shall be sent. |
| StartScan(ScanRequest req); |
| |
| // An incremental scan result containing information about a single BSS. |
| // Only one event per unique BSSID per transaction will be sent. |
| -> OnScanResult(ScanResult result); |
| |
| // An event that signals the end of a scan transaction. |
| -> OnScanEnd(ScanEnd end); |
| |
| // ==== |
| |
| JoinReq(JoinRequest req); |
| -> JoinConf(JoinConfirm resp); |
| |
| AuthenticateReq(AuthenticateRequest req); |
| -> AuthenticateConf(AuthenticateConfirm resp); |
| |
| -> AuthenticateInd(AuthenticateIndication ind); |
| AuthenticateResp(AuthenticateResponse resp); |
| |
| DeauthenticateReq(DeauthenticateRequest req); |
| -> DeauthenticateConf(DeauthenticateConfirm resp); |
| |
| -> DeauthenticateInd(DeauthenticateIndication ind); |
| |
| AssociateReq(AssociateRequest req); |
| -> AssociateConf(AssociateConfirm resp); |
| |
| -> AssociateInd(AssociateIndication ind); |
| AssociateResp(AssociateResponse resp); |
| |
| DisassociateReq(DisassociateRequest req); |
| -> DisassociateConf(DisassociateConfirm resp); |
| |
| -> DisassociateInd(DisassociateIndication ind); |
| |
| ResetReq(ResetRequest req); |
| |
| StartReq(StartRequest req); |
| -> StartConf(StartConfirm resp); |
| |
| StopReq(StopRequest req); |
| -> StopConf(StopConfirm resp); |
| |
| SetKeysReq(SetKeysRequest req); |
| |
| DeleteKeysReq(DeleteKeysRequest req); |
| |
| EapolReq(EapolRequest req); |
| -> EapolConf(EapolConfirm resp); |
| |
| // The following are extensions to the 802.11 MLME SAP interface. |
| |
| // ==== Mesh === |
| -> IncomingMpOpenAction(MeshPeeringOpenAction action); |
| SendMpOpenAction(MeshPeeringOpenAction action); |
| -> IncomingMpConfirmAction(MeshPeeringConfirmAction action); |
| SendMpConfirmAction(MeshPeeringConfirmAction action); |
| |
| MeshPeeringEstablished(MeshPeeringParams peering); |
| |
| GetMeshPathTableReq(GetMeshPathTableRequest req) -> (fuchsia.wlan.mesh.MeshPathTable table); |
| |
| -> SignalReport(SignalReportIndication ind); |
| |
| -> EapolInd(EapolIndication ind); |
| SetControlledPort(SetControlledPortRequest req); |
| |
| QueryDeviceInfo() -> (DeviceInfo info); |
| |
| StatsQueryReq(); |
| -> StatsQueryResp(StatsQueryResponse resp); |
| |
| ListMinstrelPeers() -> (MinstrelListResponse resp); |
| GetMinstrelStats(MinstrelStatsRequest req) -> (MinstrelStatsResponse resp); |
| |
| StartCaptureFrames(StartCaptureFramesRequest req) -> (StartCaptureFramesResponse resp); |
| StopCaptureFrames(); |
| -> RelayCapturedFrame(CapturedFrameResult result); |
| |
| -> OnChannelSwitched(ChannelSwitchInfo info); |
| |
| -> OnPmkAvailable(PmkInfo info); |
| |
| // === Messages for managing SAE authentication inside SME === |
| // MLME notification that SME will handle authentication. |
| -> OnSaeHandshakeInd(SaeHandshakeIndication ind); |
| // SME notification that authentication is completed. |
| SaeHandshakeResp(SaeHandshakeResponse resp); |
| SaeFrameTx(SaeFrame frame); |
| -> OnSaeFrameRx(SaeFrame frame); |
| |
| WmmStatusReq(); |
| -> OnWmmStatusResp(int32 status, internal.WmmStatusResponse resp); |
| |
| // For SoftMAC drivers only. Let SME inform MLME about the capability negotiation outcome. |
| // TODO(fxbug.dev/43063): If we are able to intersect the capabilities with beacon before associating, |
| // remove this function and the capabilities from AssociateConfirm and use AssociateRequest. |
| FinalizeAssociationReq(NegotiatedCapabilities cap); |
| }; |
| |
| // Temporary interface for bridging between the devhost-owned channel model and |
| // the driver-owned channel model of connection management. |
| /// This protocol is used to connect to the interface's underlying MLME. |
| [ForDeprecatedCBindings] |
| protocol Connector { |
| Connect(request<MLME> request); |
| }; |