.. _module-pw_transfer: =========== pw_transfer =========== .. attention:: ``pw_transfer`` is under construction and so is its documentation. ----- Usage ----- Python ====== .. automodule:: pw_transfer.transfer :members: Manager, Error **Example** .. code-block:: python from pw_transfer import transfer # Initialize a Pigweed RPC client; see pw_rpc docs for more info. rpc_client = CustomRpcClient() rpcs = rpc_client.channel(1).rpcs transfer_service = rpcs.pw.transfer.Transfer transfer_manager = transfer.Manager(transfer_service) try: # Read transfer_id 3 from the server. data = transfer_manager.read(3) except transfer.Error as err: print('Failed to read:', err.status) try: # Send some data to the server. The transfer manager does not have to be # reinitialized. transfer_manager.write(2, b'hello, world') except transfer.Error as err: print('Failed to write:', err.status) -------- Protocol -------- Protocol buffer definition ========================== .. literalinclude:: transfer.proto :language: protobuf :lines: 14- Server to client transfer (read) ================================ .. seqdiag:: :scale: 110 seqdiag { default_note_color = aliceblue; client -> server [ label = "set transfer parameters", leftnote = "transfer_id\noffset\npending_bytes\nmax_chunk_size\nchunk_delay" ]; client <-- server [ noactivate, label = "requested bytes\n(zero or more chunks)", rightnote = "transfer_id\noffset\ndata\n(remaining_bytes)" ]; client --> server [ noactivate, label = "update transfer parameters\n(as needed)", leftnote = "transfer_id\noffset\npending_bytes\n(max_chunk_size)\n(chunk_delay)" ]; client <- server [ noactivate, label = "final chunk", rightnote = "transfer_id\noffset\ndata\nremaining_bytes=0" ]; client -> server [ noactivate, label = "acknowledge completion", leftnote = "transfer_id\nstatus=OK" ]; } Client to server transfer (write) ================================= .. seqdiag:: :scale: 110 seqdiag { default_note_color = aliceblue; client -> server [ label = "start", leftnote = "transfer_id" ]; client <- server [ noactivate, label = "set transfer parameters", rightnote = "transfer_id\noffset\npending_bytes\nmax_chunk_size\nchunk_delay" ]; client --> server [ noactivate, label = "requested bytes\n(zero or more chunks)", leftnote = "transfer_id\noffset\ndata\n(remaining_bytes)" ]; client <-- server [ noactivate, label = "update transfer parameters\n(as needed)", rightnote = "transfer_id\noffset\npending_bytes\n(max_chunk_size)\n(chunk_delay)" ]; client -> server [ noactivate, label = "final chunk", leftnote = "transfer_id\noffset\ndata\nremaining_bytes=0" ]; client <- server [ noactivate, label = "acknowledge completion", rightnote = "transfer_id\nstatus=OK" ]; } Errors ====== At any point, either the client or server may terminate the transfer by sending an error chunk with the transfer ID and a non-OK status. Transmitter flow ================ .. mermaid:: graph TD start([Client initiates
transfer]) -->data_request data_request[Receive transfer
parameters]-->send_chunk send_chunk[Send chunk]-->sent_all sent_all{Sent final
chunk?} -->|yes|wait sent_all-->|no|sent_requested sent_requested{Sent all
pending?}-->|yes|data_request sent_requested-->|no|send_chunk wait[Wait for receiver]-->is_done is_done{Received
final chunk?}-->|yes|done is_done-->|no|data_request done([Transfer complete]) Receiver flow ============= .. mermaid:: graph TD start([Client initiates
transfer]) -->request_bytes request_bytes[Set transfer
parameters]-->wait wait[Wait for chunk]-->received_chunk received_chunk{Received
chunk by
deadline?}-->|no|request_bytes received_chunk-->|yes|check_chunk check_chunk{Correct
offset?} -->|yes|process_chunk check_chunk --> |no|request_bytes process_chunk[Process chunk]-->final_chunk final_chunk{Final
chunk?}-->|yes|signal_completion final_chunk{Final
chunk?}-->|no|received_requested received_requested{Received all
pending?}-->|yes|request_bytes received_requested-->|no|wait signal_completion[Signal completion]-->done done([Transfer complete])