| // Copyright 2019 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.developer.ffx; |
| using fuchsia.device; |
| using fuchsia.net; |
| using fuchsia.buildinfo; |
| using fuchsia.developer.remotecontrol as rc; |
| |
| type TargetIp = struct { |
| ip fuchsia.net.IpAddress; |
| scope_id uint32; |
| }; |
| |
| type TargetIpPort = struct { |
| ip fuchsia.net.IpAddress; |
| scope_id uint32; |
| port uint16; |
| }; |
| |
| // TODO(awdavies): Add serial number. |
| type TargetAddrInfo = strict union { |
| 1: ip TargetIp; |
| 2: ip_port TargetIpPort; |
| }; |
| |
| // TODO(awdavies): Add more target states once they're more well defined. |
| type TargetState = strict enum { |
| UNKNOWN = 1; |
| DISCONNECTED = 2; |
| PRODUCT = 3; |
| FASTBOOT = 4; |
| ZEDBOOT = 5; |
| }; |
| |
| // TODO(awdavies): Add more target types. Hardware? Product state? |
| type TargetType = strict enum { |
| UNKNOWN = 1; |
| }; |
| |
| /// Address of the ssh host address from the perspective of the target. |
| type SshHostAddrInfo = struct { |
| address string:256; |
| }; |
| |
| /// Current known state of the remote control |
| type RemoteControlState = strict enum { |
| UP = 1; |
| DOWN = 2; |
| UNKNOWN = 3; |
| }; |
| |
| /// Interface fastboot is connected over. |
| type FastbootInterface = strict enum { |
| USB = 0; |
| UDP = 1; |
| TCP = 2; |
| }; |
| |
| type TargetInfo = table { |
| 1: nodename string:fuchsia.device.DEVICE_NAME_MAX; |
| 2: addresses vector<TargetAddrInfo>:256; |
| 3: age_ms uint64; |
| 4: rcs_state RemoteControlState; |
| 5: target_type TargetType; |
| 6: target_state TargetState; |
| // Contains the string used for the product in `fx set`, for example |
| // `fx set core.x64` would make this value "core". |
| 7: product_config string:fuchsia.buildinfo.MAX_STRING_LENGTH; |
| // Contains the string used for the board in `fx set`, for example |
| // `fx set core.x64` would make this value "x64". |
| 8: board_config string:fuchsia.buildinfo.MAX_STRING_LENGTH; |
| 9: serial_number string:256; |
| /// ssh_address is the preferred address to use to connect to the |
| /// device over SSH, and will include a port number if a custom SSH |
| /// port number has been set. |
| 10: ssh_address TargetAddrInfo; |
| 11: fastboot_interface FastbootInterface; |
| /// The address of the ssh host as seen by the target. |
| 12: ssh_host_address SshHostAddrInfo; |
| }; |
| |
| type TargetRebootError = strict enum { |
| /// Cannot reboot from fastboot to recovery. |
| FASTBOOT_TO_RECOVERY = 1; |
| /// There was an Overnet communication issue with the target. |
| TARGET_COMMUNICATION = 2; |
| /// There was a Fastboot protocol communication issue with the |
| /// target. |
| FASTBOOT_COMMUNICATION = 3; |
| /// No netsvc address was found for the target when attempting |
| /// to reboot from Zedboot. |
| NETSVC_ADDRESS_NOT_FOUND = 4; |
| /// Error when running a function through netsvc protocol. |
| NETSVC_COMMUNICATION = 5; |
| }; |
| |
| type TargetRebootState = strict enum { |
| PRODUCT = 1; |
| BOOTLOADER = 2; |
| RECOVERY = 3; |
| }; |
| |
| @discoverable |
| protocol TargetControl { |
| @deprecated("Please use target collection -> target handle instead.") |
| Reboot(struct { |
| state TargetRebootState; |
| }) -> (struct {}) error TargetRebootError; |
| }; |
| |
| /// An iterator for which the client handles calls to the `Next` function. When |
| /// a client calls `ListTargets` in the `TargetCollection` protocol, the targets |
| /// will be sent to the client via the `Next` function, with acknowledgements |
| /// sent via the responder to handle backpressure. |
| /// |
| /// When there are no more targets to be sent to the client, an empty vector |
| /// will be sent as the last call to `Next`. |
| protocol TargetCollectionReader { |
| Next(struct { |
| entry vector<TargetInfo>:MAX; |
| }) -> (); |
| }; |
| |
| /// A query for a Fuchsia target device. If empty when supplied to a method, will be |
| /// interpreted as requesting the first target to be seen on the network, or ALL |
| /// targets that have been seen on the network. |
| type TargetQuery = table { |
| /// A string matcher is something that can match either the: |
| /// - Target nodename (partial matches okay). |
| /// - Target IP (any that have been seen). |
| /// - Serial number (partial matches okay). |
| /// |
| /// IPv6 and IPv4 addresses are both acceptable queries. If the address being |
| /// queried is ipv6 and includes a port number, the address (and |
| /// scope id if present) must be enclosed in square brackets. Scope and port |
| /// number are both optional, but may be present. |
| /// |
| /// If a port number is specified, it will match only with targets with |
| /// that same port number (with no port set on the target being treated as |
| /// the default ssh port, 22). |
| /// |
| /// Specifying 0 for the port will match specifically with hosts with |
| /// no port specified. |
| 1: string_matcher string:255; |
| }; |
| |
| type OpenTargetError = strict enum { |
| /// When querying for a target, an ambiguous query was received (one that |
| /// matched multiple targets). |
| QUERY_AMBIGUOUS = 1; |
| /// No targets were able to match the query after waiting. |
| TARGET_NOT_FOUND = 2; |
| }; |
| |
| type TargetConnectionError = strict enum { |
| /// Permission was denied (from the public SSH key to the target). |
| PERMISSION_DENIED = 1; |
| /// SSH refused connection to the target. |
| CONNECTION_REFUSED = 2; |
| /// Hostname could not be resolved. |
| UNKNOWN_NAME_OR_SERVICE = 3; |
| /// Timed out trying to communicate with the target. |
| TIMEOUT = 4; |
| /// SSH Key verification could not proceed (usually a known_hosts issue). |
| KEY_VERIFICATION_FAILURE = 5; |
| /// There was no route to the specified host through SSH. |
| NO_ROUTE_TO_HOST = 6; |
| /// SSH could not reach the specified address. |
| NETWORK_UNREACHABLE = 7; |
| /// The address given was invalid for the target (likely containing a |
| /// scope-ID that does not exist). |
| INVALID_ARGUMENT = 8; |
| /// An as-yet unseen error was encountered preventing connection to the |
| /// device (user will need to check the logs). |
| UNKNOWN_ERROR = 9; |
| /// There was an error communicating via FIDL to the device. This happens |
| /// after a connection has been established. |
| FIDL_COMMUNICATION_ERROR = 10; |
| /// An error was encountered while trying to knock a service in RCS. This |
| /// means that RCS was unable to connect to a service in order to verify a |
| /// FIDL channel can be established. |
| RCS_CONNECTION_ERROR = 11; |
| /// On attempting to 'knock' a service connection, the service dropped the |
| /// channel prematurely, closing the connection. |
| FAILED_TO_KNOCK_SERVICE = 12; |
| }; |
| |
| // TODO(https://fxbug.dev/94680): Migrate the method specifc error enums to use |
| // this type instead. |
| type TargetError = strict enum { |
| /// The specified address does not exist within the target. |
| ADDRESS_NOT_FOUND = 1; |
| }; |
| |
| /// Configuration options for adding a manual target. |
| type AddTargetConfig = table { |
| /// Attempts to verify connection. |
| 1: verify_connection bool; |
| }; |
| |
| /// A protocol defining a collection of Fuchsia targets. This is used to inspect |
| /// and interact with fuchsia targets that the daemon has discovered. |
| @discoverable |
| protocol TargetCollection { |
| /// Sends a list of all active targets in the collection. An active target |
| /// is one that has responded over the network recently. |
| /// |
| /// An optional query string can be passed that will limit results to only |
| /// targets whose metadata matches. Matching is limited to partial string |
| /// matches via the target's nodename, serial number, or IP address. |
| /// |
| /// The client receives updates by handling calls to `Next` in the |
| /// `TargetCollectionReader` protocol. |
| ListTargets(resource struct { |
| query TargetQuery; |
| reader client_end:TargetCollectionReader; |
| }); |
| |
| /// Opens a target handle given the query matches exactly one |
| /// target. If a target does not yet exist in the cache that matches the |
| /// query, then this will hang until one is found. It is the caller's |
| /// responsibility to time out if this call takes too long. |
| OpenTarget(resource struct { |
| query TargetQuery; |
| target_handle server_end:Target; |
| }) -> (struct {}) error OpenTargetError; |
| |
| /// Manually adds a target that cannot be discovered via mDNS. This target |
| /// will be retained indefinitely, including across daemon restarts. |
| /// |
| /// If `verify_connection` is passed as true in the config, this will wait |
| /// until it is possible to establish a remote control service connection |
| /// to the target, or else will return an error detailing what went wrong |
| /// communicating with the Fuchsia device. |
| /// |
| /// Note: the client will be responsible for timing out against this method, |
| /// as it will run for as long as the FIDL connection remains open. If the |
| /// channel is closed prematurely, then the manually added target will be |
| /// removed. |
| /// |
| /// If the channel to this call is dropped before the result is returned, |
| /// it is possible to leak a persistent manual target, so later on the |
| /// caller may need to invoke `RemoveTarget`. |
| /// |
| /// If `verify_connection` is passed as `false`, this function will return |
| /// immediately, ignoring possible connection issues with the target. |
| AddTarget(resource struct { |
| ip TargetAddrInfo; |
| config AddTargetConfig; |
| }) -> (struct {}) error TargetConnectionError; |
| |
| /// Manually adds a target that cannot be discovered via mDNS. This target |
| /// will be retained in the target collection until it establishes an RCS |
| /// connection, or until the associated connection timeout has elapsed. |
| AddEphemeralTarget(struct { |
| ip TargetAddrInfo; |
| connect_timeout_seconds uint64; |
| }) -> (); |
| |
| /// Manually remove a target from the target list. |
| /// |
| /// If the target_id doesn't match a device name, the daaemon will attempt |
| /// to interpret it as an IP. |
| RemoveTarget(struct { |
| target_id string:fuchsia.device.DEVICE_NAME_MAX; |
| }) -> (struct { |
| removed bool; |
| }); |
| }; |
| |
| /// This is a handle to a target received from the target collection. |
| /// Not to be confused with the `TargetControl` protocol. This is exclusively |
| /// for use with the target collection service. |
| @discoverable |
| protocol Target { |
| /// Returns: |
| /// * As much information identifying the target as is currently available. |
| Identity() -> (struct { |
| target_info TargetInfo; |
| }); |
| |
| /// Gets the target SSH host pipe error logs for this target. |
| /// |
| /// Returns: |
| /// * SSH host pipe error logs for the target. If there aren't any, will |
| /// return an empty string. |
| GetSshLogs() -> (struct { |
| entry string:MAX; |
| }); |
| |
| /// Waits for an SSH address to become available on the target. |
| /// |
| /// Returns: |
| /// * The first cached address viable for SSH. If there isn't one, will |
| /// wait until there is. It is the client's responsibility to handle |
| /// potential timeouts. |
| GetSshAddress() -> (struct { |
| address TargetAddrInfo; |
| }); |
| |
| /// Sets the preferred SSH address. |
| /// |
| /// If successful, then all subsequent interactions with the `Target` over |
| /// SSH will leverage the provided `ip`. That is, any existing connection to |
| /// target is severed and a new connection is established using the provided |
| /// `ip`. Note that the specified address is not persisted across daemon |
| /// version changes or restarts. |
| /// |
| /// This method is primarily useful in testing scenarios where a particular |
| /// network interface should be used (e.g. other interfaces may be disabled |
| /// during testing). |
| /// |
| /// Returns: |
| /// * An error if the `ip` does not exist within the target. Otherwise, |
| /// nothing on success. |
| SetPreferredSshAddress(struct { |
| ip TargetIp; |
| }) -> (struct {}) error TargetError; |
| |
| /// Clears an address that was previously configured using |
| /// `SetPreferredSshAddress`. |
| /// |
| /// Any existing connection to the target is severed and a new connection is |
| /// established. The newly selected address is chosen using the standard |
| /// address selection logic. |
| /// |
| /// Returns: |
| /// * Nothing on success. |
| ClearPreferredSshAddress() -> (); |
| |
| /// Opens a connection to the RemoteControlService for a given |
| /// target. If the target is not in a state that allows opening up the |
| /// remote control, will wait until it is. It is the client's responsibilty |
| /// to handle potential timeouts here otherwise it will wait indefinitely. |
| /// |
| /// Returns: |
| /// * Empty struct on success. |
| /// |
| /// Errors: |
| /// * See [TargetError] for failure states. |
| OpenRemoteControl(resource struct { |
| remote_control server_end:rc.RemoteControl; |
| }) -> (struct {}) error TargetConnectionError; |
| |
| /// Opens a Fastboot controller for a given target. |
| OpenFastboot(resource struct { |
| fastboot server_end:Fastboot; |
| }); |
| |
| /// Reboots the target to the desired state. |
| /// |
| /// Returns: |
| /// * Empty struct on success. |
| /// |
| /// Errors: |
| /// * See [TargetRebootError] for failure states. |
| Reboot(struct { |
| state TargetRebootState; |
| }) -> (struct {}) error TargetRebootError; |
| |
| |
| /// Runs an iterator over diagnostics data. At present, this means cached log data. |
| StreamActiveDiagnostics(resource struct { |
| parameters DaemonDiagnosticsStreamParameters; |
| iterator server_end:rc.ArchiveIterator; |
| }) -> (struct { |
| log_session LogSession; |
| }) error DiagnosticsStreamError; |
| }; |