| // Copyright 2022 The Pigweed Authors |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| // use this file except in compliance with the License. You may obtain a copy of |
| // the License at |
| // |
| // https://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| // License for the specific language governing permissions and limitations under |
| // the License. |
| |
| syntax = "proto3"; |
| |
| package pw.transfer; |
| |
| option java_multiple_files = true; |
| option java_package = "dev.pigweed.pw_transfer"; |
| |
| // The transfer RPC service is used to send data between the client and server. |
| service Transfer { |
| // Transfer data from the server to the client; a "download" from the client's |
| // perspective. |
| rpc Read(stream Chunk) returns (stream Chunk); |
| |
| // Transfer data from the client to the server; an "upload" from the client's |
| // perspective. |
| rpc Write(stream Chunk) returns (stream Chunk); |
| |
| // Query the status of a resource. Can be used for partially completed |
| // transfers |
| rpc GetResourceStatus(ResourceStatusRequest) returns (ResourceStatus); |
| } |
| |
| // Represents a chunk of data sent by the transfer service. Includes fields for |
| // configuring the transfer parameters. |
| // |
| // Notation: (Read|Write) (→|←) |
| // X → Means client sending data to the server. |
| // X ← Means server sending data to the client. |
| message Chunk { |
| // Represents the source or destination of the data. May be ephemeral or |
| // stable depending on the implementation. Sent in every request to identify |
| // the transfer target. |
| // |
| // LEGACY FIELD ONLY. Split into resource_id and session_id in transfer v2. |
| // |
| // Read → ID of transfer |
| // Read ← ID of transfer |
| // Write → ID of transfer |
| // Write ← ID of transfer |
| uint32 transfer_id = 1; |
| |
| // Used by the receiver to indicate how many bytes it can accept. The |
| // transmitter sends this much data, divided into chunks no larger than |
| // max_chunk_size_bytes. The receiver then starts another window by sending |
| // request_bytes again with a new offset. |
| // |
| // Read → The client requests this many bytes to be sent. |
| // Read ← N/A |
| // Write → N/A |
| // Write ← The server requests this many bytes to be sent. |
| optional uint32 pending_bytes = 2; |
| |
| // Maximum size of an individual chunk. The transmitter may send smaller |
| // chunks if required. |
| // |
| // Read → Set maximum size for subsequent chunks. |
| // Read ← N/A |
| // Write → N/A |
| // Write ← Set maximum size for subsequent chunks. |
| optional uint32 max_chunk_size_bytes = 3; |
| |
| // Minimum required delay between chunks. The transmitter may delay longer if |
| // desired. |
| // |
| // Read → Set minimum delay for subsequent chunks. |
| // Read ← N/A |
| // Write → N/A |
| // Write ← Set minimum delay for subsequent chunks. |
| optional uint32 min_delay_microseconds = 4; |
| |
| // On writes, the offset of the data. On reads, the offset at which to read. |
| // |
| // Read → Read data starting at this offset. |
| // Read ← Offset of the data. |
| // Write → Offset of the data. |
| // Write ← Write data starting at this offset. |
| uint64 offset = 5; |
| |
| // The data that was read or the data to write. |
| // |
| // Read → N/A |
| // Read ← Data read |
| // Write → Data to write |
| // Write ← N/A |
| bytes data = 6; |
| |
| // Estimated bytes remaining to read/write. Optional except for the last data |
| // chunk, for which remaining_bytes must be set to 0. |
| // |
| // The sender can set remaining_bytes at the beginning of a read/write so that |
| // the receiver can track progress or cancel the transaction if the value is |
| // too large. |
| // |
| // Read → N/A |
| // Read ← Remaining bytes to read, excluding any data in this chunk. Set to |
| // 0 for the last chunk. |
| // Write → Remaining bytes to write, excluding any data in is chunk. Set to |
| // 0 for the last chunk. |
| // Write ← N/A |
| optional uint64 remaining_bytes = 7; |
| |
| // Pigweed status code indicating the completion of a transfer. This is only |
| // present in the final packet sent by either the transmitter or receiver. |
| // |
| // The possible status codes and their meanings are listed below: |
| // |
| // OK: Transfer completed successfully. |
| // DATA_LOSS: Transfer data could not be read/written (e.g. corruption). |
| // INVALID_ARGUMENT: Received malformed chunk. |
| // NOT_FOUND: The requested resource ID is not registered (read/write). |
| // OUT_OF_RANGE: The requested offset is larger than the data (read/write). |
| // RESOURCE_EXHAUSTED: Concurrent transfer limit reached. |
| // UNIMPLEMENTED: Resource ID does not support requested operation (e.g. |
| // trying to write to a read-only transfer). |
| // |
| // Read → Transfer complete. |
| // Read ← Transfer complete. |
| // Write → Transfer complete. |
| // Write ← Transfer complete. |
| optional uint32 status = 8; |
| |
| // The offset up to which the transmitter can send data before waiting for the |
| // receiver to acknowledge. |
| // |
| // Read → Offset up to which the server can send without blocking. |
| // Read ← N/A |
| // Write → N/A |
| // Write ← Offset up to which the client can send without blocking. |
| // |
| // TODO(frolv): This will replace the pending_bytes field. Once all uses of |
| // transfer are migrated, that field should be removed. |
| uint32 window_end_offset = 9; |
| |
| enum Type { |
| // Chunk containing transfer data. |
| DATA = 0; |
| |
| // First chunk of a transfer (only sent by the client). |
| START = 1; |
| |
| // Transfer parameters indicating that the transmitter should retransmit |
| // from the specified offset. |
| PARAMETERS_RETRANSMIT = 2; |
| |
| // Transfer parameters telling the transmitter to continue sending up to |
| // index `offset + pending_bytes` of data. If the transmitter is already |
| // beyond `offset`, it does not have to rewind. |
| PARAMETERS_CONTINUE = 3; |
| |
| // Sender of the chunk is terminating the transfer. |
| COMPLETION = 4; |
| |
| // Acknowledge the completion of a transfer. Currently unused. |
| // TODO(konkers): Implement this behavior. |
| COMPLETION_ACK = 5; |
| |
| // Acknowledges a transfer start request, accepting the session ID for the |
| // transfer and optionally negotiating the protocol version. Sent from |
| // server to client. |
| START_ACK = 6; |
| |
| // Confirmation of a START_ACK's negotiated parameters, sent by the client |
| // to the server. Initiates the data transfer proper. |
| START_ACK_CONFIRMATION = 7; |
| }; |
| |
| // The type of this chunk. This field should only be processed when present. |
| // TODO(frolv): Update all users of pw_transfer and remove the optional |
| // semantics from this field. |
| // |
| // Read → Chunk type (start/parameters). |
| // Read ← Chunk type (data). |
| // Write → Chunk type (data). |
| // Write ← Chunk type (start/parameters). |
| optional Type type = 10; |
| |
| // Unique identifier for the source or destination of transfer data. May be |
| // stable or ephemeral depending on the implementation. Only sent during the |
| // initial handshake phase of a version 2 or higher transfer. |
| // |
| // Read → ID of transferable resource |
| // Read ← ID of transferable resource |
| // Write → ID of transferable resource |
| // Write ← ID of transferable resource |
| optional uint32 resource_id = 11; |
| |
| // Unique identifier for a specific transfer session. Chosen by the transfer |
| // client during the initial handshake phase, and persists for the remainder |
| // of that transfer operation. |
| // |
| // Read → ID of transfer session |
| // Read ← ID of transfer session |
| // Write → ID of transfer session |
| // Write ← ID of transfer session |
| optional uint32 session_id = 12; |
| |
| // The protocol version to use for this transfer. Only sent during the initial |
| // handshake phase of a version 2 or higher transfer to negotiate a common |
| // protocol version between the client and server. |
| // |
| // Read → Desired (START) or configured (START_ACK_CONFIRMATION) version. |
| // Read ← Configured protocol version (START_ACK). |
| // Write → Desired (START) or configured (START_ACK_CONFIRMATION) version. |
| // Write ← Configured protocol version (START_ACK). |
| optional uint32 protocol_version = 13; |
| |
| // Unique identifier for a specific transfer session. Chosen by the transfer |
| // client during the initial handshake phase. This field is used to request a |
| // session during the handshake, after which the regular session_id field is |
| // used. |
| // |
| // Read → Requested ID of transfer session |
| // Read ← N/A |
| // Write → Requested ID of transfer session |
| // Write ← N/A |
| optional uint32 desired_session_id = 14; |
| |
| // The initial offset to start the transfer from. Can be used for read or |
| // write transfers. Set by the client during start handshake. |
| // Needs to be accepted by the resource transfer handler in order for the |
| // non-zero offset transfer to start from the initial_offset. |
| // |
| // Read → Requested initial offset for the session |
| // Read ← Confirmed (matches) or denied (zero) initial offset |
| // Write → Requested initial offset for the session |
| // Write ← Confirmed (matches) or denied (zero) initial offset |
| uint64 initial_offset = 15; |
| } |
| |
| // Request for GetResourceStatus, indicating the resource to get status from. |
| message ResourceStatusRequest { |
| uint32 resource_id = 1; |
| } |
| |
| // Response for GetResourceStatus |
| message ResourceStatus { |
| // Resource id, matching request |
| uint32 resource_id = 1; |
| |
| // Status of the resource, returns Unimplemented by default. |
| uint32 status = 2; |
| // The offset that can be written to (other than 0). |
| uint64 writeable_offset = 3; |
| // The offset that can be read from (other than 0). |
| uint64 readable_offset = 4; |
| // The checksum at the given write offset. |
| optional uint64 write_checksum = 5; |
| // The checksum at the given read offset. |
| optional uint64 read_checksum = 6; |
| } |