/** @file
  Functions implementation related with Mtftp for UefiPxeBc Driver.

  Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "PxeBcImpl.h"

CHAR8  *mMtftpOptions[PXE_MTFTP_OPTION_MAXIMUM_INDEX] = {
  "blksize",
  "timeout",
  "tsize",
  "multicast",
  "windowsize"
};

/**
  This is a callback function when packets are received or transmitted in Mtftp driver.

  A callback function that is provided by the caller to intercept
  the EFI_MTFTP6_OPCODE_DATA or EFI_MTFTP6_OPCODE_DATA8 packets processed in the
  EFI_MTFTP6_PROTOCOL.ReadFile() function, and alternatively to intercept
  EFI_MTFTP6_OPCODE_OACK or EFI_MTFTP6_OPCODE_ERROR packets during a call to
  EFI_MTFTP6_PROTOCOL.ReadFile(), WriteFile() or ReadDirectory().

  @param[in]  This           Pointer to EFI_MTFTP6_PROTOCOL.
  @param[in]  Token          Pointer to EFI_MTFTP6_TOKEN.
  @param[in]  PacketLen      Length of EFI_MTFTP6_PACKET.
  @param[in]  Packet         Pointer to EFI_MTFTP6_PACKET to be checked.

  @retval EFI_SUCCESS    The current operation succeeded.
  @retval EFI_ABORTED    Abort the current transfer process.

**/
EFI_STATUS
EFIAPI
PxeBcMtftp6CheckPacket (
  IN EFI_MTFTP6_PROTOCOL  *This,
  IN EFI_MTFTP6_TOKEN     *Token,
  IN UINT16               PacketLen,
  IN EFI_MTFTP6_PACKET    *Packet
  )
{
  PXEBC_PRIVATE_DATA                   *Private;
  EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL  *Callback;
  EFI_STATUS                           Status;

  Private  = (PXEBC_PRIVATE_DATA *)Token->Context;
  Callback = Private->PxeBcCallback;
  Status   = EFI_SUCCESS;

  if (Packet->OpCode == EFI_MTFTP6_OPCODE_ERROR) {
    //
    // Store the tftp error message into mode data and set the received flag.
    //
    Private->Mode.TftpErrorReceived   = TRUE;
    Private->Mode.TftpError.ErrorCode = (UINT8)Packet->Error.ErrorCode;
    AsciiStrnCpyS (
      Private->Mode.TftpError.ErrorString,
      PXE_MTFTP_ERROR_STRING_LENGTH,
      (CHAR8 *)Packet->Error.ErrorMessage,
      PXE_MTFTP_ERROR_STRING_LENGTH - 1
      );
    Private->Mode.TftpError.ErrorString[PXE_MTFTP_ERROR_STRING_LENGTH - 1] = '\0';
  }

  if (Callback != NULL) {
    //
    // Callback to user if has when received any tftp packet.
    //
    Status = Callback->Callback (
                         Callback,
                         Private->Function,
                         TRUE,
                         PacketLen,
                         (EFI_PXE_BASE_CODE_PACKET *)Packet
                         );
    if (Status != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {
      //
      // User wants to abort current process if not EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE.
      //
      Status = EFI_ABORTED;
    } else {
      //
      // User wants to continue current process if EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE.
      //
      Status = EFI_SUCCESS;
    }
  }

  return Status;
}

/**
  This function is to get the size of a file using Tftp.

  @param[in]      Private        Pointer to PxeBc private data.
  @param[in]      Config         Pointer to EFI_MTFTP6_CONFIG_DATA.
  @param[in]      Filename       Pointer to boot file name.
  @param[in]      BlockSize      Pointer to required block size.
  @param[in]      WindowSize     Pointer to required window size.
  @param[in, out] BufferSize     Pointer to buffer size.

  @retval EFI_SUCCESS        Successfully obtained the size of file.
  @retval EFI_NOT_FOUND      Parse the tftp options failed.
  @retval EFI_DEVICE_ERROR   The network device encountered an error during this operation.
  @retval Others             Has not obtained the size of the file.

**/
EFI_STATUS
PxeBcMtftp6GetFileSize (
  IN     PXEBC_PRIVATE_DATA      *Private,
  IN     EFI_MTFTP6_CONFIG_DATA  *Config,
  IN     UINT8                   *Filename,
  IN     UINTN                   *BlockSize,
  IN     UINTN                   *WindowSize,
  IN OUT UINT64                  *BufferSize
  )
{
  EFI_MTFTP6_PROTOCOL  *Mtftp6;
  EFI_MTFTP6_OPTION    ReqOpt[3];
  EFI_MTFTP6_PACKET    *Packet;
  EFI_MTFTP6_OPTION    *Option;
  UINT32               PktLen;
  UINT8                OptBuf[PXE_MTFTP_OPTBUF_MAXNUM_INDEX];
  UINTN                OptBufSize;
  UINT32               OptCnt;
  EFI_STATUS           Status;

  *BufferSize               = 0;
  Status                    = EFI_DEVICE_ERROR;
  Mtftp6                    = Private->Mtftp6;
  Packet                    = NULL;
  Option                    = NULL;
  PktLen                    = 0;
  OptBufSize                = PXE_MTFTP_OPTBUF_MAXNUM_INDEX;
  OptCnt                    = 1;
  Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;

  Status = Mtftp6->Configure (Mtftp6, Config);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Build the required options for get info.
  //
  ReqOpt[0].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_TSIZE_INDEX];
  PxeBcUintnToAscDec (0, OptBuf, OptBufSize);
  ReqOpt[0].ValueStr = OptBuf;

  if (BlockSize != NULL) {
    ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
    ReqOpt[OptCnt].ValueStr  = (UINT8 *)(ReqOpt[OptCnt-1].ValueStr + AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);
    OptBufSize              -= (AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);
    PxeBcUintnToAscDec (*BlockSize, ReqOpt[OptCnt].ValueStr, OptBufSize);
    OptCnt++;
  }

  if (WindowSize != NULL) {
    ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_WINDOWSIZE_INDEX];
    ReqOpt[OptCnt].ValueStr  = (UINT8 *)(ReqOpt[OptCnt-1].ValueStr + AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);
    OptBufSize              -= (AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);
    PxeBcUintnToAscDec (*WindowSize, ReqOpt[OptCnt].ValueStr, OptBufSize);
    OptCnt++;
  }

  Status = Mtftp6->GetInfo (
                     Mtftp6,
                     NULL,
                     Filename,
                     NULL,
                     (UINT8)OptCnt,
                     ReqOpt,
                     &PktLen,
                     &Packet
                     );
  if (EFI_ERROR (Status)) {
    if (Status == EFI_TFTP_ERROR) {
      //
      // Store the tftp error message into mode data and set the received flag.
      //
      Private->Mode.TftpErrorReceived   = TRUE;
      Private->Mode.TftpError.ErrorCode = (UINT8)Packet->Error.ErrorCode;
      AsciiStrnCpyS (
        Private->Mode.TftpError.ErrorString,
        PXE_MTFTP_ERROR_STRING_LENGTH,
        (CHAR8 *)Packet->Error.ErrorMessage,
        PXE_MTFTP_ERROR_STRING_LENGTH - 1
        );
      Private->Mode.TftpError.ErrorString[PXE_MTFTP_ERROR_STRING_LENGTH - 1] = '\0';
    }

    goto ON_ERROR;
  }

  //
  // Parse the options in the reply packet.
  //
  OptCnt = 0;
  Status = Mtftp6->ParseOptions (
                     Mtftp6,
                     PktLen,
                     Packet,
                     (UINT32 *)&OptCnt,
                     &Option
                     );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Parse out the value of "tsize" option.
  //
  Status = EFI_NOT_FOUND;
  while (OptCnt != 0) {
    if (AsciiStrnCmp ((CHAR8 *)Option[OptCnt - 1].OptionStr, "tsize", 5) == 0) {
      *BufferSize = AsciiStrDecimalToUint64 ((CHAR8 *)(Option[OptCnt - 1].ValueStr));
      Status      = EFI_SUCCESS;
    }

    OptCnt--;
  }

  FreePool (Option);

