// Copyright 2018 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;
using fuchsia.wlan.mesh;

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

struct BssInfo {
    array<uint8>:6 bssid;
    vector<uint8>:32 ssid;
    int8 rssi_dbm;
    int8 snr_db;
    fuchsia.wlan.common.WlanChan channel;
    Protection protection;
    bool compatible;
};

enum ScanErrorCode {
    NOT_SUPPORTED = 1;
    INTERNAL_ERROR = 2;
};

struct ScanError {
    ScanErrorCode code;
    string message;
};

protocol ScanTransaction {
    // Can be called several times to deliver incremental scan results
    -> OnResult(vector<BssInfo> aps);
    -> OnFinished();
    -> OnError(ScanError error);
};

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

struct PassiveScanRequest {
};

struct ActiveScanRequest {
    // The SSIDs to scan for. Leave empty for a wildcard active scan.
    vector<vector<uint8>:32>:16 ssids;
    // Channels to scan on. Leave empty for all supported channels.
    vector<uint8>:500 channels;
};

enum ConnectResultCode {
    // Connected successfully
    SUCCESS = 0;
    // The request was superseded by another connect or disconnect command
    CANCELED = 1;
    // Failed to join for some reason
    FAILED = 2;
    // Failed to join because the authenticator rejected the credentials.
    CREDENTIAL_REJECTED = 3;
};

protocol ConnectTransaction {
    // Could add more events here to notify the client of the progress
    -> OnFinished(ConnectResultCode code);
};

struct RadioConfig {
    bool override_phy;
    fuchsia.wlan.common.PHY phy;
    bool override_cbw;
    fuchsia.wlan.common.CBW cbw;
    bool override_primary_chan;
    uint8 primary_chan;
};

/// Empty struct used as credential value for open networks.
struct Empty {
};

/// Information required to connect to a protected network.
flexible union Credential {
    /// The network does not use credentials (open networks).
    1: Empty none;

    /// Plaintext password (handled as binary data).
    2: bytes password;

    /// Hash representation of the network passphrase (handled as binary data).
    3: bytes psk;
};

struct ConnectRequest {
    vector<uint8>:32 ssid;
    Credential credential;

    RadioConfig radio_cfg;
    /// 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.
    fuchsia.wlan.common.ScanType deprecated_scan_type;
};

struct ClientStatusResponse {
    BssInfo? connected_to;
    // If non-empty, this is the SSID we are currently trying to connect to
    vector<uint8>:32 connecting_to_ssid;
};

protocol ClientSme {
    Scan(ScanRequest req, request<ScanTransaction> txn);
    Connect(ConnectRequest req, request<ConnectTransaction>? txn);
    Disconnect() -> ();
    Status() -> (ClientStatusResponse resp);
};

struct ApConfig {
    vector<uint8>:32 ssid;
    vector<uint8>:64 password;
    RadioConfig radio_cfg;
};

enum StartApResultCode {
    // TODO(porce): Fix naming style.
    SUCCESS = 0;
    ALREADY_STARTED = 1;
    INTERNAL_ERROR = 2;
    CANCELED = 3;
    TIMED_OUT = 4;
    PREVIOUS_START_IN_PROGRESS = 5;
    INVALID_ARGUMENTS = 6;
    DFS_UNSUPPORTED = 7;
};

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

struct Ap {
    vector<uint8>:32 ssid;
    uint8 channel;
    uint16 num_clients;
};

struct ApStatusResponse {
    Ap? running_ap;
};

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

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

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

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

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

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