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