ON_ERROR:
  if (Packet != NULL) {
    FreePool (Packet);
  }

  Mtftp6->Configure (Mtftp6, NULL);

  return Status;
}

/**
  This function is to get data of a file using Tftp.

  @param[in]      Private        Pointer to PxeBc private data.
  @param[in]      Config         Pointer to EFI_MTFTP6_CONFIG_DATA.
  @param[in]      Filename       Pointer to boot file name.
  @param[in]      BlockSize      Pointer to required block size.
  @param[in]      WindowSize     Pointer to required window size.
  @param[in]      BufferPtr      Pointer to buffer.
  @param[in, out] BufferSize     Pointer to buffer size.
  @param[in]      DontUseBuffer  Indicates whether with a receive buffer.

  @retval EFI_SUCCESS        Successfully read the data from the special file.
  @retval EFI_DEVICE_ERROR   The network device encountered an error during this operation.
  @retval Others             Read data from file failed.

**/
EFI_STATUS
PxeBcMtftp6ReadFile (
  IN    PXEBC_PRIVATE_DATA       *Private,
  IN     EFI_MTFTP6_CONFIG_DATA  *Config,
  IN     UINT8                   *Filename,
  IN     UINTN                   *BlockSize,
  IN     UINTN                   *WindowSize,
  IN     UINT8                   *BufferPtr,
  IN OUT UINT64                  *BufferSize,
  IN     BOOLEAN                 DontUseBuffer
  )
{
  EFI_MTFTP6_PROTOCOL  *Mtftp6;
  EFI_MTFTP6_TOKEN     Token;
  EFI_MTFTP6_OPTION    ReqOpt[2];
  UINT32               OptCnt;
  UINT8                BlksizeBuf[10];
  UINT8                WindowsizeBuf[10];
  EFI_STATUS           Status;

  Status                    = EFI_DEVICE_ERROR;
  Mtftp6                    = Private->Mtftp6;
  OptCnt                    = 0;
  Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;

  Status = Mtftp6->Configure (Mtftp6, Config);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (BlockSize != NULL) {
    ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
    ReqOpt[OptCnt].ValueStr  = BlksizeBuf;
    PxeBcUintnToAscDec (*BlockSize, ReqOpt[OptCnt].ValueStr, sizeof (BlksizeBuf));
    OptCnt++;
  }

  if (WindowSize != NULL) {
    ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_WINDOWSIZE_INDEX];
    ReqOpt[OptCnt].ValueStr  = WindowsizeBuf;
    PxeBcUintnToAscDec (*WindowSize, ReqOpt[OptCnt].ValueStr, sizeof (WindowsizeBuf));
    OptCnt++;
  }

  Token.Event        = NULL;
  Token.OverrideData = NULL;
  Token.Filename     = Filename;
  Token.ModeStr      = NULL;
  Token.OptionCount  = OptCnt;
  Token.OptionList   = ReqOpt;
  Token.Context      = Private;

  if (DontUseBuffer) {
    Token.BufferSize = 0;
    Token.Buffer     = NULL;
  } else {
    Token.BufferSize = *BufferSize;
    Token.Buffer     = BufferPtr;
  }

  Token.CheckPacket     = PxeBcMtftp6CheckPacket;
  Token.TimeoutCallback = NULL;
  Token.PacketNeeded    = NULL;

  Status = Mtftp6->ReadFile (Mtftp6, &Token);
  //
  // Get the real size of received buffer.
  //
  *BufferSize = Token.BufferSize;

  Mtftp6->Configure (Mtftp6, NULL);

  return Status;
}

