4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mtftp6 Rrq process functions implementation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync are licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync which accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync http://opensource.org/licenses/bsd-license.php.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "Mtftp6Impl.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Build and send a ACK packet for download.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Instance The pointer to the Mtftp6 instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] BlockNum The block number to be acked.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for the packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The ACK has been sent.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Failed to send the ACK.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncMtftp6RrqSendAck (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN MTFTP6_INSTANCE *Instance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT16 BlockNum
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_MTFTP6_PACKET *Ack;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NET_BUF *Packet;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Allocate net buffer to create ack packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet = NetbufAlloc (sizeof (EFI_MTFTP6_ACK_HEADER));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Packet == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ack = (EFI_MTFTP6_PACKET *) NetbufAllocSpace (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (EFI_MTFTP6_ACK_HEADER),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FALSE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Ack != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ack->Ack.OpCode = HTONS (EFI_MTFTP6_OPCODE_ACK);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ack->Ack.Block[0] = HTONS (BlockNum);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Reset current retry count of the instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance->CurRetry = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Mtftp6TransmitPacket (Instance, Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Deliver the received data block to the user, which can be saved
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync in the user provide buffer or through the CheckPacket callback.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Instance The pointer to the Mtftp6 instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Packet The pointer to the received packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Len The packet length.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] UdpPacket The net buf of the received packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The data was saved successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ABORTED The user tells to abort by return an error through
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CheckPacket.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_BUFFER_TOO_SMALL The user's buffer is too small, and buffer length is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync updated to the actual buffer size needed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncMtftp6RrqSaveBlock (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN MTFTP6_INSTANCE *Instance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_MTFTP6_PACKET *Packet,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 Len,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT NET_BUF **UdpPacket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_MTFTP6_TOKEN *Token;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Block;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 Start;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 DataLen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 TotalBlock;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN Completed;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Completed = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Token = Instance->Token;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Block = NTOHS (Packet->Data.Block);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataLen = Len - MTFTP6_DATA_HEAD_LEN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // This is the last block, save the block num
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (DataLen < Instance->BlkSize) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Completed = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance->LastBlk = Block;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mtftp6SetLastBlockNum (&Instance->BlkList, Block);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Remove this block number from the file hole. If Mtftp6RemoveBlockNum
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // returns EFI_NOT_FOUND, the block has been saved, don't save it again.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Note that : For bigger files, allowing the block counter to roll over
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // to accept transfers of unlimited size. So TotalBlock is memorised as
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // continuous block counter.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Mtftp6RemoveBlockNum (&Instance->BlkList, Block, Completed, &TotalBlock);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Status == EFI_NOT_FOUND) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Token->CheckPacket != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Callback to the check packet routine with the received packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Token->CheckPacket (&Instance->Mtftp6, Token, (UINT16) Len, Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Free the received packet before send new packet in ReceiveNotify,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // since the Udp6Io might need to be reconfigured.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufFree (*UdpPacket);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *UdpPacket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send the Mtftp6 error message if user aborted the current session.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mtftp6SendError (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_MTFTP6_ERRORCODE_ILLEGAL_OPERATION,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8 *) "User aborted download"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Token->Buffer != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Start = MultU64x32 (TotalBlock - 1, Instance->BlkSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Start + DataLen <= Token->BufferSize) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem ((UINT8 *) Token->Buffer + Start, Packet->Data.Data, DataLen);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the file size when received the last block
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Instance->LastBlk == Block) && Completed) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Token->BufferSize = Start + DataLen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (Instance->LastBlk != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Don't save the data if the buffer is too small, return
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // EFI_BUFFER_TOO_SMALL if received the last packet. This
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // will give a accurate file length.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Token->BufferSize = Start + DataLen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Free the received packet before send new packet in ReceiveNotify,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // since the udpio might need to be reconfigured.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufFree (*UdpPacket);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *UdpPacket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send the Mtftp6 error message if no enough buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mtftp6SendError (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_MTFTP6_ERRORCODE_DISK_FULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8 *) "User provided memory block is too small"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_BUFFER_TOO_SMALL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process the received data packets. It will save the block
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync then send back an ACK if it is active.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Instance The pointer to the Mtftp6 instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Packet The pointer to the received packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Len The length of the packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] UdpPacket The net buf of received packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] IsCompleted If TRUE, the download has been completed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Otherwise, the download has not been completed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The data packet was successfully processed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ABORTED The download was aborted by the user.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_BUFFER_TOO_SMALL The user-provided buffer is too small.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncMtftp6RrqHandleData (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN MTFTP6_INSTANCE *Instance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_MTFTP6_PACKET *Packet,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 Len,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT NET_BUF **UdpPacket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT BOOLEAN *IsCompleted
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 BlockNum;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync INTN Expected;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *IsCompleted = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BlockNum = NTOHS (Packet->Data.Block);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Expected = Mtftp6GetNextBlockNum (&Instance->BlkList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Expected >= 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If we are active and received an unexpected packet, retransmit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the last ACK then restart receiving. If we are passive, save
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the block.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Instance->IsMaster && (Expected != BlockNum)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Free the received packet before send new packet in ReceiveNotify,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // since the udpio might need to be reconfigured.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufFree (*UdpPacket);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *UdpPacket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mtftp6TransmitPacket (Instance, Instance->LastPacket);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Mtftp6RrqSaveBlock (Instance, Packet, Len, UdpPacket);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Reset the passive client's timer whenever it received a valid data packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!Instance->IsMaster) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance->PacketToLive = Instance->Timeout * 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether we have received all the blocks. Send the ACK if we
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // are active (unicast client or master client for multicast download).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If we have received all the blocks, send an ACK even if we are passive
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // to tell the server that we are done.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Expected = Mtftp6GetNextBlockNum (&Instance->BlkList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Instance->IsMaster || Expected < 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Expected < 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If we are passive client, then the just received Block maybe
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // isn't the last block. We need to send an ACK to the last block
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // to inform the server that we are done. If we are active client,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the Block == Instance->LastBlock.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BlockNum = Instance->LastBlk;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *IsCompleted = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BlockNum = (UINT16) (Expected - 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Free the received packet before send new packet in ReceiveNotify,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // since the udpio might need to be reconfigured.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufFree (*UdpPacket);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *UdpPacket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mtftp6RrqSendAck (Instance, BlockNum);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Validate whether the options received in the server's OACK packet is valid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The options are valid only if:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 1. The server doesn't include options not requested by us.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 2. The server can only use smaller blksize than that is requested.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 3. The server can only use the same timeout as requested.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 4. The server doesn't change its multicast channel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Instance The pointer to the Mtftp6 instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] ReplyInfo The pointer to options information in reply packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] RequestInfo The pointer to requested options info.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval TRUE If the option in the OACK is valid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval FALSE If the option is invalid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBOOLEAN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncMtftp6RrqOackValid (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN MTFTP6_INSTANCE *Instance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN MTFTP6_EXT_OPTION_INFO *ReplyInfo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN MTFTP6_EXT_OPTION_INFO *RequestInfo
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // It is invalid for server to return options we don't request
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((ReplyInfo->BitMap & ~RequestInfo->BitMap) != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Server can only specify a smaller block size to be used and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // return the timeout matches that requested.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((((ReplyInfo->BitMap & MTFTP6_OPT_BLKSIZE_BIT) != 0) && (ReplyInfo->BlkSize > RequestInfo->BlkSize)) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (((ReplyInfo->BitMap & MTFTP6_OPT_TIMEOUT_BIT) != 0) && (ReplyInfo->Timeout != RequestInfo->Timeout))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The server can send ",,master" to client to change its master
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // setting. But if it use the specific multicast channel, it can't
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // change the setting.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (((ReplyInfo->BitMap & MTFTP6_OPT_MCAST_BIT) != 0) && !NetIp6IsUnspecifiedAddr (&Instance->McastIp)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!NetIp6IsUnspecifiedAddr (&ReplyInfo->McastIp) && CompareMem (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &ReplyInfo->McastIp,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Instance->McastIp,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (EFI_IPv6_ADDRESS)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ) != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((ReplyInfo->McastPort != 0) && (ReplyInfo->McastPort != Instance->McastPort)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Configure Udp6Io to receive a packet from a multicast address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] McastIo The pointer to the mcast Udp6Io.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Context The pointer to the context.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The mcast Udp6Io was successfully configured.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Failed to configure the Udp6Io.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncMtftp6RrqConfigMcastUdpIo (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UDP_IO *McastIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_UDP6_PROTOCOL *Udp6;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_UDP6_CONFIG_DATA *Udp6Cfg;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IPv6_ADDRESS Group;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MTFTP6_INSTANCE *Instance;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Udp6 = McastIo->Protocol.Udp6;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Udp6Cfg = &(McastIo->Config.Udp6);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance = (MTFTP6_INSTANCE *) Context;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the configure data for the mcast Udp6Io.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (Udp6Cfg, sizeof (EFI_UDP6_CONFIG_DATA));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Udp6Cfg->AcceptPromiscuous = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Udp6Cfg->AcceptAnyPort = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Udp6Cfg->AllowDuplicatePort = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Udp6Cfg->TrafficClass = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Udp6Cfg->HopLimit = 128;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Udp6Cfg->ReceiveTimeout = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Udp6Cfg->TransmitTimeout = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Udp6Cfg->StationPort = Instance->McastPort;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Udp6Cfg->RemotePort = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Udp6Cfg->RemoteAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Instance->ServerIp,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (EFI_IPv6_ADDRESS)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Configure the mcast Udp6Io.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Udp6->Configure (Udp6, Udp6Cfg);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Join the multicast group
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&Group, &Instance->McastIp, sizeof (EFI_IPv6_ADDRESS));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Udp6->Groups (Udp6, TRUE, &Group);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process the OACK packet for Rrq.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Instance The pointer to the Mtftp6 instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Packet The pointer to the received packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Len The length of the packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] UdpPacket The net buf of received packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] IsCompleted If TRUE, the download has been completed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Otherwise, the download has not been completed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR Failed to create/start a multicast Udp6 child.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_TFTP_ERROR An error happened during the process.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The OACK packet successfully processed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncMtftp6RrqHandleOack (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN MTFTP6_INSTANCE *Instance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_MTFTP6_PACKET *Packet,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 Len,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT NET_BUF **UdpPacket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT BOOLEAN *IsCompleted
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_MTFTP6_OPTION *Options;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Count;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MTFTP6_EXT_OPTION_INFO ExtInfo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync INTN Expected;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *IsCompleted = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If already started the master download, don't change the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // setting. Master download always succeeds.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Expected = Mtftp6GetNextBlockNum (&Instance->BlkList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Expected != -1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Instance->IsMaster && Expected != 1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (&ExtInfo, sizeof (MTFTP6_EXT_OPTION_INFO));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Parse the options in the packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Mtftp6ParseStart (Packet, Len, &Count, &Options);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Options != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Parse the extensive options in the packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Mtftp6ParseExtensionOption (Options, Count, FALSE, &ExtInfo);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status) || !Mtftp6RrqOackValid (Instance, &ExtInfo, &Instance->ExtInfo)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Don't send an ERROR packet if the error is EFI_OUT_OF_RESOURCES.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Status != EFI_OUT_OF_RESOURCES) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Free the received packet before send new packet in ReceiveNotify,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // since the udpio might need to be reconfigured.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufFree (*UdpPacket);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *UdpPacket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send the Mtftp6 error message if invalid packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mtftp6SendError (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_MTFTP6_ERRORCODE_ILLEGAL_OPERATION,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8 *) "Mal-formated OACK packet"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_TFTP_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((ExtInfo.BitMap & MTFTP6_OPT_MCAST_BIT) != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Save the multicast info. Always update the Master, only update the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // multicast IP address, block size, timeoute at the first time. If IP
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // address is updated, create a UDP child to receive the multicast.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance->IsMaster = ExtInfo.IsMaster;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NetIp6IsUnspecifiedAddr (&Instance->McastIp)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NetIp6IsUnspecifiedAddr (&ExtInfo.McastIp) || ExtInfo.McastPort == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Free the received packet before send new packet in ReceiveNotify,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // since the udpio might need to be reconfigured.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufFree (*UdpPacket);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *UdpPacket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send the Mtftp6 error message if invalid multi-cast setting.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mtftp6SendError (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_MTFTP6_ERRORCODE_ILLEGAL_OPERATION,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8 *) "Illegal multicast setting"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_TFTP_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create a UDP child then start receive the multicast from it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Instance->McastIp,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &ExtInfo.McastIp,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (EFI_IP_ADDRESS)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance->McastPort = ExtInfo.McastPort;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance->McastUdpIo = UdpIoCreateIo (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance->Service->Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance->Service->Image,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mtftp6RrqConfigMcastUdpIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UDP_IO_UDP6_VERSION,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Instance->McastUdpIo == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = UdpIoRecvDatagram (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance->McastUdpIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mtftp6RrqInput,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Free the received packet before send new packet in ReceiveNotify,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // since the udpio might need to be reconfigured.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufFree (*UdpPacket);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *UdpPacket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send the Mtftp6 error message if failed to create Udp6Io to receive.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mtftp6SendError (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_MTFTP6_ERRORCODE_ACCESS_VIOLATION,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8 *) "Failed to create socket to receive multicast packet"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the parameters used.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ExtInfo.BlkSize != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance->BlkSize = ExtInfo.BlkSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ExtInfo.Timeout != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance->Timeout = ExtInfo.Timeout;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance->IsMaster = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ExtInfo.BlkSize != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance->BlkSize = ExtInfo.BlkSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ExtInfo.Timeout != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance->Timeout = ExtInfo.Timeout;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Free the received packet before send new packet in ReceiveNotify,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // since the udpio might need to be reconfigured.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufFree (*UdpPacket);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *UdpPacket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send an ACK to (Expected - 1) which is 0 for unicast download,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // or tell the server we want to receive the Expected block.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Mtftp6RrqSendAck (Instance, (UINT16) (Expected - 1));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The packet process callback for Mtftp6 download.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] UdpPacket The pointer to the packet received.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] UdpEpt The pointer to the Udp6 access point.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IoStatus The status from Udp6 instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Context The pointer to the context.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncMtftp6RrqInput (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN NET_BUF *UdpPacket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UDP_END_POINT *UdpEpt,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_STATUS IoStatus,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MTFTP6_INSTANCE *Instance;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_MTFTP6_PACKET *Packet;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN IsCompleted;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN IsMcast;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Opcode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 TotalNum;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Len;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance = (MTFTP6_INSTANCE *) Context;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NET_CHECK_SIGNATURE (Instance, MTFTP6_INSTANCE_SIGNATURE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IsCompleted = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IsMcast = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalNum = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return error status if Udp6 instance failed to receive.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (IoStatus)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IoStatus;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_EXIT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (UdpPacket != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (UdpPacket->TotalSize < MTFTP6_OPCODE_LEN) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_EXIT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Find the port this packet is from to restart receive correctly.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CompareMem (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6Swap128 (&UdpEpt->LocalAddr.v6),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Instance->McastIp,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (EFI_IPv6_ADDRESS)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IsMcast = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IsMcast = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Client send initial request to server's listening port. Server
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // will select a UDP port to communicate with the client. The server
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // is required to use the same port as RemotePort to multicast the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (UdpEpt->RemotePort != Instance->ServerDataPort) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Instance->ServerDataPort != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_EXIT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // For the subsequent exchange of requests, reconfigure the udpio as
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // (serverip, serverport, localip, localport).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Ususally, the client set serverport as 0 to receive and reset it
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // once the first packet arrives to send ack.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance->ServerDataPort = UdpEpt->RemotePort;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Copy the MTFTP packet to a continuous buffer if it isn't already so.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Len = UdpPacket->TotalSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalNum = UdpPacket->BlockOpNum;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TotalNum > 1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet = AllocateZeroPool (Len);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Packet == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_EXIT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufCopy (UdpPacket, 0, Len, (UINT8 *) Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet = (EFI_MTFTP6_PACKET *) NetbufGetByte (UdpPacket, 0, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Packet != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Opcode = NTOHS (Packet->OpCode);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Callback to the user's CheckPacket if provided. Abort the transmission
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // if CheckPacket returns an EFI_ERROR code.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Instance->Token->CheckPacket != NULL) &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (Opcode == EFI_MTFTP6_OPCODE_OACK || Opcode == EFI_MTFTP6_OPCODE_ERROR)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Instance->Token->CheckPacket (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Instance->Mtftp6,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance->Token,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT16) Len,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send an error message to the server to inform it
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Opcode != EFI_MTFTP6_OPCODE_ERROR) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Free the received packet before send new packet in ReceiveNotify,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // since the udpio might need to be reconfigured.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufFree (UdpPacket);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UdpPacket = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send the Mtftp6 error message if user aborted the current session.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mtftp6SendError (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_MTFTP6_ERRORCODE_REQUEST_DENIED,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8 *) "User aborted the transfer"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_EXIT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Switch the process routines by the operation code.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (Opcode) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case EFI_MTFTP6_OPCODE_DATA:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Len > (UINT32) (MTFTP6_DATA_HEAD_LEN + Instance->BlkSize)) || (Len < (UINT32) MTFTP6_DATA_HEAD_LEN)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_EXIT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Handle the data packet of Rrq.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Mtftp6RrqHandleData (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Len,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &UdpPacket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &IsCompleted
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case EFI_MTFTP6_OPCODE_OACK:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IsMcast || Len <= MTFTP6_OPCODE_LEN) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_EXIT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Handle the Oack packet of Rrq.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Mtftp6RrqHandleOack (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Len,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &UdpPacket,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &IsCompleted
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Drop and return eror if received error message.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_TFTP_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncON_EXIT:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Free the resources, then if !EFI_ERROR (Status), restart the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // receive, otherwise end the session.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Packet != NULL && TotalNum > 1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (UdpPacket != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufFree (UdpPacket);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!EFI_ERROR (Status) && !IsCompleted) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IsMcast) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = UdpIoRecvDatagram (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance->McastUdpIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mtftp6RrqInput,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = UdpIoRecvDatagram (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance->UdpIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mtftp6RrqInput,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Clean up the current session if failed to continue.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status) || IsCompleted) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mtftp6OperationClean (Instance, Status);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Start the Mtftp6 instance to download. It first initializes some
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync of the internal states, then builds and sends an RRQ reqeuest packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Finally, it starts receive for the downloading.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Instance The pointer to the Mtftp6 instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Operation The operation code of current packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The Mtftp6 is started to download.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Failed to start to download.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncMtftp6RrqStart (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN MTFTP6_INSTANCE *Instance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT16 Operation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The valid block number range are [1, 0xffff]. For example:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the client sends an RRQ request to the server, the server
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // transfers the DATA1 block. If option negoitation is ongoing,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the server will send back an OACK, then client will send ACK0.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Mtftp6InitBlockRange (&Instance->BlkList, 1, 0xffff);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Mtftp6SendRequest (Instance, Operation);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return UdpIoRecvDatagram (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance->UdpIo,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mtftp6RrqInput,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Instance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync