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

using fuchsia.wlan.common.security;
using fuchsia.wlan.common;
using fuchsia.wlan.ieee80211 as ieee80211;
using fuchsia.wlan.internal;
using fuchsia.wlan.mesh;
using fuchsia.wlan.stats;
using zx;

/// Security protection which should mirror the Protection enum defined in wlan lib common
type Protection = strict enum {
    UNKNOWN = 0;
    OPEN = 1;
    WEP = 2;
    WPA1 = 3;
    WPA1_WPA2_PERSONAL_TKIP_ONLY = 4;
    WPA2_PERSONAL_TKIP_ONLY = 5;
    WPA1_WPA2_PERSONAL = 6;
    WPA2_PERSONAL = 7;
    WPA2_WPA3_PERSONAL = 8;
    WPA3_PERSONAL = 9;
    WPA2_ENTERPRISE = 10;
    WPA3_ENTERPRISE = 11;
};

type UserDisconnectReason = strict enum {
    UNKNOWN = 0;
    FAILED_TO_CONNECT = 1;
    FIDL_CONNECT_REQUEST = 2;
    FIDL_STOP_CLIENT_CONNECTIONS_REQUEST = 3;
    PROACTIVE_NETWORK_SWITCH = 4;
    DISCONNECT_DETECTED_FROM_SME = 5;
    REGULATORY_REGION_CHANGE = 6;
    STARTUP = 7;
    NETWORK_UNSAVED = 8;
    NETWORK_CONFIG_UPDATED = 9;

    // The following reasons should only be used for development and testing.
    WLANSTACK_UNIT_TESTING = 124;
    WLAN_SME_UNIT_TESTING = 125;
    WLAN_SERVICE_UTIL_TESTING = 126;
    WLAN_DEV_TOOL = 127;
};

type DisconnectCause = struct {
    mlme_event_name DisconnectMlmeEventName;
    reason_code ieee80211.ReasonCode;
};

type DisconnectMlmeEventName = strict enum {
    DEAUTHENTICATE_INDICATION = 1;
    DISASSOCIATE_INDICATION = 2;
};

type DisconnectSource = strict union {
    1: ap DisconnectCause;
    2: user UserDisconnectReason;
    3: mlme DisconnectCause;
};

// Compatibility of a BSS with respect to a scanning interface.
//
// When a BSS is compatible with a scanning interface, this type describes the
// mutually supported modes of operation than can be used to establish a
// connection, such as the compatible set of security protocols.
//
// The data provided by this type is only applicable or meaningful when the
// local scanning interface is compatible with a BSS. As such, it is a logic
// error to construct or transmit this type with data that implies
// incompatibility.
//
// See `ScanResult`.
type Compatibility = struct {
    // Mutually supported security protocols.
    //
    // This field describes the intersection of security protocols supported by
    // a remote BSS and a local scanning interface. In this context an empty set
    // is a logic error (implies incompatibility) and so this field must never
    // be empty.
    mutual_security_protocols vector<fuchsia.wlan.common.security.Protocol>:16;
};

// Describes a BSS detected by a scan.
type ScanResult = struct {
    // The compatibility of the scanning interface and a BSS.
    //
    // If this field is absent, then the scanning interface and BSS are
    // incompatible and will not be able to establish a connection.
    compatibility box<Compatibility>;
    // Time of the scan result relative to when the system was powered on.
    // See https://fuchsia.dev/fuchsia-src/concepts/time/language_support#monotonic_time
    timestamp_nanos zx.Time;
    // Describes the BSS detected by the scan.
    bss_description fuchsia.wlan.internal.BssDescription;
};

type ScanErrorCode = strict enum {
    NOT_SUPPORTED = 1;
    INTERNAL_ERROR = 2;
    INTERNAL_MLME_ERROR = 3;
    SHOULD_WAIT = 4;
    CANCELED_BY_DRIVER_OR_FIRMWARE = 5;
};

type ScanRequest = strict union {
    1: active ActiveScanRequest;
    2: passive PassiveScanRequest;
};

type PassiveScanRequest = struct {};

type ActiveScanRequest = struct {
    /// List of SSIDs to scan for. An empty list of ssids is the same as specifying
    /// a list containing only the wildcard SSID.
    ///
    /// There is no limit on the number of SSIDs specified, but a large number of
    /// SSIDs may result in extended scan times or the error ZX_ERR_INVALID_ARGS to be
    /// returned.
    ssids vector<ieee80211.Ssid>:MAX;
    // TODO(fxbug.dev/89348): SME should instead require the higher layer to specify
    // which channels to scan and return an error if the list is empty.
    /// Channels to scan on. Leave empty for all supported channels.
    channels vector<uint8>:500;
};