/**
  This function is used to write the data of a file using Tftp.

  @param[in]       Private        Pointer to PxeBc private data.
  @param[in]       Config         Pointer to EFI_MTFTP6_CONFIG_DATA.
  @param[in]       Filename       Pointer to boot file name.
  @param[in]       Overwrite      Indicate whether with overwrite attribute.
  @param[in]       BlockSize      Pointer to required block size.
  @param[in]       BufferPtr      Pointer to buffer.
  @param[in, out]  BufferSize     Pointer to buffer size.

  @retval EFI_SUCCESS        Successfully wrote the data into a special file.
  @retval EFI_DEVICE_ERROR   The network device encountered an error during this operation.
  @retval other              Write data into file failed.

**/
EFI_STATUS
PxeBcMtftp6WriteFile (
  IN     PXEBC_PRIVATE_DATA      *Private,
  IN     EFI_MTFTP6_CONFIG_DATA  *Config,
  IN     UINT8                   *Filename,
  IN     BOOLEAN                 Overwrite,
  IN     UINTN                   *BlockSize,
  IN     UINT8                   *BufferPtr,
  IN OUT UINT64                  *BufferSize
  )
{
  EFI_MTFTP6_PROTOCOL  *Mtftp6;
  EFI_MTFTP6_TOKEN     Token;
  EFI_MTFTP6_OPTION    ReqOpt[1];
  UINT32               OptCnt;
  UINT8                OptBuf[128];
  EFI_STATUS           Status;

  Status                    = EFI_DEVICE_ERROR;
  Mtftp6                    = Private->Mtftp6;
  OptCnt                    = 0;
  Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;

  Status = Mtftp6->Configure (Mtftp6, Config);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (BlockSize != NULL) {
    ReqOpt[0].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
    ReqOpt[0].ValueStr  = OptBuf;
    PxeBcUintnToAscDec (*BlockSize, ReqOpt[0].ValueStr, PXE_MTFTP_OPTBUF_MAXNUM_INDEX);
    OptCnt++;
  }

  Token.Event           = NULL;
  Token.OverrideData    = NULL;
  Token.Filename        = Filename;
  Token.ModeStr         = NULL;
  Token.OptionCount     = OptCnt;
  Token.OptionList      = ReqOpt;
  Token.BufferSize      = *BufferSize;
  Token.Buffer          = BufferPtr;
  Token.CheckPacket     = PxeBcMtftp6CheckPacket;
  Token.TimeoutCallback = NULL;
  Token.PacketNeeded    = NULL;

  Status = Mtftp6->WriteFile (Mtftp6, &Token);
  //
  // Get the real size of transmitted buffer.
  //
  *BufferSize = Token.BufferSize;

  Mtftp6->Configure (Mtftp6, NULL);

  return Status;
}

