// 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.device.manager;

// TODO(teisenbe): Move these interfaces to be internal to the devmgr codebase

using zx;

/// This has the same structure as zx_device_prop_t.
struct DeviceProperty {
    uint16 id;
    uint16 reserved;
    uint32 value;
};

// TODO(bwb): Make this descriptive of binding, not zx_bind_inst_t
// currently a magic bitfield defined in binding.h
struct BindInstruction {
    /// bitfield that encodes the operation and execution conditions
    uint32 op;
    /// bitfield that encodes the arguments
    uint32 arg;
    /// bitfield that encodes debugging information
    uint32 debug;
};

// Identifier used to let the devcoordinator describe specific devices during
// composite construction
using LocalDeviceId = uint64;

/// This definition must match `ZX_DEVICE_NAME_MAX` and is checked by a static assert.
const uint32 DEVICE_NAME_MAX = 31;

/// Maximum number of bytes in a path
// The simple name PATH_MAX collides with a musl #define on c++ bindings.
const uint32 DEVICE_PATH_MAX = 1024;

/// Maximum number of bytes in a device arguments string.
const uint32 DEVICE_ARGS_MAX = 1024;

/// Maximum number of bytes in a metadata payload
const uint32 METADATA_BYTES_MAX = 8192;

/// Maximum number of metadata that can be added to a device
const uint32 METADATA_MAX = 32;

/// Maximum number of properties that can be attached to a device
const uint32 PROPERTIES_MAX = 256;

/// Maximum number of fragments that a composite device can have
const uint32 FRAGMENTS_MAX = 16;

/// Maximum number of parts that a composite device fragment can have
const uint32 DEVICE_FRAGMENT_PARTS_MAX = 16;

/// Maximum number of instructions in the match program of a device fragment part
const uint32 DEVICE_FRAGMENT_PART_INSTRUCTIONS_MAX = 32;

// Maximum number of instructions in a driver bind program
const uint32 BIND_PROGRAM_INSTRUCTIONS_MAX = 256;

/// Bit flags for device add configuration
bits AddDeviceConfig : uint32 {
    /// Device can be a fragment in multiple composite devices
    ALLOW_MULTI_COMPOSITE = 0x00000001;
    /// Device should be marked invisible initially (used for deprecated DEVICE_ADD_INVISIBLE)
    INVISIBLE = 0x00000002;
    /// Device should not trigger the auto-bind mechanism
    SKIP_AUTOBIND = 0x00000004;
};

/// A part of a description of a DeviceFragment
struct DeviceFragmentPart {
    // This is an awful hack around the LLCPP bindings not being ready yet.
    // Since we're using the C ones for now, we can only embed these structures as
    // arrays instead of vectors.
    uint32 match_program_count;
    array<BindInstruction>:DEVICE_FRAGMENT_PART_INSTRUCTIONS_MAX match_program;
};

/// A piece of a composite device
struct DeviceFragment {
    // This is an awful hack around the LLCPP bindings not being ready yet.
    // Since we're using the C ones for now, we can only embed these structures as
    // arrays instead of vectors.
    string:32 name;
    uint32 parts_count;
    array<DeviceFragmentPart>:DEVICE_FRAGMENT_PARTS_MAX parts;
};

/// Metadata that can be added to a device
struct DeviceMetadata {
    uint32 key;
    vector<uint8>:METADATA_BYTES_MAX data;
};

/// Composite device parts and properties
struct CompositeDeviceDescriptor {
    vector<DeviceProperty>:PROPERTIES_MAX props;
    vector<DeviceFragment>:FRAGMENTS_MAX fragments;
    uint32 coresident_device_index;
    vector<DeviceMetadata>:METADATA_MAX? metadata;
};

/// A enum of CompatibilityTestStatus
enum CompatibilityTestStatus : uint32 {
    OK = 1;
    ERR_BIND_NO_DDKADD = 2;
    ERR_BIND_TIMEOUT = 3;
    ERR_UNBIND_NO_DDKREMOVE = 4;
    ERR_UNBIND_TIMEOUT = 5;
    ERR_SUSPEND_DDKREMOVE = 6;
    ERR_INTERNAL = 7;
};

/// Protocol for controlling devices in a devhost process from the devcoordinator
protocol DeviceController {
    /// Bind the requested driver to this device.  `driver_path` is informational,
    /// but all calls to BindDriver/CreateDevice should use the same `driver_path`
    /// each time they use a `driver` VMO with the same contents. Returns a `status`
    /// and optionally a channel to the driver's test output. `test_output` will be
    /// not present unless the driver is configured to run its run_unit_tests hook, in
    /// which case the other end of the channel will have been passed to the driver.
    BindDriver(string:DEVICE_PATH_MAX driver_path, zx.handle:VMO driver)
        -> (zx.status status, zx.handle:CHANNEL? test_output);

