/** @file
  Mtftp6 Rrq process functions implementation.

  Copyright (c) 2009 - 2010, 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;

  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;

  *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;
  }

  //
  // 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;
      Instance->McastUdpIo = UdpIoCreateIo (
                               Instance->Service->Controller,
                               Instance->Service->Image,
                               Mtftp6RrqConfigMcastUdpIo,
                               UDP_IO_UDP6_VERSION,
                               Instance
                               );

      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
           );
}