/**
  This function is to read the data (file) from a directory using Tftp.

  @param[in]       Private        Pointer to PxeBc private data.
  @param[in]       Config         Pointer to EFI_MTFTP6_CONFIG_DATA.
  @param[in]       Filename       Pointer to boot file name.
  @param[in]       BlockSize      Pointer to required block size.
  @param[in]       WindowSize     Pointer to required window size.
  @param[in]       BufferPtr      Pointer to buffer.
  @param[in, out]  BufferSize     Pointer to buffer size.
  @param[in]       DontUseBuffer  Indicates whether to use a receive buffer.

  @retval EFI_SUCCESS        Successfully obtained the data from the file included in directory.
  @retval EFI_DEVICE_ERROR   The network device encountered an error during this operation.
  @retval Others             Operation failed.

**/
EFI_STATUS
PxeBcMtftp6ReadDirectory (
  IN     PXEBC_PRIVATE_DATA      *Private,
  IN     EFI_MTFTP6_CONFIG_DATA  *Config,
  IN     UINT8                   *Filename,
  IN     UINTN                   *BlockSize,
  IN     UINTN                   *WindowSize,
  IN     UINT8                   *BufferPtr,
  IN OUT UINT64                  *BufferSize,
  IN     BOOLEAN                 DontUseBuffer
  )
{
  EFI_MTFTP6_PROTOCOL  *Mtftp6;
  EFI_MTFTP6_TOKEN     Token;
  EFI_MTFTP6_OPTION    ReqOpt[2];
  UINT32               OptCnt;
  UINT8                BlksizeBuf[10];
  UINT8                WindowsizeBuf[10];
  EFI_STATUS           Status;

  Status                    = EFI_DEVICE_ERROR;
  Mtftp6                    = Private->Mtftp6;
  OptCnt                    = 0;
  Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;

  Status = Mtftp6->Configure (Mtftp6, Config);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (BlockSize != NULL) {
    ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
    ReqOpt[OptCnt].ValueStr  = BlksizeBuf;
    PxeBcUintnToAscDec (*BlockSize, ReqOpt[OptCnt].ValueStr, sizeof (BlksizeBuf));
    OptCnt++;
  }

  if (WindowSize != NULL) {
    ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_WINDOWSIZE_INDEX];
    ReqOpt[OptCnt].ValueStr  = WindowsizeBuf;
    PxeBcUintnToAscDec (*WindowSize, ReqOpt[OptCnt].ValueStr, sizeof (WindowsizeBuf));
    OptCnt++;
  }

  Token.Event        = NULL;
  Token.OverrideData = NULL;
  Token.Filename     = Filename;
  Token.ModeStr      = NULL;
  Token.OptionCount  = OptCnt;
  Token.OptionList   = ReqOpt;
  Token.Context      = Private;

  if (DontUseBuffer) {
    Token.BufferSize = 0;
    Token.Buffer     = NULL;
  } else {
    Token.BufferSize = *BufferSize;
    Token.Buffer     = BufferPtr;
  }

  Token.CheckPacket     = PxeBcMtftp6CheckPacket;
  Token.TimeoutCallback = NULL;
  Token.PacketNeeded    = NULL;

  Status = Mtftp6->ReadDirectory (Mtftp6, &Token);
  //
  // Get the real size of received buffer.
  //
  *BufferSize = Token.BufferSize;

  Mtftp6->Configure (Mtftp6, NULL);

  return Status;
}