    /// Give this device a channel to its shadow in another process.
    ConnectProxy(zx.handle:CHANNEL shadow);

    /// Ask devhost to call the device init hook.
    Init() -> (zx.status status);

    /// Ask devhost to unbind this device. On success, the remote end of this
    /// interface channel will close instead of returning a result.
    Unbind() -> () error zx.status;

    /// Ask the devhost to complete the removal of this device, which previously had
    /// invoked `ScheduleRemove`. This is a special case that can be removed
    /// once `device_remove` invokes `unbind`.
    CompleteRemoval() -> () error zx.status;

    /// Ask devhost to suspend this device, using the target state indicated by `flags`.
    Suspend(uint32 flags) -> (zx.status status);

    /// Ask devhost to resume this device, using the target system state indicated by
    /// 'target_system_state'.
    Resume(uint32 target_system_state) -> (zx.status status);

    /// Inform devhost about the compatibility test status when compatibility tests
    /// fail or complete successfully.
    // TODO(ravoorir) : This should be an asynchronous call from devhost to
    // devcoordinator as a reply to RunCompatibilityTests, when llcpp can support
    // making an asynchronous fidl call.
    CompleteCompatibilityTests(CompatibilityTestStatus status);
};

const uint32 FRAGMENT_NAME_MAX = 32;

[ForDeprecatedCBindings]
struct Fragment {
    string:FRAGMENT_NAME_MAX name;
    LocalDeviceId id;
};

/// Protocol for controlling a devhost process from the devcoordinator
protocol DevhostController {
    /// Create a device in the devhost that only implements the device protocol
    /// and claims to support the given `protocol_id`.  This device will communicate
    /// with the devcoordinator via `coordinator`. Implements DeviceController on device_controller_rpc
    CreateDeviceStub(Coordinator coordinator_rpc, request<DeviceController> device_controller_rpc, uint32 protocol_id, LocalDeviceId local_device_id);

    /// Create a device in the devhost representing the shadowed half of device
    /// in another devhost.  This new device will communicate with the devcoordinator
    /// via `rpc`, and with its other half via `parent_proxy`.
    ///
    /// The new device will have the given driver responsible for running its half
    /// of the driver's cross-process protocol.  It's create() method will be invoked,
    /// giving it access to `parent_proxy` and `proxy_args`.
    ///
    /// parent_proxy, if present, will usually be a channel to the upper half of
    /// a shadowed device.  The one exception is when this method is used
    /// to create the Platform Bus, in which case it will be a channel to a
    /// fuchsia.boot.Items protocol.
    ///
    /// `local_device_id` will be a unique value within the device's devhost
    CreateDevice(Coordinator coordinator_rpc, request<DeviceController> device_controller_rpc, string:DEVICE_PATH_MAX driver_path,
                 zx.handle:VMO driver, handle? parent_proxy,
                 string:DEVICE_ARGS_MAX? proxy_args, LocalDeviceId local_device_id);

    /// Introduce a composite device that has the given name and properties.
    /// `fragments` will be a list of all of the composite's fragments,
    /// described using devhost local device ids.  The order of the fragments
    /// will match the original composite creation request.  The new device will
    /// communicate with devcoordinator via `rpc`.
    ///
    /// `local_device_id` will be a unique value within the device's devhost, identifying
    /// the resulting composite device.
    CreateCompositeDevice(Coordinator coordinator_rpc, request<DeviceController> device_controller_rpc,
                          vector<Fragment>:FRAGMENTS_MAX fragments,
                          string:DEVICE_NAME_MAX name, LocalDeviceId local_device_id)
        -> (zx.status status);
};

/// Interface for the devices in devhosts to coordinate with the devcoordinator.
protocol Coordinator {
    /// Record the addition of a new device that can be communicated with via `rpc`.
    /// For binding purposes, it is has properties `props`. `name` and `driver_path`
    /// are informational and used for debugging.  The device will have `protocol_id`
    /// as its primary protocol id.  `args` should only be used for shadowed devices,
    /// and will be forwarded to the shadow device. `client_remote`, if present,
    /// will be passed to the device as an open connection for the client.
    /// On success, the returned `local_device_id` is the identifier assigned by devmgr.
    AddDevice(request<Coordinator> coordinator, DeviceController device_controller,
              vector<DeviceProperty>:PROPERTIES_MAX props,
              string:DEVICE_NAME_MAX name, uint32 protocol_id,
              string:DEVICE_PATH_MAX? driver_path, string:DEVICE_ARGS_MAX? args,
              AddDeviceConfig device_add_config, bool has_init, zx.handle:VMO? inspect,
              zx.handle:CHANNEL? client_remote)
        -> (LocalDeviceId local_device_id) error zx.status;

