Lines Matching full:chunk
43 last_chunk_sent_ == Chunk::Type::kStartAck) { in HandleEvent()
44 // The client is retrying its initial chunk as the response may not in HandleEvent()
72 HandleChunkEvent(event.chunk); in HandleEvent()
113 // initial chunk. in InitiateTransferAsClient()
132 Chunk start_chunk(desired_protocol_version_, Chunk::Type::kStart); in InitiateTransferAsClient()
138 // Parameters should still be set on the initial chunk for backwards in InitiateTransferAsClient()
189 Chunk chunk(ProtocolVersion::kLegacy, Chunk::Type::kStart); in SendInitialLegacyTransmitChunk() local
190 chunk.set_session_id(resource_id_); in SendInitialLegacyTransmitChunk()
192 EncodeAndSendChunk(chunk); in SendInitialLegacyTransmitChunk()
209 // A transfer always begins with a window size of one chunk, set during in UpdateTransferParameters()
216 // chunk in congestion avoidance. in UpdateTransferParameters()
255 void Context::SetTransferParameters(Chunk& parameters) { in SetTransferParameters()
269 Chunk::Type type = Chunk::Type::kParametersRetransmit; in SendTransferParameters()
273 type = Chunk::Type::kStart; in SendTransferParameters()
277 type = Chunk::Type::kParametersRetransmit; in SendTransferParameters()
280 type = Chunk::Type::kParametersContinue; in SendTransferParameters()
284 Chunk parameters(configured_protocol_version_, type); in SendTransferParameters()
314 void Context::EncodeAndSendChunk(const Chunk& chunk) { in EncodeAndSendChunk() argument
315 last_chunk_sent_ = chunk.type(); in EncodeAndSendChunk()
318 if ((chunk.remaining_bytes().has_value() && in EncodeAndSendChunk()
319 chunk.remaining_bytes().value() == 0) || in EncodeAndSendChunk()
320 (chunk.type() != Chunk::Type::kData && in EncodeAndSendChunk()
321 chunk.type() != Chunk::Type::kParametersContinue)) { in EncodeAndSendChunk()
322 chunk.LogChunk(false, pw::chrono::SystemClock::duration::zero()); in EncodeAndSendChunk()
327 if (chunk.type() == Chunk::Type::kData || in EncodeAndSendChunk()
328 chunk.type() == Chunk::Type::kParametersContinue) { in EncodeAndSendChunk()
329 chunk.LogChunk(false, log_rate_limit_); in EncodeAndSendChunk()
333 Result<ConstByteSpan> data = chunk.Encode(thread_->encode_buffer()); in EncodeAndSendChunk()
335 PW_LOG_ERROR("Failed to encode chunk for transfer %u: %d", in EncodeAndSendChunk()
336 static_cast<unsigned>(chunk.session_id()), in EncodeAndSendChunk()
345 PW_LOG_ERROR("Failed to write chunk for transfer %u: %d", in EncodeAndSendChunk()
346 static_cast<unsigned>(chunk.session_id()), in EncodeAndSendChunk()
377 // proceed to waiting for a chunk. in Initialize()
399 last_chunk_sent_ = Chunk::Type::kStart; in Initialize()
412 Result<Chunk> maybe_chunk = in HandleChunkEvent()
413 Chunk::Parse(ConstByteSpan(event.data, event.size)); in HandleChunkEvent()
418 Chunk chunk = *maybe_chunk; in HandleChunkEvent() local
425 if (chunk.type() != Chunk::Type::kData && in HandleChunkEvent()
426 chunk.type() != Chunk::Type::kParametersContinue) { in HandleChunkEvent()
427 chunk.LogChunk(true, pw::chrono::SystemClock::duration::zero()); in HandleChunkEvent()
431 if (chunk.type() == Chunk::Type::kData || in HandleChunkEvent()
432 chunk.type() == Chunk::Type::kParametersContinue) { in HandleChunkEvent()
433 chunk.LogChunk(true, log_rate_limit_); in HandleChunkEvent()
437 if (chunk.IsTerminatingChunk()) { in HandleChunkEvent()
439 HandleTermination(chunk.status().value()); in HandleChunkEvent()
442 static_cast<int>(chunk.status().value().code()), in HandleChunkEvent()
449 HandleTransmitChunk(chunk); in HandleChunkEvent()
451 HandleReceiveChunk(chunk); in HandleChunkEvent()
455 void Context::PerformInitialHandshake(const Chunk& chunk) { in PerformInitialHandshake() argument
456 switch (chunk.type()) { in PerformInitialHandshake()
458 case Chunk::Type::kStart: { in PerformInitialHandshake()
459 UpdateLocalProtocolConfigurationFromPeer(chunk); in PerformInitialHandshake()
469 Chunk start_ack(configured_protocol_version_, Chunk::Type::kStartAck); in PerformInitialHandshake()
480 case Chunk::Type::kStartAck: { in PerformInitialHandshake()
481 UpdateLocalProtocolConfigurationFromPeer(chunk); in PerformInitialHandshake()
484 if (offset_ != chunk.initial_offset()) { in PerformInitialHandshake()
489 Chunk start_ack_confirmation(configured_protocol_version_, in PerformInitialHandshake()
490 Chunk::Type::kStartAckConfirmation); in PerformInitialHandshake()
495 // confirmation chunk so that the server can immediately begin sending in PerformInitialHandshake()
512 case Chunk::Type::kStartAckConfirmation: { in PerformInitialHandshake()
516 HandleTransmitChunk(chunk); in PerformInitialHandshake()
518 HandleReceiveChunk(chunk); in PerformInitialHandshake()
523 // If a non-handshake chunk is received during an INITIATING state, the in PerformInitialHandshake()
526 // and process the chunk appropriately. in PerformInitialHandshake()
527 case Chunk::Type::kData: in PerformInitialHandshake()
528 case Chunk::Type::kParametersRetransmit: in PerformInitialHandshake()
529 case Chunk::Type::kParametersContinue: in PerformInitialHandshake()
532 // legacy chunk. in PerformInitialHandshake()
533 session_id_ = chunk.session_id(); in PerformInitialHandshake()
538 if (chunk.initial_offset() != 0) { in PerformInitialHandshake()
553 HandleTransmitChunk(chunk); in PerformInitialHandshake()
555 HandleReceiveChunk(chunk); in PerformInitialHandshake()
559 case Chunk::Type::kCompletion: in PerformInitialHandshake()
560 case Chunk::Type::kCompletionAck: in PerformInitialHandshake()
568 void Context::UpdateLocalProtocolConfigurationFromPeer(const Chunk& chunk) { in UpdateLocalProtocolConfigurationFromPeer() argument
571 static_cast<int>(chunk.protocol_version())); in UpdateLocalProtocolConfigurationFromPeer()
574 std::min(desired_protocol_version_, chunk.protocol_version()); in UpdateLocalProtocolConfigurationFromPeer()
581 void Context::HandleTransmitChunk(const Chunk& chunk) { in HandleTransmitChunk() argument
585 PW_CRASH("Never should handle chunk while inactive"); in HandleTransmitChunk()
589 // chunk is received, tell the other end that the transfer is over. in HandleTransmitChunk()
590 if (!chunk.IsInitialChunk() && status_.ok()) { in HandleTransmitChunk()
598 PerformInitialHandshake(chunk); in HandleTransmitChunk()
603 if (chunk.protocol_version() == configured_protocol_version_) { in HandleTransmitChunk()
604 HandleTransferParametersUpdate(chunk); in HandleTransmitChunk()
608 "but received a chunk with version %d", in HandleTransmitChunk()
611 static_cast<int>(chunk.protocol_version())); in HandleTransmitChunk()
617 HandleTerminatingChunk(chunk); in HandleTransmitChunk()
622 void Context::HandleTransferParametersUpdate(const Chunk& chunk) { in HandleTransferParametersUpdate() argument
623 bool retransmit = chunk.RequestsTransmissionFromOffset(); in HandleTransferParametersUpdate()
629 if (offset_ != chunk.offset()) { in HandleTransferParametersUpdate()
630 if (Status seek_status = SeekReader(chunk.offset()); !seek_status.ok()) { in HandleTransferParametersUpdate()
633 static_cast<unsigned>(chunk.offset()), in HandleTransferParametersUpdate()
653 offset_ = chunk.offset(); in HandleTransferParametersUpdate()
656 window_end_offset_ = chunk.window_end_offset(); in HandleTransferParametersUpdate()
658 if (chunk.max_chunk_size_bytes().has_value()) { in HandleTransferParametersUpdate()
659 max_chunk_size_bytes_ = std::min(chunk.max_chunk_size_bytes().value(), in HandleTransferParametersUpdate()
663 if (chunk.min_delay_microseconds().has_value()) { in HandleTransferParametersUpdate()
665 std::chrono::microseconds(chunk.min_delay_microseconds().value())); in HandleTransferParametersUpdate()
673 static_cast<unsigned>(chunk.offset()), in HandleTransferParametersUpdate()
682 static_cast<unsigned>(chunk.offset()), in HandleTransferParametersUpdate()
693 Chunk chunk(configured_protocol_version_, Chunk::Type::kData); in TransmitNextChunk() local
694 chunk.set_session_id(session_id_); in TransmitNextChunk()
695 chunk.set_offset(offset_); in TransmitNextChunk()
698 // the buffer for the chunk data. in TransmitNextChunk()
700 chunk.EncodedSize() + 1 /* data key */ + 5 /* data size */; in TransmitNextChunk()
705 pwpb::Chunk::Fields::kRemainingBytes, total_size); in TransmitNextChunk()
712 // Read the next chunk of data into the encode buffer. in TransmitNextChunk()
729 chunk.set_remaining_bytes(0); in TransmitNextChunk()
732 PW_LOG_INFO("Transfer %u sending final chunk with remaining_bytes=0", in TransmitNextChunk()
754 "Transfer %u sending chunk offset=%u size=%u", in TransmitNextChunk()
759 chunk.set_payload(data.value()); in TransmitNextChunk()
764 chunk.set_remaining_bytes(total_size - offset_); in TransmitNextChunk()
774 Result<ConstByteSpan> encoded_chunk = chunk.Encode(buffer); in TransmitNextChunk()
776 PW_LOG_ERROR("Transfer %u failed to encode transmit chunk", in TransmitNextChunk()
783 PW_LOG_ERROR("Transfer %u failed to send transmit chunk, status %u", in TransmitNextChunk()
790 last_chunk_sent_ = chunk.type(); in TransmitNextChunk()
799 // More data is to be sent. Set a timeout to send the next chunk following in TransmitNextChunk()
800 // the chunk delay. in TransmitNextChunk()
805 void Context::HandleReceiveChunk(const Chunk& chunk) { in HandleReceiveChunk() argument
807 PerformInitialHandshake(chunk); in HandleReceiveChunk()
812 // If the transfer has already completed and another chunk is received, in HandleReceiveChunk()
813 // re-send the final status chunk. in HandleReceiveChunk()
818 if (chunk.protocol_version() != configured_protocol_version_) { in HandleReceiveChunk()
821 "but received a chunk with version %d", in HandleReceiveChunk()
824 static_cast<int>(chunk.protocol_version())); in HandleReceiveChunk()
841 if (chunk.offset() != offset_) { in HandleReceiveChunk()
842 if (last_chunk_offset_ == chunk.offset()) { in HandleReceiveChunk()
847 static_cast<unsigned>(chunk.offset())); in HandleReceiveChunk()
859 static_cast<unsigned>(chunk.offset())); in HandleReceiveChunk()
862 last_chunk_offset_ = chunk.offset(); in HandleReceiveChunk()
872 // The correct chunk was received; process it normally. in HandleReceiveChunk()
875 HandleReceivedData(chunk); in HandleReceiveChunk()
879 HandleTerminatingChunk(chunk); in HandleReceiveChunk()
884 void Context::HandleReceivedData(const Chunk& chunk) { in HandleReceivedData() argument
885 if (chunk.offset() != offset_) { in HandleReceivedData()
886 if (chunk.offset() + chunk.payload().size() <= offset_ && in HandleReceivedData()
887 chunk.type() != Chunk::Type::kStartAckConfirmation) { in HandleReceivedData()
888 // If the chunk's data has already been received, don't go through a full in HandleReceivedData()
891 // the transmitter to keep going with a CONTINUE parameters chunk. in HandleReceivedData()
893 // However, as a retried chunk indicates a potential issue with the in HandleReceivedData()
898 PW_LOG_DEBUG("Transfer %u received duplicate chunk with offset %u", in HandleReceivedData()
900 static_cast<unsigned>(chunk.offset())); in HandleReceivedData()
904 // Bad offset; reset window size to send another parameters chunk. in HandleReceivedData()
910 static_cast<unsigned>(chunk.offset())); in HandleReceivedData()
920 if (chunk.offset() + chunk.payload().size() > window_end_offset_) { in HandleReceivedData()
925 static_cast<unsigned>(chunk.payload().size()), in HandleReceivedData()
944 last_chunk_offset_ = chunk.offset(); in HandleReceivedData()
947 if (chunk.has_payload()) { in HandleReceivedData()
948 if (Status status = writer().Write(chunk.payload()); !status.ok()) { in HandleReceivedData()
950 "Transfer %u write of %u B chunk failed with status %u; aborting " in HandleReceivedData()
953 static_cast<unsigned>(chunk.payload().size()), in HandleReceivedData()
959 transfer_rate_.Update(chunk.payload().size()); in HandleReceivedData()
963 offset_ += chunk.payload().size(); in HandleReceivedData()
966 // transfer. Acknowledge the completion through a status chunk and clean up. in HandleReceivedData()
967 if (chunk.IsFinalTransmitChunk()) { in HandleReceivedData()
972 if (chunk.window_end_offset() != 0) { in HandleReceivedData()
973 if (chunk.window_end_offset() < offset_) { in HandleReceivedData()
977 static_cast<unsigned>(chunk.window_end_offset()), in HandleReceivedData()
983 if (chunk.window_end_offset() > window_end_offset_) { in HandleReceivedData()
991 static_cast<unsigned>(chunk.window_end_offset()), in HandleReceivedData()
997 window_end_offset_ = chunk.window_end_offset(); in HandleReceivedData()
1002 if (chunk.type() == Chunk::Type::kStartAckConfirmation) { in HandleReceivedData()
1025 void Context::HandleTerminatingChunk(const Chunk& chunk) { in HandleTerminatingChunk() argument
1026 switch (chunk.type()) { in HandleTerminatingChunk()
1027 case Chunk::Type::kCompletion: in HandleTerminatingChunk()
1030 case Chunk::Type::kCompletionAck: in HandleTerminatingChunk()
1036 case Chunk::Type::kData: in HandleTerminatingChunk()
1037 case Chunk::Type::kStart: in HandleTerminatingChunk()
1038 case Chunk::Type::kParametersRetransmit: in HandleTerminatingChunk()
1039 case Chunk::Type::kParametersContinue: in HandleTerminatingChunk()
1040 case Chunk::Type::kStartAck: in HandleTerminatingChunk()
1041 case Chunk::Type::kStartAckConfirmation: in HandleTerminatingChunk()
1042 // If a non-completion chunk is received in a TERMINATING state, re-send in HandleTerminatingChunk()
1043 // the transfer's completion chunk to the peer. in HandleTerminatingChunk()
1045 Chunk::Final(configured_protocol_version_, session_id_, status_)); in HandleTerminatingChunk()
1071 // Don't send a final chunk if the other end of the transfer has not yet in TerminateTransfer()
1089 Chunk(configured_protocol_version_, Chunk::Type::kCompletionAck) in HandleTermination()
1103 // version for the status chunk. in SendFinalStatusChunk()
1112 PW_LOG_INFO("Sending final chunk for transfer %u with status %u", in SendFinalStatusChunk()
1116 Chunk chunk = in SendFinalStatusChunk() local
1117 Chunk::Final(configured_protocol_version_, session_id_, status_); in SendFinalStatusChunk()
1119 chunk.set_resource_id(resource_id_); in SendFinalStatusChunk()
1121 EncodeAndSendChunk(chunk); in SendFinalStatusChunk()
1149 // has waited for its inter-chunk delay and should transmit its next in HandleTimeout()
1150 // chunk. in HandleTimeout()
1159 // chunk has been received from the other side. The transfer should retry in HandleTimeout()
1164 last_chunk_sent_ == Chunk::Type::kStart) { in HandleTimeout()
1181 "Transfer %u failed to receive a chunk after %u retries (lifetime %u).", in Retry()
1189 // chunk was never ACKed. Simply clean up the transfer context. in Retry()
1201 last_chunk_sent_ == Chunk::Type::kStartAckConfirmation) { in Retry()
1208 Chunk::Final(configured_protocol_version_, session_id_, status_)); in Retry()
1215 "Receive transfer %u timed out waiting for chunk; resending parameters", in Retry()
1222 // In a transmit, if a data chunk has not yet been sent, the initial transfer in Retry()
1223 // parameters did not arrive from the receiver. Resend the initial chunk. in Retry()
1232 // Otherwise, resend the most recent chunk. If the reader doesn't support in Retry()
1242 // Rewind the transfer position and resend the chunk. in Retry()
1249 Chunk retry_chunk(configured_protocol_version_, last_chunk_sent_); in RetryHandshake()
1252 case Chunk::Type::kStart: in RetryHandshake()
1254 // chunk, so we use the client's desired version instead. in RetryHandshake()
1264 case Chunk::Type::kStartAck: in RetryHandshake()
1269 case Chunk::Type::kStartAckConfirmation: in RetryHandshake()
1276 case Chunk::Type::kData: in RetryHandshake()
1277 case Chunk::Type::kParametersRetransmit: in RetryHandshake()
1278 case Chunk::Type::kParametersContinue: in RetryHandshake()
1279 case Chunk::Type::kCompletion: in RetryHandshake()
1280 case Chunk::Type::kCompletionAck: in RetryHandshake()
1289 // Start with the user-provided maximum chunk size, which should be the usable in MaxWriteChunkSize()
1313 // Subtract the transfer service overhead for a client write chunk in MaxWriteChunkSize()
1322 // Use a lower bound of a single chunk for the window end offset, as it will in MaxWriteChunkSize()
1336 "Transfer service maximum chunk size is too small to fit a payload. " in MaxWriteChunkSize()