// Copyright 2021 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.internal as internal;
using fuchsia.wlan.stats;
using fuchsia.wlan.minstrel;
using zx;

// Custom primitives for communicating between the wlan service and the MLME drivers.
// The primitives defined here are not part of the official 802.11 MLME SAP interface specification,
// but follow the same principle for the sake of consistency.

// EAPOL.indication

type EapolIndication = struct {
    src_addr ieee80211.MacAddr;
    dst_addr ieee80211.MacAddr;
    data bytes;
};

type MacRole = strict enum {
    CLIENT = 1;
    AP = 2;
    MESH = 3;
};

// BandInfo groups capabilities defined per band.
// This grouping is the industry's de factor standard.
type BandCapabilities = struct {
    band_id fuchsia.wlan.common.Band;
    rates bytes:internal.RATES_MAX_LEN;
    base_frequency uint16;
    channels bytes;

    capability_info internal.CapabilityInfo;
    ht_cap box<internal.HtCapabilities>;
    vht_cap box<internal.VhtCapabilities>;
};

type DeviceInfo = struct {
    sta_addr ieee80211.MacAddr;
    role MacRole;
    bands vector<BandCapabilities>;
    driver_features vector<fuchsia.wlan.common.DriverFeature>:32;
    qos_capable bool;
};

// SETKEYS.confirm
// IEEE Std 802.11-2016 6.3.20.1 does not specify this primitive, but in practice
// the SetKeys operation can sometimes fail. We return a list of results, since
// multiple keys may be set at once and result in partial failure.

type SetKeyResult = struct {
    key_id uint16;
    status zx.status;
};

type SetKeysConfirm = struct {
    results vector<SetKeyResult>;
};

// STATS_QUERY.response

type StatsQueryResponse = struct {
    stats fuchsia.wlan.stats.IfaceStats;
};

// TODO(fxbug.dev/83621): Move this to wlan_internal.fidl after fxbug.dev/85462 is fixed
type GetIfaceCounterStatsResponse = strict union {
    1: stats fuchsia.wlan.stats.IfaceCounterStats;
    2: error_status int32;
};

// TODO(fxbug.dev/83621): Move this to wlan_internal.fidl after fxbug.dev/85462 is fixed
type GetIfaceHistogramStatsResponse = strict union {
    1: stats fuchsia.wlan.stats.IfaceHistogramStats;
    2: error_status int32;
};

type MinstrelListResponse = struct {
    peers fuchsia.wlan.minstrel.Peers;
};

type MinstrelStatsRequest = struct {
    peer_addr ieee80211.MacAddr;
};

type MinstrelStatsResponse = struct {
    peer box<fuchsia.wlan.minstrel.Peer>;
};

// SET_CONTROLLED_PORT.request

type SetControlledPortRequest = struct {
    peer_sta_address ieee80211.MacAddr;
    state ControlledPortState;
};

type ControlledPortState = strict enum {
    CLOSED = 0;
    OPEN = 1;
};

// START_CAPTURE_FRAMES.request

/// Bits used to request management frame subtypes to be captured. Also used in
/// StartCaptureFramesResponse to indicate what management frames are supported.
///
/// These values are set at `1 << MgmtFrameSubtypeValue`
/// See IEEE Std 802.11-2016, 9.2.4.1.3, for value of each management frame subtype
type MgmtFrameCaptureFlags = strict bits : uint32 {
    ASSOC_REQ = 0x1;
    ASSOC_RESP = 0x2;
    REASSOC_REQ = 0x4;
    REASSOC_RESP = 0x8;
    PROBE_REQ = 0x10;
    PROBE_RESP = 0x20;
    TIMING_AD = 0x40;
    BEACON = 0x100;
    ATIM = 0x200;
    DISASSOC = 0x400;
    AUTH = 0x800;
    DEAUTH = 0x1000;
    ACTION = 0x2000;
    ACTION_NO_ACK = 0x4000;
};

type StartCaptureFramesRequest = struct {
    mgmt_frame_flags MgmtFrameCaptureFlags;
};

type StartCaptureFramesResponse = struct {
    status int32;
    supported_mgmt_frames MgmtFrameCaptureFlags;
};

type CapturedFrameResult = struct {
    frame bytes;
};

/// Non-IEEE custom structure to inform a SoftMAC device about the association negotiation outcome.
// TODO(fxbug.dev/43063): Remove if we are able to intersect the capabilities with beacon before associating
type NegotiatedCapabilities = struct {
    channel fuchsia.wlan.common.WlanChannel;
    capability_info internal.CapabilityInfo;
    rates bytes:internal.RATES_MAX_LEN;
    wmm_param box<WmmParameter>;
    ht_cap box<internal.HtCapabilities>;
    vht_cap box<internal.VhtCapabilities>;
};

type PmkInfo = struct {
    pmk bytes;
    pmkid bytes;
};

type SaeHandshakeIndication = struct {
    peer_sta_address ieee80211.MacAddr;
};

type SaeHandshakeResponse = struct {
    peer_sta_address ieee80211.MacAddr;
    status_code ieee80211.StatusCode;
};

type SaeFrame = struct {
    peer_sta_address ieee80211.MacAddr;
    status_code ieee80211.StatusCode;
    seq_num uint16;
    sae_fields bytes;
};