    /// Requests the devcoordinator schedule the removal of this device,
    /// and the unbinding of its children.
    /// If `unbind_self` is true, the unbind hook for this device will also be called.
    ScheduleRemove(bool unbind_self);

    /// Requests the devcoordinator schedule the unbinding of this device's children.
    ScheduleUnbindChildren();

    /// Mark this device as visible.
    MakeVisible() -> () error zx.status;

    /// Attempt to bind a driver against this device.  If `driver_path` is null,
    /// this will initiate the driver matching algorithm.
    // TODO(teisenbe): Specify the behavior of invoking this multiple times.  I believe
    // the current behavior is a bug.
    BindDevice(string:DEVICE_PATH_MAX? driver_path) -> () error zx.status;

    /// Returns the topological path of this device.
    GetTopologicalPath() -> (string:DEVICE_PATH_MAX path) error zx.status;

    /// Requests that the firmware at the given path be loaded and returned.
    LoadFirmware(string:DEVICE_PATH_MAX fw_path)
        -> (zx.handle:VMO vmo, uint64 size) error zx.status;

    /// Retrieve the metadata blob associated with this device and the given key.
    GetMetadata(uint32 key)
        -> (vector<uint8>:METADATA_BYTES_MAX data) error zx.status;

    /// Retrieve the metadata size associated with this device and the given key.
    GetMetadataSize(uint32 key)
        -> (uint64 size) error zx.status;

    /// Add metadata blob associated with this device and the given key.
    // TODO(teisenbe): Document the behavior of calling this twice with the same
    // key.  I believe the current behavior results in inaccessible data that is
    // kept around for the lifetime of the device.
    AddMetadata(uint32 key, vector<uint8>:METADATA_BYTES_MAX? data)
        -> () error zx.status;

    /// Behaves like AddMetadata, but instead of associating it with the
    /// requesting device, associates it with the device at `device_path`.  If
    /// the device at `device_path` is not a child of the requesting device AND
    /// the requesting device is not running in the sys devhost, then this will
    /// fail.
    PublishMetadata(string:DEVICE_PATH_MAX device_path, uint32 key,
                    vector<uint8>:METADATA_BYTES_MAX? data) -> () error zx.status;

    /// Adds the given composite device.  This causes the devcoordinator to try to match the
    /// fragments against the existing device tree, and to monitor all new device additions
    /// in order to find the fragments as they are created.
    AddCompositeDevice(string:DEVICE_NAME_MAX name, CompositeDeviceDescriptor comp_desc)
        -> () error zx.status;

    /// Watches a directory, receiving events of added messages on the
    /// watcher request channel.
    /// See fuchsia.io.Directory for more information.
    DirectoryWatch(uint32 mask, uint32 options, zx.handle:CHANNEL watcher)
        -> () error zx.status;

    /// Run Compatibility tests for the driver that binds to this device.
    /// The hook_wait_time is the time that the driver expects to take for
    /// each device hook in nanoseconds.
    /// Returns whether the compatibility tests started, and does not convey
    /// anything about the status of the test.
    RunCompatibilityTests(int64 hook_wait_time) -> () error zx.status;
};

/// Protocol for getting the information needed to debug bind programs from the devcoordinator.
[Discoverable]
protocol BindDebugger {
    /// Returns the bind program of the given driver.
    /// ZX_ERR_NOT_FOUND indicates that there is no driver matching the given path.
    /// ZX_ERR_BUFFER_TOO_SMALL indicates that the driver's bind program is longer than the
    /// maximum number of instructions (BIND_PROGRAM_INSTRUCTIONS_MAX).
    GetBindProgram(string:DEVICE_PATH_MAX driver_path)
        -> (vector<BindInstruction>:BIND_PROGRAM_INSTRUCTIONS_MAX instructions)
        error zx.status;

    /// Returns the list of properties of the given device.
    /// ZX_ERR_NOT_FOUND indicates that there is no device matching the given path.
    /// ZX_ERR_BAD_PATH indicates that the given path is not valid.
    /// ZX_ERR_BUFFER_TOO_SMALL indicates either that the given path is too long,
    /// or that the device has more than the maximum number of properties (PROPERTIES_MAX).
    GetDeviceProperties(string:DEVICE_PATH_MAX device_path)
        -> (vector<DeviceProperty>:PROPERTIES_MAX props) error zx.status;
};
