// 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.
library fuchsia.starnix.binder;

using zx;
using fuchsia.posix;

const MAX_PATH_LENGTH uint64 = 4095;
const MAX_REQUEST_COUNT uint64 = 16;

alias Fd = int32;

/// The flags associated with an opened file.
type FileFlags = flexible bits : uint64 {
    // Permissions
    /// The owner can read the file.
    RIGHT_READABLE = 0b1;
    /// The owner can write to fhe file.
    RIGHT_WRITABLE = 0b10;
    // Skipping bits for exec and suid bits and for group and other mode if
    // they are needed in the future.

    // File type
    /// The file is a directory.
    DIRECTORY = 0b1000000000000;
};

/// The representation of an open file that can be transferred between the
/// binder device driver and the client.
type FileHandle = resource struct {
    /// The handle connecting to the file protocol. If not present, the file
    /// should behave as it is was a null file: all read must succeed with empty
    /// content and all write must succeed. See `fdio_fd_create_null()`.
    file zx.Handle:<optional>;

    /// The flags associated with the opened file.
    flags FileFlags;
};

/// Protocol that gives the binder driver access to the client process'
/// resources.
open protocol ProcessAccessor {
    /// Writes the contents of `content` to `address` in the process memory,
    /// using the vmo content size to determine the number of bytes to write.
    flexible WriteMemory(resource struct {
        address uint64;
        content zx.Handle:VMO;
    }) -> () error fuchsia.posix.Errno;

    /// Execute the given `request` and returns the associated `response`. Any
    /// failure will interrupt further processing and fail this operation and
    /// the associated errno will be then returned.
    /// The implementator of this protocol should handle these requests as best
    /// it can so that a failure doesn't have visible side-effects.
    flexible FileRequest(@generated_name("FileRequest") resource table {
        /// The list of file descriptor the client must close.
        1: close_requests vector<Fd>:MAX_REQUEST_COUNT;
        /// The list of file descriptor the client must duplicate and transfer to
        /// the binder driver.
        2: get_requests vector<Fd>:MAX_REQUEST_COUNT;
        /// The list of open file the client must add to its fd table, returning
        /// the new minted file descriptors.
        3: add_requests vector<FileHandle>:MAX_REQUEST_COUNT;
    }) -> (@generated_name("FileResponse") resource table {
        // (No ordinal 1 since there is no response for the close operation.)
        /// The list of open file retriever for the `get_requests`.
        2: get_responses vector<FileHandle>:MAX_REQUEST_COUNT;
        /// The list of file descriptors minted for the `add_requests`.
        3: add_responses vector<Fd>:MAX_REQUEST_COUNT;
    }) error fuchsia.posix.Errno;
};

/// Give access to the binder nodes.
@discoverable
open protocol DevBinder {
    /// Open the binder device node.
    flexible Open(resource table {
        /// The path to the binder device in the starnix process.
        /// Mandatory
        1: path vector<uint8>:MAX_PATH_LENGTH;

        /// The service giving the binder driver access to the resources of the client process.
        2: process_accessor client_end:ProcessAccessor;

        /// The handle to the process that will use the binder driver. It is
        /// used by the driver to read the data sent to the driver.
        /// Mandatory
        3: process zx.Handle:PROCESS;

        /// The request to the Binder protocol implementation.
        /// Mandatory
        4: binder server_end:Binder;
    });

    /// Close the binder device node, previously opened with `Open`. The handle
    /// is passed back to the service so that it can identify the device being
    /// closed.
    flexible Close(resource table {
        /// The Binder protocol opened previously.
        1: binder client_end:Binder;
    });
};

/// Protocol that allows Starnix to control binder servers and clients in other
/// Fuchsia components.
@discoverable
open protocol RemoteController {
    /// Called by the Starnix kernel when it requires the remote Fuchsia
    /// component to start servicing the binder protocol.
    flexible Start(resource table {
        1: dev_binder client_end:DevBinder;
        2: lutex_controller client_end:LutexController;
    });
};

/// Protocol that allows a Fuchsia component to interact with the Linux futexes
/// of a process running inside starnix.
@discoverable
open protocol LutexController {
    /// FUTEX_WAIT_BITSET command
    flexible WaitBitset(@generated_name("WaitBitsetRequest") resource table {
        /// The vmo containing the shared address of the futex.
        /// Mandatory
        1: vmo zx.Handle:VMO;
        /// The offset in the vmo where the shared address of the futex is.
        /// Mandatory
        2: offset uint64;
        /// The expected value of the futex.
        /// Mandatory
        3: value uint32;
        /// The bit mask.
        /// Optional. If not present, as mask with all bits present will be used.
        4: mask uint32;
        /// The deadline for the wait operation.
        /// Optional. If not present, the operation can block indefinitely.
        5: deadline zx.Time;
    }) -> () error fuchsia.posix.Errno;

    /// FUTEX_WAKE_BITSET command
    flexible WakeBitset(@generated_name("WakeBitsetRequest") resource table {
        /// The vmo containing the shared address of the futex.
        /// Mandatory
        1: vmo zx.Handle:VMO;
        /// The offset in the vmo where the shared address of the futex is.
        /// Mandatory
        2: offset uint64;
        /// Maximum number of waiter to wake.
        /// Mandatory
        3: count uint32;
        /// The bit mask.
        /// Optional. If not present, as mask with all bits present will be used.
        4: mask uint32;
    }) -> (@generated_name("WakeResponse") resource table {
        /// The number of waiters that were woken up.
        1: count uint64;
    }) error fuchsia.posix.Errno;
};

/// An opened connection to a binder driver.
open protocol Binder {
    /// Set the VMO to used as a share resource between the driver and the
    /// client. `mapped_address` is the address where the vmo is mapped in the
    /// client address space.
    flexible SetVmo(resource struct {
        vmo zx.Handle:VMO;
        mapped_address uint64;
    });
    flexible Ioctl(struct {
        tid zx.Koid;
        request uint32;
        parameter uint64;
    }) -> () error fuchsia.posix.Errno;
};