type ConnectResult = struct {
    code ieee80211.StatusCode;
    /// `is_credential_rejected` is true if connect failure is likely due to wrong credential.
    /// Policy uses this to determine whether to retry with the same password.
    is_credential_rejected bool;
    /// If `is_reconnect` is false, the result comes from the initial connection request.
    /// If it's true, the result comes from an SME-initiated reconnection.
    is_reconnect bool;
};

type DisconnectInfo = struct {
    /// Whether SME is attempting to reconnect by itself
    is_sme_reconnecting bool;
    /// Where the disconnect originated and associated reason
    disconnect_source DisconnectSource;
};

protocol ConnectTransaction {
    /// Return the result of the initial connection request or later SME-initiated reconnection.
    -> OnConnectResult(struct {
        result ConnectResult;
    });

    /// Notify that the client has disconnected. If DisconnectInfo indicates that SME is
    /// attempting to reconnect by itself, there's not need for caller to intervene for now.
    -> OnDisconnect(struct {
        info DisconnectInfo;
    });

    /// Give an update of the latest signal report.
    -> OnSignalReport(struct {
        ind fuchsia.wlan.internal.SignalReportIndication;
    });

    /// Give an update of the channel switching.
    -> OnChannelSwitched(struct {
        info fuchsia.wlan.internal.ChannelSwitchInfo;
    });
};

type RadioConfig = struct {
    phy fuchsia.wlan.common.WlanPhyType;
    channel fuchsia.wlan.common.WlanChannel;
};

/// Empty struct used for union variants with no associated data.
type Empty = struct {};

type ConnectRequest = struct {
    ssid ieee80211.Ssid;
    bss_description fuchsia.wlan.internal.BssDescription;
    /// Informs SME whether multiple candidates were available, for metrics.
    multiple_bss_candidates bool;
    /// Authentication method.
    ///
    /// Describes how SME authenticates when connecting to the target network.
    authentication fuchsia.wlan.common.security.Authentication;

    /// Deprecated. SME makes internal decision on whether to perform a passive or active
    /// scan during connect. Setting this field will not affect anything for FullMAC, but
    /// currently SoftMAC still honor this argument.
    deprecated_scan_type fuchsia.wlan.common.ScanType;
};

type ServingApInfo = struct {
    bssid ieee80211.MacAddr;
    ssid ieee80211.Ssid;
    rssi_dbm int8;
    snr_db int8;
    channel fuchsia.wlan.common.WlanChannel;
    protection Protection;
};

type ClientStatusResponse = strict union {
    1: connected ServingApInfo;
    2: connecting ieee80211.Ssid;
    3: idle Empty;
};

protocol ClientSme {
    // TODO(fxbug.dev/100478): Remove this denylist when support
    // for other languages is complete.
    @bindings_denylist("cpp, dart, go, hlcpp, llcpp")
    @experimental_overflowing(response=true)
    Scan(resource struct {
        req ScanRequest;
    }) -> (struct {
        scan_results vector<ScanResult>;
    }) error ScanErrorCode;
    Connect(resource struct {
        req ConnectRequest;
        txn server_end:<ConnectTransaction, optional>;
    });
    Disconnect(struct {
        reason UserDisconnectReason;
    }) -> ();
    Status() -> (struct {
        resp ClientStatusResponse;
    });
    WmmStatus() -> (struct {
        resp fuchsia.wlan.internal.WmmStatusResponse;
    }) error int32;
};

type ApConfig = struct {
    ssid ieee80211.Ssid;
    password vector<uint8>:64;
    radio_cfg RadioConfig;
};

type StartApResultCode = strict enum {
    SUCCESS = 0;
    ALREADY_STARTED = 1;
    INTERNAL_ERROR = 2;
    CANCELED = 3;
    TIMED_OUT = 4;
    PREVIOUS_START_IN_PROGRESS = 5;
    INVALID_ARGUMENTS = 6;
};

type StopApResultCode = strict enum {
    SUCCESS = 0;
    INTERNAL_ERROR = 1;
    TIMED_OUT = 2;
};

type Ap = struct {
    ssid ieee80211.Ssid;
    channel uint8;
    num_clients uint16;
};

type ApStatusResponse = struct {
    running_ap box<Ap>;
};

protocol ApSme {
    Start(struct {
        config ApConfig;
    }) -> (struct {
        code StartApResultCode;
    });
    Stop() -> (struct {
        code StopApResultCode;
    });
    Status() -> (struct {
        resp ApStatusResponse;
    });
};

type MeshConfig = struct {
    mesh_id vector<uint8>:32;
    channel uint8;
};

type JoinMeshResultCode = strict enum {
    SUCCESS = 0;
    CANCELED = 1;
    INTERNAL_ERROR = 2;
    INVALID_ARGUMENTS = 3;
    DFS_UNSUPPORTED = 4;
};