/**
  This is a callback function when packets are received or transmitted in Mtftp driver.

  A callback function that is provided by the caller to intercept
  the EFI_MTFTP6_OPCODE_DATA or EFI_MTFTP4_OPCODE_DATA8 packets processed in the
  EFI_MTFTP4_PROTOCOL.ReadFile() function, and alternatively to intercept
  EFI_MTFTP4_OPCODE_OACK or EFI_MTFTP4_OPCODE_ERROR packets during a call to
  EFI_MTFTP4_PROTOCOL.ReadFile(), WriteFile() or ReadDirectory().

  @param[in]  This           Pointer to EFI_MTFTP4_PROTOCOL.
  @param[in]  Token          Pointer to EFI_MTFTP4_TOKEN.
  @param[in]  PacketLen      Length of EFI_MTFTP4_PACKET.
  @param[in]  Packet         Pointer to EFI_MTFTP4_PACKET to be checked.

  @retval EFI_SUCCESS    The current operation succeeded.
  @retval EFI_ABORTED    Abort the current transfer process.

**/
EFI_STATUS
EFIAPI
PxeBcMtftp4CheckPacket (
  IN EFI_MTFTP4_PROTOCOL  *This,
  IN EFI_MTFTP4_TOKEN     *Token,
  IN UINT16               PacketLen,
  IN EFI_MTFTP4_PACKET    *Packet
  )
{
  PXEBC_PRIVATE_DATA                   *Private;
  EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL  *Callback;
  EFI_STATUS                           Status;

  Private  = (PXEBC_PRIVATE_DATA *)Token->Context;
  Callback = Private->PxeBcCallback;
  Status   = EFI_SUCCESS;

  if (Packet->OpCode == EFI_MTFTP4_OPCODE_ERROR) {
    //
    // Store the tftp error message into mode data and set the received flag.
    //
    Private->Mode.TftpErrorReceived   = TRUE;
    Private->Mode.TftpError.ErrorCode = (UINT8)Packet->Error.ErrorCode;
    AsciiStrnCpyS (
      Private->Mode.TftpError.ErrorString,
      PXE_MTFTP_ERROR_STRING_LENGTH,
      (CHAR8 *)Packet->Error.ErrorMessage,
      PXE_MTFTP_ERROR_STRING_LENGTH - 1
      );
    Private->Mode.TftpError.ErrorString[PXE_MTFTP_ERROR_STRING_LENGTH - 1] = '\0';
  }

  if (Callback != NULL) {
    //
    // Callback to user if has when received any tftp packet.
    //
    Status = Callback->Callback (
                         Callback,
                         Private->Function,
                         TRUE,
                         PacketLen,
                         (EFI_PXE_BASE_CODE_PACKET *)Packet
                         );
    if (Status != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {
      //
      // User wants to abort current process if not EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE.
      //
      Status = EFI_ABORTED;
    } else {
      //
      // User wants to continue current process if EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE.
      //
      Status = EFI_SUCCESS;
    }
  }

  return Status;
}

/**
  This function is to get size of a file using Tftp.

  @param[in]      Private        Pointer to PxeBc private data.
  @param[in]      Config         Pointer to EFI_MTFTP4_CONFIG_DATA.
  @param[in]      Filename       Pointer to boot file name.
  @param[in]      BlockSize      Pointer to required block size.
  @param[in]      WindowSize     Pointer to required window size.
  @param[in, out] BufferSize     Pointer to buffer size.

  @retval EFI_SUCCESS        Successfully obtained the size of file.
  @retval EFI_NOT_FOUND      Parse the tftp options failed.
  @retval EFI_DEVICE_ERROR   The network device encountered an error during this operation.
  @retval Others             Did not obtain the size of the file.

**/
EFI_STATUS
PxeBcMtftp4GetFileSize (
  IN     PXEBC_PRIVATE_DATA      *Private,
  IN     EFI_MTFTP4_CONFIG_DATA  *Config,
  IN     UINT8                   *Filename,
  IN     UINTN                   *BlockSize,
  IN     UINTN                   *WindowSize,
  IN OUT UINT64                  *BufferSize
  )
{
  EFI_MTFTP4_PROTOCOL  *Mtftp4;
  EFI_MTFTP4_OPTION    ReqOpt[3];
  EFI_MTFTP4_PACKET    *Packet;
  EFI_MTFTP4_OPTION    *Option;
  UINT32               PktLen;
  UINT8                OptBuf[PXE_MTFTP_OPTBUF_MAXNUM_INDEX];
  UINTN                OptBufSize;
  UINT32               OptCnt;
  EFI_STATUS           Status;

  *BufferSize               = 0;
  Status                    = EFI_DEVICE_ERROR;
  Mtftp4                    = Private->Mtftp4;
  Packet                    = NULL;
  Option                    = NULL;
  PktLen                    = 0;
  OptBufSize                = PXE_MTFTP_OPTBUF_MAXNUM_INDEX;
  OptCnt                    = 1;
  Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;

  Status = Mtftp4->Configure (Mtftp4, Config);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Build the required options for get info.
  //
  ReqOpt[0].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_TSIZE_INDEX];
  PxeBcUintnToAscDec (0, OptBuf, OptBufSize);
  ReqOpt[0].ValueStr = OptBuf;

  if (BlockSize != NULL) {
    ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
    ReqOpt[OptCnt].ValueStr  = (UINT8 *)(ReqOpt[OptCnt-1].ValueStr + AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);
    OptBufSize              -= (AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);
    PxeBcUintnToAscDec (*BlockSize, ReqOpt[OptCnt].ValueStr, OptBufSize);
    OptCnt++;
  }

  if (WindowSize != NULL) {
    ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_WINDOWSIZE_INDEX];
    ReqOpt[OptCnt].ValueStr  = (UINT8 *)(ReqOpt[OptCnt-1].ValueStr + AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);
    OptBufSize              -= (AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);
    PxeBcUintnToAscDec (*WindowSize, ReqOpt[OptCnt].ValueStr, OptBufSize);
    OptCnt++;
  }

  Status = Mtftp4->GetInfo (
                     Mtftp4,
                     NULL,
                     Filename,
                     NULL,
                     (UINT8)OptCnt,
                     ReqOpt,
                     &PktLen,
                     &Packet
                     );
  if (EFI_ERROR (Status)) {
    if (Status == EFI_TFTP_ERROR) {
      //
      // Store the tftp error message into mode data and set the received flag.
      //
      Private->Mode.TftpErrorReceived   = TRUE;
      Private->Mode.TftpError.ErrorCode = (UINT8)Packet->Error.ErrorCode;
      AsciiStrnCpyS (
        Private->Mode.TftpError.ErrorString,
        PXE_MTFTP_ERROR_STRING_LENGTH,
        (CHAR8 *)Packet->Error.ErrorMessage,
        PXE_MTFTP_ERROR_STRING_LENGTH - 1
        );
      Private->Mode.TftpError.ErrorString[PXE_MTFTP_ERROR_STRING_LENGTH - 1] = '\0';
    }

    goto ON_ERROR;
  }

  //
  // Parse the options in the reply packet.
  //
  OptCnt = 0;
  Status = Mtftp4->ParseOptions (
                     Mtftp4,
                     PktLen,
                     Packet,
                     (UINT32 *)&OptCnt,
                     &Option
                     );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Parse out the value of "tsize" option.
  //
  Status = EFI_NOT_FOUND;
  while (OptCnt != 0) {
    if (AsciiStrnCmp ((CHAR8 *)Option[OptCnt - 1].OptionStr, "tsize", 5) == 0) {
      *BufferSize = AsciiStrDecimalToUint64 ((CHAR8 *)(Option[OptCnt - 1].ValueStr));
      Status      = EFI_SUCCESS;
    }

    OptCnt--;
  }

  FreePool (Option);

ON_ERROR:
  if (Packet != NULL) {
    FreePool (Packet);
  }

  Mtftp4->Configure (Mtftp4, NULL);

  return Status;
}

