1// Copyright 2022 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 19option java_multiple_files = true; 20option java_package = "dev.pigweed.pw_transfer"; 21 22// The transfer RPC service is used to send data between the client and server. 23service Transfer { 24 // Transfer data from the server to the client; a "download" from the client's 25 // perspective. 26 rpc Read(stream Chunk) returns (stream Chunk); 27 28 // Transfer data from the client to the server; an "upload" from the client's 29 // perspective. 30 rpc Write(stream Chunk) returns (stream Chunk); 31 32 // Query the status of a resource. Can be used for partially completed 33 // transfers 34 rpc GetResourceStatus(ResourceStatusRequest) returns (ResourceStatus); 35} 36 37// Represents a chunk of data sent by the transfer service. Includes fields for 38// configuring the transfer parameters. 39// 40// Notation: (Read|Write) (→|←) 41// X → Means client sending data to the server. 42// X ← Means server sending data to the client. 43message Chunk { 44 // Represents the source or destination of the data. May be ephemeral or 45 // stable depending on the implementation. Sent in every request to identify 46 // the transfer target. 47 // 48 // LEGACY FIELD ONLY. Split into resource_id and session_id in transfer v2. 49 // 50 // Read → ID of transfer 51 // Read ← ID of transfer 52 // Write → ID of transfer 53 // Write ← ID of transfer 54 uint32 transfer_id = 1; 55 56 // Used by the receiver to indicate how many bytes it can accept. The 57 // transmitter sends this much data, divided into chunks no larger than 58 // max_chunk_size_bytes. The receiver then starts another window by sending 59 // request_bytes again with a new offset. 60 // 61 // Read → The client requests this many bytes to be sent. 62 // Read ← N/A 63 // Write → N/A 64 // Write ← The server requests this many bytes to be sent. 65 optional uint32 pending_bytes = 2; 66 67 // Maximum size of an individual chunk. The transmitter may send smaller 68 // chunks if required. 69 // 70 // Read → Set maximum size for subsequent chunks. 71 // Read ← N/A 72 // Write → N/A 73 // Write ← Set maximum size for subsequent chunks. 74 optional uint32 max_chunk_size_bytes = 3; 75 76 // Minimum required delay between chunks. The transmitter may delay longer if 77 // desired. 78 // 79 // Read → Set minimum delay for subsequent chunks. 80 // Read ← N/A 81 // Write → N/A 82 // Write ← Set minimum delay for subsequent chunks. 83 optional uint32 min_delay_microseconds = 4; 84 85 // On writes, the offset of the data. On reads, the offset at which to read. 86 // 87 // Read → Read data starting at this offset. 88 // Read ← Offset of the data. 89 // Write → Offset of the data. 90 // Write ← Write data starting at this offset. 91 uint64 offset = 5; 92 93 // The data that was read or the data to write. 94 // 95 // Read → N/A 96 // Read ← Data read 97 // Write → Data to write 98 // Write ← N/A 99 bytes data = 6; 100 101 // Estimated bytes remaining to read/write. Optional except for the last data 102 // chunk, for which remaining_bytes must be set to 0. 103 // 104 // The sender can set remaining_bytes at the beginning of a read/write so that 105 // the receiver can track progress or cancel the transaction if the value is 106 // too large. 107 // 108 // Read → N/A 109 // Read ← Remaining bytes to read, excluding any data in this chunk. Set to 110 // 0 for the last chunk. 111 // Write → Remaining bytes to write, excluding any data in is chunk. Set to 112 // 0 for the last chunk. 113 // Write ← N/A 114 optional uint64 remaining_bytes = 7; 115 116 // Pigweed status code indicating the completion of a transfer. This is only 117 // present in the final packet sent by either the transmitter or receiver. 118 // 119 // The possible status codes and their meanings are listed below: 120 // 121 // OK: Transfer completed successfully. 122 // DATA_LOSS: Transfer data could not be read/written (e.g. corruption). 123 // INVALID_ARGUMENT: Received malformed chunk. 124 // NOT_FOUND: The requested resource ID is not registered (read/write). 125 // OUT_OF_RANGE: The requested offset is larger than the data (read/write). 126 // RESOURCE_EXHAUSTED: Concurrent transfer limit reached. 127 // UNIMPLEMENTED: Resource ID does not support requested operation (e.g. 128 // trying to write to a read-only transfer). 129 // 130 // Read → Transfer complete. 131 // Read ← Transfer complete. 132 // Write → Transfer complete. 133 // Write ← Transfer complete. 134 optional uint32 status = 8; 135 136 // The offset up to which the transmitter can send data before waiting for the 137 // receiver to acknowledge. 138 // 139 // Read → Offset up to which the server can send without blocking. 140 // Read ← N/A 141 // Write → N/A 142 // Write ← Offset up to which the client can send without blocking. 143 // 144 // TODO(frolv): This will replace the pending_bytes field. Once all uses of 145 // transfer are migrated, that field should be removed. 146 uint32 window_end_offset = 9; 147 148 enum Type { 149 // Chunk containing transfer data. 150 DATA = 0; 151 152 // First chunk of a transfer (only sent by the client). 153 START = 1; 154 155 // Transfer parameters indicating that the transmitter should retransmit 156 // from the specified offset. 157 PARAMETERS_RETRANSMIT = 2; 158 159 // Transfer parameters telling the transmitter to continue sending up to 160 // index `offset + pending_bytes` of data. If the transmitter is already 161 // beyond `offset`, it does not have to rewind. 162 PARAMETERS_CONTINUE = 3; 163 164 // Sender of the chunk is terminating the transfer. 165 COMPLETION = 4; 166 167 // Acknowledge the completion of a transfer. Currently unused. 168 // TODO(konkers): Implement this behavior. 169 COMPLETION_ACK = 5; 170 171 // Acknowledges a transfer start request, accepting the session ID for the 172 // transfer and optionally negotiating the protocol version. Sent from 173 // server to client. 174 START_ACK = 6; 175 176 // Confirmation of a START_ACK's negotiated parameters, sent by the client 177 // to the server. Initiates the data transfer proper. 178 START_ACK_CONFIRMATION = 7; 179 }; 180 181 // The type of this chunk. This field should only be processed when present. 182 // TODO(frolv): Update all users of pw_transfer and remove the optional 183 // semantics from this field. 184 // 185 // Read → Chunk type (start/parameters). 186 // Read ← Chunk type (data). 187 // Write → Chunk type (data). 188 // Write ← Chunk type (start/parameters). 189 optional Type type = 10; 190 191 // Unique identifier for the source or destination of transfer data. May be 192 // stable or ephemeral depending on the implementation. Only sent during the 193 // initial handshake phase of a version 2 or higher transfer. 194 // 195 // Read → ID of transferable resource 196 // Read ← ID of transferable resource 197 // Write → ID of transferable resource 198 // Write ← ID of transferable resource 199 optional uint32 resource_id = 11; 200 201 // Unique identifier for a specific transfer session. Chosen by the transfer 202 // client during the initial handshake phase, and persists for the remainder 203 // of that transfer operation. 204 // 205 // Read → ID of transfer session 206 // Read ← ID of transfer session 207 // Write → ID of transfer session 208 // Write ← ID of transfer session 209 optional uint32 session_id = 12; 210 211 // The protocol version to use for this transfer. Only sent during the initial 212 // handshake phase of a version 2 or higher transfer to negotiate a common 213 // protocol version between the client and server. 214 // 215 // Read → Desired (START) or configured (START_ACK_CONFIRMATION) version. 216 // Read ← Configured protocol version (START_ACK). 217 // Write → Desired (START) or configured (START_ACK_CONFIRMATION) version. 218 // Write ← Configured protocol version (START_ACK). 219 optional uint32 protocol_version = 13; 220 221 // Unique identifier for a specific transfer session. Chosen by the transfer 222 // client during the initial handshake phase. This field is used to request a 223 // session during the handshake, after which the regular session_id field is 224 // used. 225 // 226 // Read → Requested ID of transfer session 227 // Read ← N/A 228 // Write → Requested ID of transfer session 229 // Write ← N/A 230 optional uint32 desired_session_id = 14; 231 232 // The initial offset to start the transfer from. Can be used for read or 233 // write transfers. Set by the client during start handshake. 234 // Needs to be accepted by the resource transfer handler in order for the 235 // non-zero offset transfer to start from the initial_offset. 236 // 237 // Read → Requested initial offset for the session 238 // Read ← Confirmed (matches) or denied (zero) initial offset 239 // Write → Requested initial offset for the session 240 // Write ← Confirmed (matches) or denied (zero) initial offset 241 uint64 initial_offset = 15; 242} 243 244// Request for GetResourceStatus, indicating the resource to get status from. 245message ResourceStatusRequest { 246 uint32 resource_id = 1; 247} 248 249// Response for GetResourceStatus 250message ResourceStatus { 251 // Resource id, matching request 252 uint32 resource_id = 1; 253 254 // Status of the resource, returns Unimplemented by default. 255 uint32 status = 2; 256 // The offset that can be written to (other than 0). 257 uint64 writeable_offset = 3; 258 // The offset that can be read from (other than 0). 259 uint64 readable_offset = 4; 260 // The checksum at the given write offset. 261 optional uint64 write_checksum = 5; 262 // The checksum at the given read offset. 263 optional uint64 read_checksum = 6; 264} 265