type LeaveMeshResultCode = strict enum {
    SUCCESS = 0;
    INTERNAL_ERROR = 1;
};

type GetMeshPathTableResultCode = strict enum {
    SUCCESS = 0;
    INTERNAL_ERROR = 1;
};

protocol MeshSme {
    Join(struct {
        config MeshConfig;
    }) -> (struct {
        code JoinMeshResultCode;
    });
    Leave() -> (struct {
        code LeaveMeshResultCode;
    });
    GetMeshPathTable() -> (struct {
        code GetMeshPathTableResultCode;
        path fuchsia.wlan.mesh.MeshPathTable;
    });
};

protocol Telemetry {
    GetCounterStats() -> (struct {
        stats fuchsia.wlan.stats.IfaceCounterStats;
    }) error zx.Status;
    GetHistogramStats() -> (struct {
        stats fuchsia.wlan.stats.IfaceHistogramStats;
    }) error zx.Status;
};

protocol FeatureSupport {
    /// Return support for features related to discovery of potential BSSs.
    /// * see [`fuchsia.wlan.common/DiscoverySupport`]
    QueryDiscoverySupport() -> (struct {
        resp fuchsia.wlan.common.DiscoverySupport;
    }) error zx.Status;

    /// Return support for features related to the MAC sublayer.
    /// * see [`fuchsia.wlan.common/MacSublayerSupport`]
    QueryMacSublayerSupport() -> (struct {
        resp fuchsia.wlan.common.MacSublayerSupport;
    }) error zx.Status;

    /// Return support for features related to security/access control
    /// and data confidentiality.
    /// * see [`fuchsia.wlan.common/SecuritySupport`]
    QuerySecuritySupport() -> (struct {
        resp fuchsia.wlan.common.SecuritySupport;
    }) error zx.Status;

    /// Return support for features related to spectrum management.
    /// * see [`fuchsia.wlan.common/SpectrumManagementSupport`]
    QuerySpectrumManagementSupport() -> (struct {
        resp fuchsia.wlan.common.SpectrumManagementSupport;
    }) error zx.Status;
};

type LegacyPrivacySupport = struct {
    wep_supported bool;
    wpa1_supported bool;
};

protocol UsmeBootstrap {
    Start(resource struct {
        generic_sme_server server_end:GenericSme;
        legacy_privacy_support LegacyPrivacySupport;
    }) -> (resource struct {
        inspect_vmo zx.Handle:VMO;
    });
};

// High level SME info independent of the current MAC role.
type GenericSmeQuery = struct {
    role fuchsia.wlan.common.WlanMacRole;
    sta_addr ieee80211.MacAddr;
};

protocol GenericSme {
    /// Query the underlying SME to determine basic properties. This should
    /// generally be called first to determine which SME protocol to request
    /// for the SME.
    Query() -> (resource struct {
        resp GenericSmeQuery;
    });
    /// Attempt to establish a new connection to an underlying Client SME.
    /// Connections may be established for the whole lifetime of the SME,
    /// but concurrent connections might lead to unexpected behavior.
    /// Likely errors include:
    ///     * NOT_SUPPORTED: The underlying SME is not a Client SME.
    ///     * PEER_CLOSED: The underlying SME is shutting down.
    GetClientSme(resource struct {
        sme_server server_end:ClientSme;
    }) -> () error zx.Status;
    /// Attempt to establish a new connection to an underlying AP SME.
    /// Connections may be established for the whole lifetime of the SME,
    /// but concurrent connections might lead to unexpected behavior.
    /// Likely errors include:
    ///     * NOT_SUPPORTED: The underlying SME is not an AP SME.
    ///     * PEER_CLOSED: The underlying SME is shutting down.
    GetApSme(resource struct {
        sme_server server_end:ApSme;
    }) -> () error zx.Status;
    /// Attempt to establish a new connection to telemetry information for the
    /// underlying SME.
    /// Connections may be established for the whole lifetime of the SME, and
    /// concurrent connections are safe since this is a read-only API.
    /// Likely errors include:
    ///     * NOT_SUPPORTED: The underlying SME does not support telemetry.
    ///     * PEER_CLOSED: The underlying SME is shutting down.
    GetSmeTelemetry(resource struct {
        telemetry_server server_end:Telemetry;
    }) -> () error zx.Status;
    /// Attempt to establish a new connection to feature support information for
    /// the underlying SME.
    /// Connections may be established for the whole lifetime of the SME, and
    /// concurrent connections are safe since this is a read-only API.
    /// Likely errors include:
    ///     * PEER_CLOSED: The underlying SME is shutting down.
    GetFeatureSupport(resource struct {
        feature_support_server server_end:FeatureSupport;
    }) -> () error zx.Status;
};