/**
  This function is to read the data of a file using Tftp.

  @param[in]      Private        Pointer to PxeBc private data.
  @param[in]      Config         Pointer to EFI_MTFTP4_CONFIG_DATA.
  @param[in]      Filename       Pointer to boot file name.
  @param[in]      BlockSize      Pointer to required block size.
  @param[in]      WindowSize     Pointer to required window size.
  @param[in]      BufferPtr      Pointer to buffer.
  @param[in, out] BufferSize     Pointer to buffer size.
  @param[in]      DontUseBuffer  Indicates whether to use a receive buffer.

  @retval EFI_SUCCESS        Successfully read the data from the special file.
  @retval EFI_DEVICE_ERROR   The network device encountered an error during this operation.
  @retval Others             Read data from file failed.

**/
EFI_STATUS
PxeBcMtftp4ReadFile (
  IN     PXEBC_PRIVATE_DATA      *Private,
  IN     EFI_MTFTP4_CONFIG_DATA  *Config,
  IN     UINT8                   *Filename,
  IN     UINTN                   *BlockSize,
  IN     UINTN                   *WindowSize,
  IN     UINT8                   *BufferPtr,
  IN OUT UINT64                  *BufferSize,
  IN     BOOLEAN                 DontUseBuffer
  )
{
  EFI_MTFTP4_PROTOCOL  *Mtftp4;
  EFI_MTFTP4_TOKEN     Token;
  EFI_MTFTP4_OPTION    ReqOpt[2];
  UINT32               OptCnt;
  UINT8                BlksizeBuf[10];
  UINT8                WindowsizeBuf[10];
  EFI_STATUS           Status;

  Status                    = EFI_DEVICE_ERROR;
  Mtftp4                    = Private->Mtftp4;
  OptCnt                    = 0;
  Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;

  Status = Mtftp4->Configure (Mtftp4, Config);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (BlockSize != NULL) {
    ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
    ReqOpt[OptCnt].ValueStr  = BlksizeBuf;
    PxeBcUintnToAscDec (*BlockSize, ReqOpt[OptCnt].ValueStr, sizeof (BlksizeBuf));
    OptCnt++;
  }

  if (WindowSize != NULL) {
    ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_WINDOWSIZE_INDEX];
    ReqOpt[OptCnt].ValueStr  = WindowsizeBuf;
    PxeBcUintnToAscDec (*WindowSize, ReqOpt[OptCnt].ValueStr, sizeof (WindowsizeBuf));
    OptCnt++;
  }

  Token.Event        = NULL;
  Token.OverrideData = NULL;
  Token.Filename     = Filename;
  Token.ModeStr      = NULL;
  Token.OptionCount  = OptCnt;
  Token.OptionList   = ReqOpt;
  Token.Context      = Private;

  if (DontUseBuffer) {
    Token.BufferSize = 0;
    Token.Buffer     = NULL;
  } else {
    Token.BufferSize = *BufferSize;
    Token.Buffer     = BufferPtr;
  }

  Token.CheckPacket     = PxeBcMtftp4CheckPacket;
  Token.TimeoutCallback = NULL;
  Token.PacketNeeded    = NULL;

  Status = Mtftp4->ReadFile (Mtftp4, &Token);
  //
  // Get the real size of received buffer.
  //
  *BufferSize = Token.BufferSize;

  Mtftp4->Configure (Mtftp4, NULL);

  return Status;
}

/**
  This function is to write the data of a file using Tftp.

  @param[in]       Private        Pointer to PxeBc private data.
  @param[in]       Config         Pointer to EFI_MTFTP4_CONFIG_DATA.
  @param[in]       Filename       Pointer to boot file name.
  @param[in]       Overwrite      Indicates whether to use the overwrite attribute.
  @param[in]       BlockSize      Pointer to required block size.
  @param[in]       BufferPtr      Pointer to buffer.
  @param[in, out]  BufferSize     Pointer to buffer size.

  @retval EFI_SUCCESS        Successfully write the data  into the special file.
  @retval EFI_DEVICE_ERROR   The network device encountered an error during this operation.
  @retval other              Write data into file failed.

**/
EFI_STATUS
PxeBcMtftp4WriteFile (
  IN     PXEBC_PRIVATE_DATA      *Private,
  IN     EFI_MTFTP4_CONFIG_DATA  *Config,
  IN     UINT8                   *Filename,
  IN     BOOLEAN                 Overwrite,
  IN     UINTN                   *BlockSize,
  IN     UINT8                   *BufferPtr,
  IN OUT UINT64                  *BufferSize
  )
{
  EFI_MTFTP4_PROTOCOL  *Mtftp4;
  EFI_MTFTP4_TOKEN     Token;
  EFI_MTFTP4_OPTION    ReqOpt[1];
  UINT32               OptCnt;
  UINT8                OptBuf[128];
  EFI_STATUS           Status;

  Status                    = EFI_DEVICE_ERROR;
  Mtftp4                    = Private->Mtftp4;
  OptCnt                    = 0;
  Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;

  Status = Mtftp4->Configure (Mtftp4, Config);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (BlockSize != NULL) {
    ReqOpt[0].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
    ReqOpt[0].ValueStr  = OptBuf;
    PxeBcUintnToAscDec (*BlockSize, ReqOpt[0].ValueStr, PXE_MTFTP_OPTBUF_MAXNUM_INDEX);
    OptCnt++;
  }

  Token.Event           = NULL;
  Token.OverrideData    = NULL;
  Token.Filename        = Filename;
  Token.ModeStr         = NULL;
  Token.OptionCount     = OptCnt;
  Token.OptionList      = ReqOpt;
  Token.BufferSize      = *BufferSize;
  Token.Buffer          = BufferPtr;
  Token.CheckPacket     = PxeBcMtftp4CheckPacket;
  Token.TimeoutCallback = NULL;
  Token.PacketNeeded    = NULL;

  Status = Mtftp4->WriteFile (Mtftp4, &Token);
  //
  // Get the real size of transmitted buffer.
  //
  *BufferSize = Token.BufferSize;

  Mtftp4->Configure (Mtftp4, NULL);

  return Status;
}

