// 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.stats;
using fuchsia.wlan.minstrel;

// 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.

// SIGNAL_REPORT.indication

struct SignalReportIndication {
    int8 rssi_dbm;
};

// EAPOL.indication

struct EapolIndication {
    array<uint8>:6 src_addr;
    array<uint8>:6 dst_addr;
    bytes data;
};

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

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

    CapabilityInfo cap;
    HtCapabilities? ht_cap;
    VhtCapabilities? vht_cap;
};

struct DeviceInfo {
    array<uint8>:6 mac_addr;
    MacRole role;
    vector<BandCapabilities> bands;
    vector<fuchsia.wlan.common.DriverFeature>:32 driver_features;
};

// STATS_QUERY.response

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

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

struct MinstrelStatsRequest {
    array<uint8>:6 mac_addr;
};

struct MinstrelStatsResponse {
    fuchsia.wlan.minstrel.Peer? peer;
};

// SET_CONTROLLED_PORT.request

struct SetControlledPortRequest {
    array<uint8>:6 peer_sta_address;
    ControlledPortState state;
};

enum ControlledPortState {
    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
bits MgmtFrameCaptureFlags : 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;
};

struct StartCaptureFramesRequest {
    MgmtFrameCaptureFlags mgmt_frame_flags;
};

struct StartCaptureFramesResponse {
    int32 status;
    MgmtFrameCaptureFlags supported_mgmt_frames;
};

struct CapturedFrameResult {
    bytes frame;
};

// IEEE 802.11-2016 9.4.2.19
// Unlike a normal channel switch announcement, a ChannelSwitchInfo is sent at the time the channel
// changes and does not include a delay field.
struct ChannelSwitchInfo {
    uint8 new_channel;
    // The operating class/country may also be modified by an extended channel switch request, but
    // we do not currently support this.
};

// Method ordinals are defined in wlan_mlme.fidl to prevent error prone overlaps with official
// MLME primitives.
