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

/// Acronyms \
/// Iface:  Interface \
/// Phy:    Physical \
/// Mac:    Medium Access Control \
/// Sta:    Station \
/// Addr:   Address
@available(added=15)
library fuchsia.wlan.phyimpl;

using fuchsia.wlan.common;
using fuchsia.wlan.ieee80211 as ieee80211;
using zx;

const WLANPHY_ALPHA2_LEN uint8 = 2;

type WlanPhyCountry = flexible union {
    /// ISO Alpha-2 takes two octet alphabet characters.
    /// This needs to be expanded if at least one WLAN device driver or firmware
    /// requires more than two octets.
    1: alpha2 array<uint8, WLANPHY_ALPHA2_LEN>;
};

@discoverable
@transport("Driver")
closed protocol WlanPhyImpl {
    /// MAC roles supported for ifaces on the physical device.
    strict GetSupportedMacRoles() -> (table {
        1: supported_mac_roles
                vector<fuchsia.wlan.common.WlanMacRole>:fuchsia.wlan.common.MAX_SUPPORTED_MAC_ROLES;
    }) error zx.Status;

    /// Create a new interface with the specified role, returning the interface id. \
    /// Some common error codes are: \
    /// ZX_ERR_NO_RESOURCES: maximum number of interfaces have already been created. \
    /// ZX_ERR_NOT_SUPPORTED: device does not support the specified role.
    strict CreateIface(resource table {
        /// The station role for this interface. A device may support multiple roles,
        /// but an interface is instantiated with a single role. This field is required.
        1: role fuchsia.wlan.common.WlanMacRole;
        /// A handle to the direct MLME channel, if supported by the driver. This
        /// channel should be used by SME to communicate with MLME via the MLME
        /// protocol. This field is required.
        2: mlme_channel zx.Handle:CHANNEL;
        /// The initial station address set from configuration layer. This field is optional.
        3: init_sta_addr ieee80211.MacAddr;
    }) -> (table {
        /// This field is always present.
        1: iface_id uint16;
    }) error zx.Status;

    /// Destroy the interface with the matching id. \
    /// Some common error codes are: \
    /// ZX_ERR_NOT_FOUND: Specified iface does not exist or has already been removed. \
    /// ZX_ERR_SHOULD_WAIT: Device is busy and cannot be removed, try again later.
    strict DestroyIface(table {
        /// This field is required.
        1: iface_id uint16;
    }) -> () error zx.Status;

    /// Set country with a WlanPhyCountry. \
    /// Some common error codes are: \
    /// ZX_ERR_NOT_FOUND: Specified country code not supported. PHY state is left unchanged.
    strict SetCountry(WlanPhyCountry) -> () error zx.Status;

    /// Set device to a world-safe country, i.e. a mode that conforms to all
    /// regulatory constraints globally. \
    /// Generally expected to succeed if the device is in a functional state.
    strict ClearCountry() -> () error zx.Status;

    /// Read currently configured country. Implementations are advised to read the
    /// country directly from the firmware, where possible. \
    /// Generally expected to succeed if the device is in a functional state.
    strict GetCountry() -> (WlanPhyCountry) error zx.Status;

    /// Set Power Save mode on device. In most implementations this
    /// likely to be set in Firmware. \
    /// Some common error codes are: \
    /// ZX_ERR_NOT_SUPPORTED: Specified Power Save mode not supported.
    strict SetPowerSaveMode(table {
        /// This field is required.
        1: ps_mode fuchsia.wlan.common.PowerSaveType;
    }) -> () error zx.Status;

    /// Get current Power Save mode from device. In most implementation this
    /// likely to be retrieved from Firmware.
    strict GetPowerSaveMode() -> (table {
        /// This field is required.
        1: ps_mode fuchsia.wlan.common.PowerSaveType;
    }) error zx.Status;
};

service Service {
    wlan_phy_impl client_end:WlanPhyImpl;
};
