1// Copyright 2021 The Pigweed Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); you may not 4// use this file except in compliance with the License. You may obtain a copy of 5// the License at 6// 7// https://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12// License for the specific language governing permissions and limitations under 13// the License. 14 15syntax = "proto3"; 16 17package pw.transfer; 18 19// The transfer RPC service is used to send data between the client and server. 20service Transfer { 21 // Transfer data from the server to the client; a "download" from the client's 22 // perspective. 23 rpc Read(stream Chunk) returns (stream Chunk); 24 25 // Transfer data from the client to the server; an "upload" from the client's 26 // perspective. 27 rpc Write(stream Chunk) returns (stream Chunk); 28} 29 30// Represents a chunk of data sent by the transfer service. Includes fields for 31// configuring the transfer parameters. 32// 33// Notation: (Read|Write) (→|←) 34// X → Means client sending data to the server. 35// X ← Means server sending data to the client. 36message Chunk { 37 // Represents the source or destination of the data. May be ephemeral or 38 // stable depending on the implementation. Sent in every request to identify 39 // the transfer target. 40 // 41 // Read → ID of transfer 42 // Read ← ID of transfer 43 // Write → ID of transfer 44 // Write ← ID of transfer 45 uint32 transfer_id = 1; 46 47 // Used by the receiver to indicate how many bytes it can accept. The 48 // transmitter sends this much data, divided into chunks no larger than 49 // max_chunk_size_bytes. The receiver then starts another window by sending 50 // request_bytes again with a new offset. 51 // 52 // Read → The client requests this many bytes to be sent. 53 // Read ← N/A 54 // Write → N/A 55 // Write ← The server requests this many bytes to be sent. 56 optional uint32 pending_bytes = 2; 57 58 // Maximum size of an individual chunk. The transmitter may send smaller 59 // chunks if required. 60 // 61 // Read → Set maximum size for subsequent chunks. 62 // Read ← N/A 63 // Write → N/A 64 // Write ← Set maximum size for subsequent chunks. 65 optional uint32 max_chunk_size_bytes = 3; 66 67 // Minimum required delay between chunks. The transmitter may delay longer if 68 // desired. 69 // 70 // Read → Set minimum delay for subsequent chunks. 71 // Read ← N/A 72 // Write → N/A 73 // Write ← Set minimum delay for subsequent chunks. 74 optional uint32 min_delay_microseconds = 4; 75 76 // On writes, the offset of the data. On reads, the offset at which to read. 77 // 78 // Read → Read data starting at this offset. 79 // Read ← Offset of the data. 80 // Write → Offset of the data. 81 // Write ← Write data starting at this offset. 82 uint64 offset = 5; 83 84 // The data that was read or the data to write. 85 // 86 // Read → N/A 87 // Read ← Data read 88 // Write → Data to write 89 // Write ← N/A 90 bytes data = 6; 91 92 // Estimated bytes remaining to read/write. Optional except for the last data 93 // chunk, for which remaining_bytes must be set to 0. 94 // 95 // The sender can set remaining_bytes at the beginning of a read/write so that 96 // the receiver can track progress or cancel the transaction if the value is 97 // too large. 98 // 99 // Read → N/A 100 // Read ← Remaining bytes to read, excluding any data in this chunk. Set to 101 // 0 for the last chunk. 102 // Write → Remaining bytes to write, excluding any data in is chunk. Set to 103 // 0 for the last chunk. 104 // Write ← N/A 105 optional uint64 remaining_bytes = 7; 106 107 // Pigweed status code indicating the completion of a transfer. This is only 108 // present in the final packet sent by either the transmitter or receiver. 109 // 110 // The possible status codes and their meanings are listed below: 111 // 112 // OK: Transfer completed successfully. 113 // DATA_LOSS: Transfer data could not be read/written (e.g. corruption). 114 // INVALID_ARGUMENT: Received malformed chunk. 115 // NOT_FOUND: The requested transfer ID is not registered (read/write). 116 // OUT_OF_RANGE: The requested offset is larger than the data (read/write). 117 // RESOURCE_EXHAUSTED: Concurrent transfer limit reached. 118 // UNIMPLEMENTED: Transfer ID does not support requested operation (e.g. 119 // trying to write to a read-only transfer). 120 // 121 // Read → Transfer complete. 122 // Read ← Transfer complete. 123 // Write → Transfer complete. 124 // Write ← Transfer complete. 125 optional uint32 status = 8; 126 127 // The offset up to which the transmitter can send data before waiting for the 128 // receiver to acknowledge. 129 // 130 // Read → Offset up to which the server can send without blocking. 131 // Read ← N/A 132 // Write → N/A 133 // Write ← Offset up to which the client can send without blocking. 134 // 135 // TODO(frolv): This will replace the pending_bytes field. Once all uses of 136 // transfer are migrated, that field should be removed. 137 uint32 window_end_offset = 9; 138 139 enum Type { 140 // Chunk containing transfer data. 141 TRANSFER_DATA = 0; 142 143 // First chunk of a transfer (only sent by the client). 144 TRANSFER_START = 1; 145 146 // Transfer parameters indicating that the transmitter should retransmit 147 // from the specified offset. 148 PARAMETERS_RETRANSMIT = 2; 149 150 // Transfer parameters telling the transmitter to continue sending up to 151 // index `offset + pending_bytes` of data. If the transmitter is already 152 // beyond `offset`, it does not have to rewind. 153 PARAMETERS_CONTINUE = 3; 154 155 // Sender of the chunk is terminating the transfer. 156 TRANSFER_COMPLETION = 4; 157 158 // Acknowledge the completion of a transfer. Currently unused. 159 // TODO(konkers): Implement this behavior. 160 TRANSFER_COMPLETION_ACK = 5; 161 }; 162 163 // The type of this chunk. This field should only be processed when present. 164 // TODO(frolv): Update all users of pw_transfer and remove the optional 165 // semantics from this field. 166 // 167 // Read → Chunk type (start/parameters). 168 // Read ← Chunk type (data). 169 // Write → Chunk type (data). 170 // Write ← Chunk type (start/parameters). 171 optional Type type = 10; 172} 173