/**
  This function is to get data (file) from a directory using Tftp.

  @param[in]       Private        Pointer to PxeBc private data.
  @param[in]       Config         Pointer to EFI_MTFTP4_CONFIG_DATA.
  @param[in]       Filename       Pointer to boot file name.
  @param[in]       BlockSize      Pointer to required block size.
  @param[in]       WindowSize     Pointer to required window size.
  @param[in]       BufferPtr      Pointer to buffer.
  @param[in, out]  BufferSize     Pointer to buffer size.
  @param[in]       DontUseBuffer  Indicates whether to use a receive buffer.

  @retval EFI_SUCCESS        Successfully obtained the data from the file included in the directory.
  @retval EFI_DEVICE_ERROR   The network device encountered an error during this operation.
  @retval Others             Operation failed.

**/
EFI_STATUS
PxeBcMtftp4ReadDirectory (
  IN     PXEBC_PRIVATE_DATA      *Private,
  IN     EFI_MTFTP4_CONFIG_DATA  *Config,
  IN     UINT8                   *Filename,
  IN     UINTN                   *BlockSize,
  IN     UINTN                   *WindowSize,
  IN     UINT8                   *BufferPtr,
  IN OUT UINT64                  *BufferSize,
  IN     BOOLEAN                 DontUseBuffer
  )
{
  EFI_MTFTP4_PROTOCOL  *Mtftp4;
  EFI_MTFTP4_TOKEN     Token;
  EFI_MTFTP4_OPTION    ReqOpt[2];
  UINT32               OptCnt;
  UINT8                BlksizeBuf[10];
  UINT8                WindowsizeBuf[10];
  EFI_STATUS           Status;

  Status                    = EFI_DEVICE_ERROR;
  Mtftp4                    = Private->Mtftp4;
  OptCnt                    = 0;
  Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;

  Status = Mtftp4->Configure (Mtftp4, Config);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (BlockSize != NULL) {
    ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
    ReqOpt[OptCnt].ValueStr  = BlksizeBuf;
    PxeBcUintnToAscDec (*BlockSize, ReqOpt[OptCnt].ValueStr, sizeof (BlksizeBuf));
    OptCnt++;
  }

  if (WindowSize != NULL) {
    ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_WINDOWSIZE_INDEX];
    ReqOpt[OptCnt].ValueStr  = WindowsizeBuf;
    PxeBcUintnToAscDec (*WindowSize, ReqOpt[OptCnt].ValueStr, sizeof (WindowsizeBuf));
    OptCnt++;
  }

  Token.Event        = NULL;
  Token.OverrideData = NULL;
  Token.Filename     = Filename;
  Token.ModeStr      = NULL;
  Token.OptionCount  = OptCnt;
  Token.OptionList   = ReqOpt;
  Token.Context      = Private;

  if (DontUseBuffer) {
    Token.BufferSize = 0;
    Token.Buffer     = NULL;
  } else {
    Token.BufferSize = *BufferSize;
    Token.Buffer     = BufferPtr;
  }

  Token.CheckPacket     = PxeBcMtftp4CheckPacket;
  Token.TimeoutCallback = NULL;
  Token.PacketNeeded    = NULL;

  Status = Mtftp4->ReadDirectory (Mtftp4, &Token);
  //
  // Get the real size of received buffer.
  //
  *BufferSize = Token.BufferSize;

  Mtftp4->Configure (Mtftp4, NULL);

  return Status;
}

/**
  This function is wrapper to get the file size using TFTP.

  @param[in]      Private        Pointer to PxeBc private data.
  @param[in]      Config         Pointer to configure data.
  @param[in]      Filename       Pointer to boot file name.
  @param[in]      BlockSize      Pointer to required block size.
  @param[in]      WindowSize     Pointer to required window size.
  @param[in, out] BufferSize     Pointer to buffer size.

  @retval EFI_SUCCESS        Successfully obtained the size of file.
  @retval EFI_NOT_FOUND      Parse the tftp options failed.
  @retval EFI_DEVICE_ERROR   The network device encountered an error during this operation.
  @retval Others             Did not obtain the size of the file.

**/
EFI_STATUS
PxeBcTftpGetFileSize (
  IN     PXEBC_PRIVATE_DATA  *Private,
  IN     VOID                *Config,
  IN     UINT8               *Filename,
  IN     UINTN               *BlockSize,
  IN     UINTN               *WindowSize,
  IN OUT UINT64              *BufferSize
  )
{
  if (Private->PxeBc.Mode->UsingIpv6) {
    return PxeBcMtftp6GetFileSize (
             Private,
             (EFI_MTFTP6_CONFIG_DATA *)Config,
             Filename,
             BlockSize,
             WindowSize,
             BufferSize
             );
  } else {
    return PxeBcMtftp4GetFileSize (
             Private,
             (EFI_MTFTP4_CONFIG_DATA *)Config,
             Filename,
             BlockSize,
             WindowSize,
             BufferSize
             );
  }
}

