/** @file
  Mtftp6 support 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"


/**
  Allocate a MTFTP block range, then init it to the range of [Start, End].

  @param[in]  Start                  The start block number.
  @param[in]  End                    The last block number in the range.

  @return Range                      The range of the allocated block buffer.

**/
MTFTP6_BLOCK_RANGE *
Mtftp6AllocateRange (
  IN UINT16                 Start,
  IN UINT16                 End
  )
{
  MTFTP6_BLOCK_RANGE        *Range;

  Range = AllocateZeroPool (sizeof (MTFTP6_BLOCK_RANGE));

  if (Range == NULL) {
    return NULL;
  }

  InitializeListHead (&Range->Link);
  Range->Start  = Start;
  Range->End    = End;
  Range->Bound  = End;

  return Range;
}


/**
  Initialize the block range for either RRQ or WRQ. RRQ and WRQ have
  different requirements for Start and End. For example, during startup,
  WRQ initializes its whole valid block range to [0, 0xffff]. This
  is bacause the server will send an ACK0 to inform the user to start the
  upload. When the client receives an ACK0, it will remove 0 from the range,
  get the next block number, which is 1, then upload the BLOCK1. For RRQ
  without option negotiation, the server will directly send the BLOCK1
  in response to the client's RRQ. When received BLOCK1, the client will
  remove it from the block range and send an ACK. It also works if there
  is option negotiation.

  @param[in]  Head                   The block range head to initialize.
  @param[in]  Start                  The Start block number.
  @param[in]  End                    The last block number.

  @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory for initial block range.
  @retval EFI_SUCCESS            The initial block range is created.

**/
EFI_STATUS
Mtftp6InitBlockRange (
  IN LIST_ENTRY             *Head,
  IN UINT16                 Start,
  IN UINT16                 End
  )
{
  MTFTP6_BLOCK_RANGE        *Range;

  Range = Mtftp6AllocateRange (Start, End);

  if (Range == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  InsertTailList (Head, &Range->Link);
  return EFI_SUCCESS;
}


/**
  Get the first valid block number on the range list.

  @param[in]  Head                   The block range head.

  @retval     ==-1                   If the block range is empty.
  @retval     >-1                    The first valid block number.

**/
INTN
Mtftp6GetNextBlockNum (
  IN LIST_ENTRY              *Head
  )
{
  MTFTP6_BLOCK_RANGE  *Range;

  if (IsListEmpty (Head)) {
    return -1;
  }

  Range = NET_LIST_HEAD (Head, MTFTP6_BLOCK_RANGE, Link);
  return Range->Start;
}


/**
  Set the last block number of the block range list. It
  removes all the blocks after the Last. MTFTP initialize the
  block range to the maximum possible range, such as [0, 0xffff]
  for WRQ. When it gets the last block number, it calls
  this function to set the last block number.

  @param[in]  Head                   The block range list.
  @param[in]  Last                   The last block number.

**/
VOID
Mtftp6SetLastBlockNum (
  IN LIST_ENTRY             *Head,
  IN UINT16                 Last
  )
{
  MTFTP6_BLOCK_RANGE        *Range;

  //
  // Iterate from the tail to head to remove the block number
  // after the last.
  //
  while (!IsListEmpty (Head)) {
    Range = NET_LIST_TAIL (Head, MTFTP6_BLOCK_RANGE, Link);

    if (Range->Start > Last) {
      RemoveEntryList (&Range->Link);
      FreePool (Range);
      continue;
    }

    if (Range->End > Last) {
      Range->End = Last;
    }
    return ;
  }
}


/**
  Remove the block number from the block range list.

  @param[in]  Head                   The block range list to remove from.
  @param[in]  Num                    The block number to remove.
  @param[in]  Completed              Whether Num is the last block number
  @param[out] TotalBlock             The continuous block number in all

  @retval EFI_NOT_FOUND          The block number isn't in the block range list.
  @retval EFI_SUCCESS            The block number has been removed from the list.
  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.

**/
EFI_STATUS
Mtftp6RemoveBlockNum (
  IN LIST_ENTRY             *Head,
  IN UINT16                 Num,
  IN BOOLEAN                Completed,
  OUT UINT64                *TotalBlock
  )
{
  MTFTP6_BLOCK_RANGE        *Range;
  MTFTP6_BLOCK_RANGE        *NewRange;
  LIST_ENTRY                *Entry;

  NET_LIST_FOR_EACH (Entry, Head) {

    //
    // Each block represents a hole [Start, End] in the file,
    // skip to the first range with End >= Num
    //
    Range = NET_LIST_USER_STRUCT (Entry, MTFTP6_BLOCK_RANGE, Link);

    if (Range->End < Num) {
      continue;
    }

    //
    // There are three different cases for Start
    // 1. (Start > Num) && (End >= Num):
    //    because all the holes before this one has the condition of
    //    End < Num, so this block number has been removed.
    //
    // 2. (Start == Num) && (End >= Num):
    //    Need to increase the Start by one, and if End == Num, this
    //    hole has been removed completely, remove it.
    //
    // 3. (Start < Num) && (End >= Num):
    //    if End == Num, only need to decrease the End by one because
    //    we have (Start < Num) && (Num == End), so (Start <= End - 1).
    //    if (End > Num), the hold is splited into two holes, with
    //    [Start, Num - 1] and [Num + 1, End].
    //
    if (Range->Start > Num) {
      return EFI_NOT_FOUND;

    } else if (Range->Start == Num) {
      Range->Start++;

      //
      // Note that: RFC 1350 does not mention block counter roll-over,
      // but several TFTP hosts implement the roll-over be able to accept
      // transfers of unlimited size. There is no consensus, however, whether
      // the counter should wrap around to zero or to one. Many implementations
      // wrap to zero, because this is the simplest to implement. Here we choose
      // this solution.
      //
      *TotalBlock  = Num;

      if (Range->Round > 0) {
        *TotalBlock += Range->Bound +  MultU64x32 ((UINT64) (Range->Round -1), (UINT32)(Range->Bound + 1)) + 1;
      }

      if (Range->Start > Range->Bound) {
        Range->Start = 0;
        Range->Round ++;
      }

      if ((Range->Start > Range->End) || Completed) {
        RemoveEntryList (&Range->Link);
        FreePool (Range);
      }

      return EFI_SUCCESS;

    } else {
      if (Range->End == Num) {
        Range->End--;
      } else {
        NewRange = Mtftp6AllocateRange ((UINT16) (Num + 1), (UINT16) Range->End);

        if (NewRange == NULL) {
          return EFI_OUT_OF_RESOURCES;
        }

        Range->End = Num - 1;
        NetListInsertAfter (&Range->Link, &NewRange->Link);
      }

      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}


/**
  Configure the opened Udp6 instance until the corresponding Ip6 instance
  has been configured.

  @param[in]  UdpIo                  The pointer to the Udp6 Io.
  @param[in]  UdpCfgData             The pointer to the Udp6 configure data.

  @retval EFI_SUCCESS            Configure the Udp6 instance successfully.
  @retval EFI_NO_MAPPING         The corresponding Ip6 instance has not
                                 been configured yet.

**/
EFI_STATUS
Mtftp6GetMapping (
  IN UDP_IO                 *UdpIo,
  IN EFI_UDP6_CONFIG_DATA   *UdpCfgData
  )
{
  EFI_IP6_MODE_DATA         Ip6Mode;
  EFI_UDP6_PROTOCOL         *Udp6;
  EFI_STATUS                Status;
  EFI_EVENT                 Event;

  Event  = NULL;
  Udp6   = UdpIo->Protocol.Udp6;

  //
  // Create a timer to check whether the Ip6 instance configured or not.
  //
  Status = gBS->CreateEvent (
                  EVT_TIMER,
                  TPL_CALLBACK,
                  NULL,
                  NULL,
                  &Event
                  );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  Status = gBS->SetTimer (
                  Event,
                  TimerRelative,
                  MTFTP6_GET_MAPPING_TIMEOUT * MTFTP6_TICK_PER_SECOND
                  );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Check the Ip6 mode data till timeout.
  //
  while (EFI_ERROR (gBS->CheckEvent (Event))) {

    Udp6->Poll (Udp6);

    Status = Udp6->GetModeData (Udp6, NULL, &Ip6Mode, NULL, NULL);

    if (!EFI_ERROR (Status)) {

      if  (Ip6Mode.IsConfigured) {
        //
        // Continue to configure the Udp6 instance.
        //
        Status = Udp6->Configure (Udp6, UdpCfgData);
      } else {
        Status = EFI_NO_MAPPING;
      }
    }
  }

ON_EXIT:

  if (Event != NULL) {
    gBS->CloseEvent (Event);
  }

  return Status;
}


/**
  The dummy configure routine for create a new Udp6 Io.

  @param[in]  UdpIo                  The pointer to the Udp6 Io.
  @param[in]  Context                The pointer to the context.

  @retval EFI_SUCCESS                This value is always returned.

**/
EFI_STATUS
EFIAPI
Mtftp6ConfigDummyUdpIo (
  IN UDP_IO                 *UdpIo,
  IN VOID                   *Context
  )
{
  return EFI_SUCCESS;
}


/**
  The configure routine for Mtftp6 instance to transmit/receive.

  @param[in]  UdpIo                  The pointer to the Udp6 Io.
  @param[in]  ServerIp               The pointer to the server address.
  @param[in]  ServerPort             The pointer to the server port.
  @param[in]  LocalIp                The pointer to the local address.
  @param[in]  LocalPort              The pointer to the local port.

  @retval EFI_SUCCESS            Configured the Udp6 Io for Mtftp6 successfully.
  @retval EFI_NO_MAPPING         The corresponding Ip6 instance has not been
                                 configured yet.

**/
EFI_STATUS
Mtftp6ConfigUdpIo (
  IN UDP_IO                 *UdpIo,
  IN EFI_IPv6_ADDRESS       *ServerIp,
  IN UINT16                 ServerPort,
  IN EFI_IPv6_ADDRESS       *LocalIp,
  IN UINT16                 LocalPort
  )
{
  EFI_STATUS                Status;
  EFI_UDP6_PROTOCOL         *Udp6;
  EFI_UDP6_CONFIG_DATA      *Udp6Cfg;

  Udp6    = UdpIo->Protocol.Udp6;
  Udp6Cfg = &(UdpIo->Config.Udp6);

  ZeroMem (Udp6Cfg, sizeof (EFI_UDP6_CONFIG_DATA));

  //
  // Set the Udp6 Io configure data.
  //
  Udp6Cfg->AcceptPromiscuous  = FALSE;
  Udp6Cfg->AcceptAnyPort      = FALSE;
  Udp6Cfg->AllowDuplicatePort = FALSE;
  Udp6Cfg->TrafficClass       = 0;
  Udp6Cfg->HopLimit           = 128;
  Udp6Cfg->ReceiveTimeout     = 0;
  Udp6Cfg->TransmitTimeout    = 0;
  Udp6Cfg->StationPort        = LocalPort;
  Udp6Cfg->RemotePort         = ServerPort;

  CopyMem (
    &Udp6Cfg->StationAddress,
    LocalIp,
    sizeof (EFI_IPv6_ADDRESS)
    );

  CopyMem (
    &Udp6Cfg->RemoteAddress,
    ServerIp,
    sizeof (EFI_IPv6_ADDRESS)
    );

  //
  // Configure the Udp6 instance with current configure data.
  //
  Status = Udp6->Configure (Udp6, Udp6Cfg);

  if (Status == EFI_NO_MAPPING) {

    return Mtftp6GetMapping (UdpIo, Udp6Cfg);
  }

  return Status;
}


/**
  Build and transmit the request packet for the Mtftp6 instance.

  @param[in]  Instance               The pointer to the Mtftp6 instance.
  @param[in]  Operation              The operation code of this packet.

  @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory for the request.
  @retval EFI_SUCCESS            The request is built and sent.
  @retval Others                 Failed to transmit the packet.

**/
EFI_STATUS
Mtftp6SendRequest (
  IN MTFTP6_INSTANCE        *Instance,
  IN UINT16                 Operation
  )
{
  EFI_MTFTP6_PACKET         *Packet;
  EFI_MTFTP6_OPTION         *Options;
  EFI_MTFTP6_TOKEN          *Token;
  NET_BUF                   *Nbuf;
  UINT8                     *Mode;
  UINT8                     *Cur;
  UINT32                    Len1;
  UINT32                    Len2;
  UINT32                    Len;
  UINTN                     Index;

  Token   = Instance->Token;
  Options = Token->OptionList;
  Mode    = Token->ModeStr;

  if (Mode == NULL) {
    Mode = (UINT8 *) "octet";
  }

  //
  // The header format of RRQ/WRQ packet is:
  //
  //   2 bytes     string    1 byte     string   1 byte
  //   ------------------------------------------------
  //  | Opcode |  Filename  |   0  |    Mode    |   0  |
  //   ------------------------------------------------
  //
  // The common option format is:
  //
  //    string     1 byte     string   1 byte
  //   ---------------------------------------
  //  | OptionStr |   0  |  ValueStr  |   0   |
  //   ---------------------------------------
  //

  //
  // Compute the size of new Mtftp6 packet.
  //
  Len1 = (UINT32) AsciiStrLen ((CHAR8 *) Token->Filename);
  Len2 = (UINT32) AsciiStrLen ((CHAR8 *) Mode);
  Len  = Len1 + Len2 + 4;

  for (Index = 0; Index < Token->OptionCount; Index++) {
    Len1  = (UINT32) AsciiStrLen ((CHAR8 *) Options[Index].OptionStr);
    Len2  = (UINT32) AsciiStrLen ((CHAR8 *) Options[Index].ValueStr);
    Len  += Len1 + Len2 + 2;
  }

  //
  // Allocate a packet then copy the data.
  //
  if ((Nbuf = NetbufAlloc (Len)) == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Copy the opcode, filename and mode into packet.
  //
  Packet         = (EFI_MTFTP6_PACKET *) NetbufAllocSpace (Nbuf, Len, FALSE);
  ASSERT (Packet != NULL);

  Packet->OpCode = HTONS (Operation);
  Cur            = Packet->Rrq.Filename;
  Cur            = (UINT8 *) AsciiStrCpy ((CHAR8 *) Cur, (CHAR8 *) Token->Filename);
  Cur           += AsciiStrLen ((CHAR8 *) Token->Filename) + 1;
  Cur            = (UINT8 *) AsciiStrCpy ((CHAR8 *) Cur, (CHAR8 *) Mode);
  Cur           += AsciiStrLen ((CHAR8 *) Mode) + 1;

  //
  // Copy all the extension options into the packet.
  //
  for (Index = 0; Index < Token->OptionCount; ++Index) {
    Cur  = (UINT8 *) AsciiStrCpy ((CHAR8 *) Cur, (CHAR8 *) Options[Index].OptionStr);
    Cur += AsciiStrLen ((CHAR8 *) Options[Index].OptionStr) + 1;
    Cur  = (UINT8 *) AsciiStrCpy ((CHAR8 *) Cur, (CHAR8 *) Options[Index].ValueStr);
    Cur += AsciiStrLen ((CHAR8 *) (CHAR8 *) Options[Index].ValueStr) + 1;
  }

  //
  // Save the packet buf for retransmit
  //
  if (Instance->LastPacket != NULL) {
    NetbufFree (Instance->LastPacket);
  }

  Instance->LastPacket = Nbuf;
  Instance->CurRetry   = 0;

  return Mtftp6TransmitPacket (Instance, Nbuf);
}


/**
  Build and send an error packet.

  @param[in]  Instance               The pointer to the Mtftp6 instance.
  @param[in]  ErrCode                The error code in the packet.
  @param[in]  ErrInfo                The error message in the packet.

  @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory for the error packet.
  @retval EFI_SUCCESS            The error packet is transmitted.
  @retval Others                 Failed to transmit the packet.

**/
EFI_STATUS
Mtftp6SendError (
  IN MTFTP6_INSTANCE        *Instance,
  IN UINT16                 ErrCode,
  IN UINT8*                 ErrInfo
  )
{
  NET_BUF                   *Nbuf;
  EFI_MTFTP6_PACKET         *TftpError;
  UINT32                    Len;

  //
  // Allocate a packet then copy the data.
  //
  Len  = (UINT32) (AsciiStrLen ((CHAR8 *) ErrInfo) + sizeof (EFI_MTFTP6_ERROR_HEADER));
  Nbuf = NetbufAlloc (Len);

  if (Nbuf == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  TftpError = (EFI_MTFTP6_PACKET *) NetbufAllocSpace (Nbuf, Len, FALSE);

  if (TftpError == NULL) {
    NetbufFree (Nbuf);
    return EFI_OUT_OF_RESOURCES;
  }

  TftpError->OpCode          = HTONS (EFI_MTFTP6_OPCODE_ERROR);
  TftpError->Error.ErrorCode = HTONS (ErrCode);

  AsciiStrCpy ((CHAR8 *) TftpError->Error.ErrorMessage, (CHAR8 *) ErrInfo);

  //
  // Save the packet buf for retransmit
  //
  if (Instance->LastPacket != NULL) {
    NetbufFree (Instance->LastPacket);
  }

  Instance->LastPacket = Nbuf;
  Instance->CurRetry   = 0;

  return Mtftp6TransmitPacket (Instance, Nbuf);
}


/**
  The callback function called when the packet is transmitted.

  @param[in]  Packet                 The pointer to the packet.
  @param[in]  UdpEpt                 The pointer to the Udp6 access point.
  @param[in]  IoStatus               The result of the transmission.
  @param[in]  Context                The pointer to the context.

**/
VOID
EFIAPI
Mtftp6OnPacketSent (
  IN NET_BUF                   *Packet,
  IN UDP_END_POINT             *UdpEpt,
  IN EFI_STATUS                IoStatus,
  IN VOID                      *Context
  )
{
  NetbufFree (Packet);
  *(BOOLEAN *) Context = TRUE;
}


/**
  Send the packet for the Mtftp6 instance.

  @param[in]  Instance               The pointer to the Mtftp6 instance.
  @param[in]  Packet                 The pointer to the packet to be sent.

  @retval EFI_SUCCESS            The packet was sent out
  @retval Others                 Failed to transmit the packet.

**/
EFI_STATUS
Mtftp6TransmitPacket (
  IN MTFTP6_INSTANCE        *Instance,
  IN NET_BUF                *Packet
  )
{
  EFI_UDP6_PROTOCOL         *Udp6;
  EFI_UDP6_CONFIG_DATA      Udp6CfgData;
  EFI_STATUS                Status;
  UINT16                    *Temp;
  UINT16                    Value;
  UINT16                    OpCode;

  ZeroMem (&Udp6CfgData, sizeof(EFI_UDP6_CONFIG_DATA));
  Udp6 = Instance->UdpIo->Protocol.Udp6;

  //
  // Set the live time of the packet.
  //
  Instance->PacketToLive = Instance->IsMaster ? Instance->Timeout : (Instance->Timeout * 2);

  Temp   = (UINT16 *) NetbufGetByte (Packet, 0, NULL);
  ASSERT (Temp != NULL);

  Value  = *Temp;
  OpCode = NTOHS (Value);

  if (OpCode == EFI_MTFTP6_OPCODE_RRQ || OpCode == EFI_MTFTP6_OPCODE_DIR || OpCode == EFI_MTFTP6_OPCODE_WRQ) {
    //
    // For the Rrq, Dir, Wrq requests of the operation, configure the Udp6Io as
    // (serverip, 69, localip, localport) to send.
    // Usually local address and local port are both default as zero.
    //
    Status = Udp6->Configure (Udp6, NULL);

    if (EFI_ERROR (Status)) {
      return Status;
    }

    Status = Mtftp6ConfigUdpIo (
               Instance->UdpIo,
               &Instance->ServerIp,
               Instance->ServerCmdPort,
               &Instance->Config->StationIp,
               Instance->Config->LocalPort
               );

    if (EFI_ERROR (Status)) {
      return Status;
    }

    //
    // Get the current local address and port by get Udp6 mode data.
    //
    Status = Udp6->GetModeData (Udp6, &Udp6CfgData, NULL, NULL, NULL);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    NET_GET_REF (Packet);

    Instance->IsTransmitted = FALSE;

    Status = UdpIoSendDatagram (
               Instance->UdpIo,
               Packet,
               NULL,
               NULL,
               Mtftp6OnPacketSent,
               &Instance->IsTransmitted
               );

    if (EFI_ERROR (Status)) {
      NET_PUT_REF (Packet);
      return Status;
    }

    //
    // Poll till the packet sent out from the ip6 queue.
    //
    gBS->RestoreTPL (Instance->OldTpl);

    while (!Instance->IsTransmitted) {
      Udp6->Poll (Udp6);
    }

    Instance->OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

    //
    // For the subsequent exchange of such requests, reconfigure the Udp6Io as
    // (serverip, 0, localip, localport) to receive.
    // Currently local address and local port are specified by Udp6 mode data.
    //
    Status = Udp6->Configure (Udp6, NULL);

    if (EFI_ERROR (Status)) {
      return Status;
    }

    Status = Mtftp6ConfigUdpIo (
               Instance->UdpIo,
               &Instance->ServerIp,
               Instance->ServerDataPort,
               &Udp6CfgData.StationAddress,
               Udp6CfgData.StationPort
               );
  } else {
    //
    // For the data exchange, configure the Udp6Io as (serverip, dataport,
    // localip, localport) to send/receive.
    // Currently local address and local port are specified by Udp6 mode data.
    //
    Status = Udp6->GetModeData (Udp6, &Udp6CfgData, NULL, NULL, NULL);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    if (Udp6CfgData.RemotePort != Instance->ServerDataPort) {

      Status = Udp6->Configure (Udp6, NULL);

      if (EFI_ERROR (Status)) {
        return Status;
      }

      Status = Mtftp6ConfigUdpIo (
                 Instance->UdpIo,
                 &Instance->ServerIp,
                 Instance->ServerDataPort,
                 &Udp6CfgData.StationAddress,
                 Udp6CfgData.StationPort
                 );

      if (EFI_ERROR (Status)) {
        return Status;
      }
    }

    NET_GET_REF (Packet);

    Instance->IsTransmitted = FALSE;

    Status = UdpIoSendDatagram (
               Instance->UdpIo,
               Packet,
               NULL,
               NULL,
               Mtftp6OnPacketSent,
               &Instance->IsTransmitted
               );

    if (EFI_ERROR (Status)) {
      NET_PUT_REF (Packet);
    }

    //
    // Poll till the packet sent out from the ip6 queue.
    //
    gBS->RestoreTPL (Instance->OldTpl);

    while (!Instance->IsTransmitted) {
      Udp6->Poll (Udp6);
    }

    Instance->OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
  }

  return Status;
}


/**
  Check packet for GetInfo callback routine.

  GetInfo is implemented with EfiMtftp6ReadFile. It's used to inspect
  the first packet from server, then abort the session.

  @param[in]  This                   The pointer to the Mtftp6 protocol.
  @param[in]  Token                  The pointer to the Mtftp6 token.
  @param[in]  PacketLen              The length of the packet.
  @param[in]  Packet                 The pointer to the received packet.

  @retval EFI_ABORTED            Abort the Mtftp6 operation.

**/
EFI_STATUS
EFIAPI
Mtftp6CheckPacket (
  IN EFI_MTFTP6_PROTOCOL    *This,
  IN EFI_MTFTP6_TOKEN       *Token,
  IN UINT16                 PacketLen,
  IN EFI_MTFTP6_PACKET      *Packet
  )
{
  MTFTP6_GETINFO_CONTEXT    *Context;
  UINT16                    OpCode;

  Context = (MTFTP6_GETINFO_CONTEXT *) Token->Context;
  OpCode  = NTOHS (Packet->OpCode);

  //
  // Set the GetInfo's return status according to the OpCode.
  //
  switch (OpCode) {
  case EFI_MTFTP6_OPCODE_ERROR:
    Context->Status = EFI_TFTP_ERROR;
    break;

  case EFI_MTFTP6_OPCODE_OACK:
    Context->Status = EFI_SUCCESS;
    break;

  default:
    Context->Status = EFI_PROTOCOL_ERROR;
  }

  //
  // Allocate buffer then copy the packet over. Use gBS->AllocatePool
  // in case NetAllocatePool will implements something tricky.
  //
  *(Context->Packet) = AllocateZeroPool (PacketLen);

  if (*(Context->Packet) == NULL) {
    Context->Status = EFI_OUT_OF_RESOURCES;
    return EFI_ABORTED;
  }

  *(Context->PacketLen) = PacketLen;
  CopyMem (*(Context->Packet), Packet, PacketLen);

  return EFI_ABORTED;
}


/**
  Clean up the current Mtftp6 operation.

  @param[in]  Instance               The pointer to the Mtftp6 instance.
  @param[in]  Result                 The result to be returned to the user.

**/
VOID
Mtftp6OperationClean (
  IN MTFTP6_INSTANCE        *Instance,
  IN EFI_STATUS             Result
  )
{
  LIST_ENTRY                *Entry;
  LIST_ENTRY                *Next;
  MTFTP6_BLOCK_RANGE        *Block;

  //
  // Clean up the current token and event.
  //
  if (Instance->Token != NULL) {
    Instance->Token->Status = Result;
    if (Instance->Token->Event != NULL) {
      gBS->SignalEvent (Instance->Token->Event);
    }
    Instance->Token = NULL;
  }

  //
  // Clean up the corresponding Udp6Io.
  //
  if (Instance->UdpIo != NULL) {
    UdpIoCleanIo (Instance->UdpIo);
  }

  if (Instance->McastUdpIo != NULL) {
    gBS->CloseProtocol (
           Instance->McastUdpIo->UdpHandle,
           &gEfiUdp6ProtocolGuid,
           Instance->McastUdpIo->Image,
           Instance->Handle
           );
    UdpIoFreeIo (Instance->McastUdpIo);
    Instance->McastUdpIo = NULL;
  }

  //
  // Clean up the stored last packet.
  //
  if (Instance->LastPacket != NULL) {
    NetbufFree (Instance->LastPacket);
    Instance->LastPacket = NULL;
  }

  NET_LIST_FOR_EACH_SAFE (Entry, Next, &Instance->BlkList) {
    Block = NET_LIST_USER_STRUCT (Entry, MTFTP6_BLOCK_RANGE, Link);
    RemoveEntryList (Entry);
    FreePool (Block);
  }

  //
  // Reinitialize the corresponding fields of the Mtftp6 operation.
  //
  ZeroMem (&Instance->ExtInfo, sizeof (MTFTP6_EXT_OPTION_INFO));
  ZeroMem (&Instance->ServerIp, sizeof (EFI_IPv6_ADDRESS));
  ZeroMem (&Instance->McastIp, sizeof (EFI_IPv6_ADDRESS));

  Instance->ServerCmdPort  = 0;
  Instance->ServerDataPort = 0;
  Instance->McastPort      = 0;
  Instance->BlkSize        = 0;
  Instance->LastBlk        = 0;
  Instance->PacketToLive   = 0;
  Instance->MaxRetry       = 0;
  Instance->CurRetry       = 0;
  Instance->Timeout        = 0;
  Instance->IsMaster       = TRUE;
}


/**
  Start the Mtftp6 instance to perform the operation, such as read file,
  write file, and read directory.

  @param[in]  This                   The MTFTP session.
  @param[in]  Token                  The token than encapsues the user's request.
  @param[in]  OpCode                 The operation to perform.

  @retval EFI_INVALID_PARAMETER  Some of the parameters are invalid.
  @retval EFI_NOT_STARTED        The MTFTP session hasn't been configured.
  @retval EFI_ALREADY_STARTED    There is pending operation for the session.
  @retval EFI_SUCCESS            The operation is successfully started.

**/
EFI_STATUS
Mtftp6OperationStart (
  IN EFI_MTFTP6_PROTOCOL    *This,
  IN EFI_MTFTP6_TOKEN       *Token,
  IN UINT16                 OpCode
  )
{
  MTFTP6_INSTANCE           *Instance;
  EFI_STATUS                Status;

  if (This == NULL ||
      Token == NULL ||
      Token->Filename == NULL ||
      (Token->OptionCount != 0 && Token->OptionList == NULL) ||
      (Token->OverrideData != NULL && !NetIp6IsValidUnicast (&Token->OverrideData->ServerIp))
      ) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // At least define one method to collect the data for download.
  //
  if ((OpCode == EFI_MTFTP6_OPCODE_RRQ || OpCode == EFI_MTFTP6_OPCODE_DIR) &&
      Token->Buffer == NULL &&
      Token->CheckPacket == NULL
      ) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // At least define one method to provide the data for upload.
  //
  if (OpCode == EFI_MTFTP6_OPCODE_WRQ && Token->Buffer == NULL && Token->PacketNeeded == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = MTFTP6_INSTANCE_FROM_THIS (This);

  if (Instance->Config == NULL) {
    return EFI_NOT_STARTED;
  }

  if (Instance->Token != NULL) {
    return EFI_ACCESS_DENIED;
  }

  Status           = EFI_SUCCESS;
  Instance->OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  //
  // Parse the extension options in the request packet.
  //
  if (Token->OptionCount != 0) {

    Status = Mtftp6ParseExtensionOption (
               Token->OptionList,
               Token->OptionCount,
               TRUE,
               &Instance->ExtInfo
               );

    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }
  }

  //
  // Initialize runtime data from config data or override data.
  //
  Instance->Token           = Token;
  Instance->ServerCmdPort   = Instance->Config->InitialServerPort;
  Instance->ServerDataPort  = 0;
  Instance->MaxRetry        = Instance->Config->TryCount;
  Instance->Timeout         = Instance->Config->TimeoutValue;
  Instance->IsMaster        = TRUE;

  CopyMem (
    &Instance->ServerIp,
    &Instance->Config->ServerIp,
    sizeof (EFI_IPv6_ADDRESS)
    );

  if (Token->OverrideData != NULL) {
    Instance->ServerCmdPort = Token->OverrideData->ServerPort;
    Instance->MaxRetry      = Token->OverrideData->TryCount;
    Instance->Timeout       = Token->OverrideData->TimeoutValue;

    CopyMem (
      &Instance->ServerIp,
      &Token->OverrideData->ServerIp,
      sizeof (EFI_IPv6_ADDRESS)
      );
  }

  //
  // Set default value for undefined parameters.
  //
  if (Instance->ServerCmdPort == 0) {
    Instance->ServerCmdPort = MTFTP6_DEFAULT_SERVER_CMD_PORT;
  }
  if (Instance->BlkSize == 0) {
    Instance->BlkSize = MTFTP6_DEFAULT_BLK_SIZE;
  }
  if (Instance->MaxRetry == 0) {
    Instance->MaxRetry = MTFTP6_DEFAULT_MAX_RETRY;
  }
  if (Instance->Timeout == 0) {
    Instance->Timeout = MTFTP6_DEFAULT_TIMEOUT;
  }

  Token->Status = EFI_NOT_READY;

  //
  // Switch the routines by the operation code.
  //
  switch (OpCode) {
  case EFI_MTFTP6_OPCODE_RRQ:
    Status = Mtftp6RrqStart (Instance, OpCode);
    break;

  case EFI_MTFTP6_OPCODE_DIR:
    Status = Mtftp6RrqStart (Instance, OpCode);
    break;

  case EFI_MTFTP6_OPCODE_WRQ:
    Status = Mtftp6WrqStart (Instance, OpCode);
    break;

  default:
    Status = EFI_DEVICE_ERROR;
    goto ON_ERROR;
  }

  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Return immediately for asynchronous or poll the instance for synchronous.
  //
  gBS->RestoreTPL (Instance->OldTpl);

  if (Token->Event == NULL) {
    while (Token->Status == EFI_NOT_READY) {
      This->Poll (This);
    }
    return Token->Status;
  }

  return EFI_SUCCESS;

ON_ERROR:

  Mtftp6OperationClean (Instance, Status);
  gBS->RestoreTPL (Instance->OldTpl);

  return Status;
}


/**
  The timer ticking routine for the Mtftp6 instance.

  @param[in]  Event                  The pointer to the ticking event.
  @param[in]  Context                The pointer to the context.

**/
VOID
EFIAPI
Mtftp6OnTimerTick (
  IN EFI_EVENT              Event,
  IN VOID                   *Context
  )
{
  MTFTP6_SERVICE            *Service;
  MTFTP6_INSTANCE           *Instance;
  LIST_ENTRY                *Entry;
  LIST_ENTRY                *Next;
  EFI_MTFTP6_TOKEN          *Token;
  EFI_STATUS                Status;

  Service = (MTFTP6_SERVICE *) Context;

  //
  // Iterate through all the children of the Mtftp service instance. Time
  // out the packet. If maximum retries reached, clean the session up.
  //
  NET_LIST_FOR_EACH_SAFE (Entry, Next, &Service->Children) {

    Instance = NET_LIST_USER_STRUCT (Entry, MTFTP6_INSTANCE, Link);

    if (Instance->Token == NULL) {
      continue;
    }

    if (Instance->PacketToLive > 0) {
      Instance->PacketToLive--;
      continue;
    }

    Instance->CurRetry++;
    Token = Instance->Token;

    if (Token->TimeoutCallback != NULL) {
      //
      // Call the timeout callback routine if has.
      //
      Status = Token->TimeoutCallback (&Instance->Mtftp6, Token);

      if (EFI_ERROR (Status)) {
        Mtftp6SendError (
           Instance,
           EFI_MTFTP6_ERRORCODE_REQUEST_DENIED,
           (UINT8 *) "User aborted the transfer in time out"
           );
        Mtftp6OperationClean (Instance, EFI_ABORTED);
        continue;
      }
    }

    //
    // Retransmit the packet if haven't reach the maxmium retry count,
    // otherwise exit the transfer.
    //
    if (Instance->CurRetry < Instance->MaxRetry) {
      Mtftp6TransmitPacket (Instance, Instance->LastPacket);
    } else {
      Mtftp6OperationClean (Instance, EFI_TIMEOUT);
      continue;
    }
  }
}