/**
  This function is a wrapper to get file using TFTP.

  @param[in]      Private        Pointer to PxeBc private data.
  @param[in]      Config         Pointer to config data.
  @param[in]      Filename       Pointer to boot file name.
  @param[in]      BlockSize      Pointer to required block size.
  @param[in]      WindowSize     Pointer to required window size.
  @param[in]      BufferPtr      Pointer to buffer.
  @param[in, out] BufferSize     Pointer to buffer size.
  @param[in]      DontUseBuffer  Indicates whether to use a receive buffer.

  @retval EFI_SUCCESS        Successfully read the data from the special file.
  @retval EFI_DEVICE_ERROR   The network device encountered an error during this operation.
  @retval Others             Read data from file failed.

**/
EFI_STATUS
PxeBcTftpReadFile (
  IN     PXEBC_PRIVATE_DATA  *Private,
  IN     VOID                *Config,
  IN     UINT8               *Filename,
  IN     UINTN               *BlockSize,
  IN     UINTN               *WindowSize,
  IN     UINT8               *BufferPtr,
  IN OUT UINT64              *BufferSize,
  IN     BOOLEAN             DontUseBuffer
  )
{
  if (Private->PxeBc.Mode->UsingIpv6) {
    return PxeBcMtftp6ReadFile (
             Private,
             (EFI_MTFTP6_CONFIG_DATA *)Config,
             Filename,
             BlockSize,
             WindowSize,
             BufferPtr,
             BufferSize,
             DontUseBuffer
             );
  } else {
    return PxeBcMtftp4ReadFile (
             Private,
             (EFI_MTFTP4_CONFIG_DATA *)Config,
             Filename,
             BlockSize,
             WindowSize,
             BufferPtr,
             BufferSize,
             DontUseBuffer
             );
  }
}

/**
  This function is a wrapper to write file using TFTP.

  @param[in]       Private        Pointer to PxeBc private data.
  @param[in]       Config         Pointer to config data.
  @param[in]       Filename       Pointer to boot file name.
  @param[in]       Overwrite      Indicate whether with overwrite attribute.
  @param[in]       BlockSize      Pointer to required block size.
  @param[in]       BufferPtr      Pointer to buffer.
  @param[in, out]  BufferSize     Pointer to buffer size.

  @retval EFI_SUCCESS        Successfully wrote the data into a special file.
  @retval EFI_DEVICE_ERROR   The network device encountered an error during this operation.
  @retval other              Write data into file failed.

**/
EFI_STATUS
PxeBcTftpWriteFile (
  IN     PXEBC_PRIVATE_DATA  *Private,
  IN     VOID                *Config,
  IN     UINT8               *Filename,
  IN     BOOLEAN             Overwrite,
  IN     UINTN               *BlockSize,
  IN     UINT8               *BufferPtr,
  IN OUT UINT64              *BufferSize
  )
{
  if (Private->PxeBc.Mode->UsingIpv6) {
    return PxeBcMtftp6WriteFile (
             Private,
             (EFI_MTFTP6_CONFIG_DATA *)Config,
             Filename,
             Overwrite,
             BlockSize,
             BufferPtr,
             BufferSize
             );
  } else {
    return PxeBcMtftp4WriteFile (
             Private,
             (EFI_MTFTP4_CONFIG_DATA *)Config,
             Filename,
             Overwrite,
             BlockSize,
             BufferPtr,
             BufferSize
             );
  }
}

/**
  This function is a wrapper to get the data (file) from a directory using TFTP.

  @param[in]       Private        Pointer to PxeBc private data.
  @param[in]       Config         Pointer to config data.
  @param[in]       Filename       Pointer to boot file name.
  @param[in]       BlockSize      Pointer to required block size.
  @param[in]       WindowSize     Pointer to required window size.
  @param[in]       BufferPtr      Pointer to buffer.
  @param[in, out]  BufferSize     Pointer to buffer size.
  @param[in]       DontUseBuffer  Indicatse whether to use a receive buffer.

  @retval EFI_SUCCESS        Successfully obtained the data from the file included in the directory.
  @retval EFI_DEVICE_ERROR   The network device encountered an error during this operation.
  @retval Others             Operation failed.

**/
EFI_STATUS
PxeBcTftpReadDirectory (
  IN     PXEBC_PRIVATE_DATA  *Private,
  IN     VOID                *Config,
  IN     UINT8               *Filename,
  IN     UINTN               *BlockSize,
  IN     UINTN               *WindowSize,
  IN     UINT8               *BufferPtr,
  IN OUT UINT64              *BufferSize,
  IN     BOOLEAN             DontUseBuffer
  )
{
  if (Private->PxeBc.Mode->UsingIpv6) {
    return PxeBcMtftp6ReadDirectory (
             Private,
             (EFI_MTFTP6_CONFIG_DATA *)Config,
             Filename,
             BlockSize,
             WindowSize,
             BufferPtr,
             BufferSize,
             DontUseBuffer
             );
  } else {
    return PxeBcMtftp4ReadDirectory (
             Private,
             (EFI_MTFTP4_CONFIG_DATA *)Config,
             Filename,
             BlockSize,
             WindowSize,
             BufferPtr,
             BufferSize,
             DontUseBuffer
             );
  }
}
