/** @file
  Routines to process Wrq (upload).

Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Mtftp4Impl.h"

/**
  Build then send a MTFTP data packet for the MTFTP upload session.

  @param  Instance              The MTFTP upload session.
  @param  BlockNum              The block number to send.

  @retval EFI_OUT_OF_RESOURCES  Failed to build the packet.
  @retval EFI_ABORTED           The consumer of this child directs to abort the
                                transmission by return an error through PacketNeeded.
  @retval EFI_SUCCESS           The data is sent.

**/
EFI_STATUS
Mtftp4WrqSendBlock (
  IN OUT MTFTP4_PROTOCOL  *Instance,
  IN     UINT16           BlockNum
  )
{
  EFI_MTFTP4_PACKET  *Packet;
  EFI_MTFTP4_TOKEN   *Token;
  NET_BUF            *UdpPacket;
  EFI_STATUS         Status;
  UINT16             DataLen;
  UINT8              *DataBuf;
  UINT64             Start;

  //
  // Allocate a buffer to hold the user data
  //
  UdpPacket = NetbufAlloc (Instance->BlkSize + MTFTP4_DATA_HEAD_LEN);

  if (UdpPacket == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Packet = (EFI_MTFTP4_PACKET *)NetbufAllocSpace (UdpPacket, MTFTP4_DATA_HEAD_LEN, FALSE);
  ASSERT (Packet != NULL);

  Packet->Data.OpCode = HTONS (EFI_MTFTP4_OPCODE_DATA);
  Packet->Data.Block  = HTONS (BlockNum);

  //
  // Read the block from either the buffer or PacketNeeded callback
  //
  Token   = Instance->Token;
  DataLen = Instance->BlkSize;

  if (Token->Buffer != NULL) {
    Start = MultU64x32 (BlockNum - 1, Instance->BlkSize);

    if (Token->BufferSize < Start + Instance->BlkSize) {
      DataLen             = (UINT16)(Token->BufferSize - Start);
      Instance->LastBlock = BlockNum;
      Mtftp4SetLastBlockNum (&Instance->Blocks, BlockNum);
    }

    if (DataLen > 0) {
      NetbufAllocSpace (UdpPacket, DataLen, FALSE);
      CopyMem (Packet->Data.Data, (UINT8 *)Token->Buffer + Start, DataLen);
    }
  } else {
    //
    // Get data from PacketNeeded
    //
    DataBuf = NULL;
    Status  = Token->PacketNeeded (
                       &Instance->Mtftp4,
                       Token,
                       &DataLen,
                       (VOID **)&DataBuf
                       );

    if (EFI_ERROR (Status) || (DataLen > Instance->BlkSize)) {
      if (DataBuf != NULL) {
        FreePool (DataBuf);
      }

      if (UdpPacket != NULL) {
        NetbufFree (UdpPacket);
      }

      Mtftp4SendError (
        Instance,
        EFI_MTFTP4_ERRORCODE_REQUEST_DENIED,
        (UINT8 *)"User aborted the transfer"
        );

      return EFI_ABORTED;
    }

    if (DataLen < Instance->BlkSize) {
      Instance->LastBlock = BlockNum;
      Mtftp4SetLastBlockNum (&Instance->Blocks, BlockNum);
    }

    if (DataLen > 0) {
      NetbufAllocSpace (UdpPacket, DataLen, FALSE);
      CopyMem (Packet->Data.Data, DataBuf, DataLen);
      FreePool (DataBuf);
    }
  }

  return Mtftp4SendPacket (Instance, UdpPacket);
}

/**
  Function to handle received ACK packet.

  If the ACK number matches the expected block number, and there are more
  data pending, send the next block. Otherwise tell the caller that we are done.

  @param  Instance              The MTFTP upload session
  @param  Packet                The MTFTP packet received
  @param  Len                   The packet length
  @param  Completed             Return whether the upload has finished.

  @retval EFI_SUCCESS           The ACK is successfully processed.
  @retval EFI_TFTP_ERROR        The block number loops back.
  @retval Others                Failed to transmit the next data packet.

**/
EFI_STATUS
Mtftp4WrqHandleAck (
  IN     MTFTP4_PROTOCOL    *Instance,
  IN     EFI_MTFTP4_PACKET  *Packet,
  IN     UINT32             Len,
  OUT BOOLEAN               *Completed
  )
{
  UINT16  AckNum;
  INTN    Expected;
  UINT64  BlockCounter;

  *Completed = FALSE;
  AckNum     = NTOHS (Packet->Ack.Block[0]);
  Expected   = Mtftp4GetNextBlockNum (&Instance->Blocks);

  ASSERT (Expected >= 0);

  //
  // Get an unwanted ACK, return EFI_SUCCESS to let Mtftp4WrqInput
  // restart receive.
  //
  if (Expected != AckNum) {
    return EFI_SUCCESS;
  }

  //
  // Remove the acked block number, if this is the last block number,
  // tell the Mtftp4WrqInput to finish the transfer. This is the last
  // block number if the block range are empty.
  //
  Mtftp4RemoveBlockNum (&Instance->Blocks, AckNum, *Completed, &BlockCounter);

  Expected = Mtftp4GetNextBlockNum (&Instance->Blocks);

  if (Expected < 0) {
    //
    // The block range is empty. It may either because the last
    // block has been ACKed, or the sequence number just looped back,
    // that is, there is more than 0xffff blocks.
    //
    if (Instance->LastBlock == AckNum) {
      ASSERT (Instance->LastBlock >= 1);
      *Completed = TRUE;
      return EFI_SUCCESS;
    } else {
      Mtftp4SendError (
        Instance,
        EFI_MTFTP4_ERRORCODE_REQUEST_DENIED,
        (UINT8 *)"Block number rolls back, not supported, try blksize option"
        );

      return EFI_TFTP_ERROR;
    }
  }

  return Mtftp4WrqSendBlock (Instance, (UINT16)Expected);
}

/**
  Check whether the received OACK is valid.

  The OACK is valid only if:
  1. It only include options requested by us
  2. It can only include a smaller block size
  3. It can't change the proposed time out value.
  4. Other requirements of the individal MTFTP options as required.

  @param  Reply                 The options included in the OACK
  @param  Request               The options we requested

  @retval TRUE                  The options included in OACK is valid.
  @retval FALSE                 The options included in OACK is invalid.

**/
BOOLEAN
Mtftp4WrqOackValid (
  IN MTFTP4_OPTION  *Reply,
  IN MTFTP4_OPTION  *Request
  )
{
  //
  // It is invalid for server to return options we don't request
  //
  if ((Reply->Exist & ~Request->Exist) != 0) {
    return FALSE;
  }

  //
  // Server can only specify a smaller block size to be used and
  // return the timeout matches that requested.
  //
  if ((((Reply->Exist & MTFTP4_BLKSIZE_EXIST) != 0) && (Reply->BlkSize > Request->BlkSize)) ||
      (((Reply->Exist & MTFTP4_TIMEOUT_EXIST) != 0) && (Reply->Timeout != Request->Timeout)))
  {
    return FALSE;
  }

  return TRUE;
}

/**
  Function to handle the MTFTP OACK packet.

  It parses the packet's options, and update the internal states of the session.

  @param  Instance              The MTFTP session
  @param  Packet                The received OACK packet
  @param  Len                   The length of the packet
  @param  Completed             Whether the transmission has completed. NOT used by
                                this function.

  @retval EFI_SUCCESS           The OACK process is OK
  @retval EFI_TFTP_ERROR        Some error occurred, and the session reset.

**/
EFI_STATUS
Mtftp4WrqHandleOack (
  IN OUT MTFTP4_PROTOCOL    *Instance,
  IN     EFI_MTFTP4_PACKET  *Packet,
  IN     UINT32             Len,
  OUT BOOLEAN               *Completed
  )
{
  MTFTP4_OPTION      Reply;
  EFI_MTFTP4_PACKET  Bogus;
  EFI_STATUS         Status;
  INTN               Expected;

  *Completed = FALSE;

  //
  // Ignore the OACK if already started the upload
  //
  Expected = Mtftp4GetNextBlockNum (&Instance->Blocks);

  if (Expected != 0) {
    return EFI_SUCCESS;
  }

  //
  // Parse and validate the options from server
  //
  ZeroMem (&Reply, sizeof (MTFTP4_OPTION));
  Status = Mtftp4ParseOptionOack (Packet, Len, Instance->Operation, &Reply);

  if (EFI_ERROR (Status) || !Mtftp4WrqOackValid (&Reply, &Instance->RequestOption)) {
    //
    // Don't send a MTFTP error packet when out of resource, it can
    // only make it worse.
    //
    if (Status != EFI_OUT_OF_RESOURCES) {
      Mtftp4SendError (
        Instance,
        EFI_MTFTP4_ERRORCODE_ILLEGAL_OPERATION,
        (UINT8 *)"Malformatted OACK packet"
        );
    }

    return EFI_TFTP_ERROR;
  }

  if (Reply.BlkSize != 0) {
    Instance->BlkSize = Reply.BlkSize;
  }

  if (Reply.Timeout != 0) {
    Instance->Timeout = Reply.Timeout;
  }

  //
  // Build a bogus ACK0 packet then pass it to the Mtftp4WrqHandleAck,
  // which will start the transmission of the first data block.
  //
  Bogus.Ack.OpCode   = HTONS (EFI_MTFTP4_OPCODE_ACK);
  Bogus.Ack.Block[0] = 0;

  Status = Mtftp4WrqHandleAck (
             Instance,
             &Bogus,
             sizeof (EFI_MTFTP4_ACK_HEADER),
             Completed
             );

  return Status;
}

/**
  The input process routine for MTFTP upload.

  @param  UdpPacket             The received MTFTP packet.
  @param  EndPoint              The local/remote access point
  @param  IoStatus              The result of the packet receiving
  @param  Context               Opaque parameter for the callback, which is the
                                MTFTP session.
**/
VOID
EFIAPI
Mtftp4WrqInput (
  IN NET_BUF        *UdpPacket,
  IN UDP_END_POINT  *EndPoint,
  IN EFI_STATUS     IoStatus,
  IN VOID           *Context
  )
{
  MTFTP4_PROTOCOL    *Instance;
  EFI_MTFTP4_PACKET  *Packet;
  BOOLEAN            Completed;
  EFI_STATUS         Status;
  UINT32             Len;
  UINT16             Opcode;

  Instance = (MTFTP4_PROTOCOL *)Context;
  NET_CHECK_SIGNATURE (Instance, MTFTP4_PROTOCOL_SIGNATURE);

  Completed = FALSE;
  Packet    = NULL;
  Status    = EFI_SUCCESS;

  if (EFI_ERROR (IoStatus)) {
    Status = IoStatus;
    goto ON_EXIT;
  }

  ASSERT (UdpPacket != NULL);

  if (UdpPacket->TotalSize < MTFTP4_OPCODE_LEN) {
    goto ON_EXIT;
  }

  //
  // Client send initial request to server's listening port. Server
  // will select a UDP port to communicate with the client.
  //
  if (EndPoint->RemotePort != Instance->ConnectedPort) {
    if (Instance->ConnectedPort != 0) {
      goto ON_EXIT;
    } else {
      Instance->ConnectedPort = EndPoint->RemotePort;
    }
  }

  //
  // Copy the MTFTP packet to a continuous buffer if it isn't already so.
  //
  Len = UdpPacket->TotalSize;

  if (UdpPacket->BlockOpNum > 1) {
    Packet = AllocatePool (Len);

    if (Packet == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ON_EXIT;
    }

    NetbufCopy (UdpPacket, 0, Len, (UINT8 *)Packet);
  } else {
    Packet = (EFI_MTFTP4_PACKET *)NetbufGetByte (UdpPacket, 0, NULL);
    ASSERT (Packet != NULL);
  }

  Opcode = NTOHS (Packet->OpCode);

  //
  // Call the user's CheckPacket if provided. Abort the transmission
  // if CheckPacket returns an EFI_ERROR code.
  //
  if ((Instance->Token->CheckPacket != NULL) &&
      ((Opcode == EFI_MTFTP4_OPCODE_OACK) || (Opcode == EFI_MTFTP4_OPCODE_ERROR)))
  {
    Status = Instance->Token->CheckPacket (
                                &Instance->Mtftp4,
                                Instance->Token,
                                (UINT16)Len,
                                Packet
                                );

    if (EFI_ERROR (Status)) {
      //
      // Send an error message to the server to inform it
      //
      if (Opcode != EFI_MTFTP4_OPCODE_ERROR) {
        Mtftp4SendError (
          Instance,
          EFI_MTFTP4_ERRORCODE_REQUEST_DENIED,
          (UINT8 *)"User aborted the transfer"
          );
      }

      Status = EFI_ABORTED;
      goto ON_EXIT;
    }
  }

  switch (Opcode) {
    case EFI_MTFTP4_OPCODE_ACK:
      if (Len != MTFTP4_OPCODE_LEN + MTFTP4_BLKNO_LEN) {
        goto ON_EXIT;
      }

      Status = Mtftp4WrqHandleAck (Instance, Packet, Len, &Completed);
      break;

    case EFI_MTFTP4_OPCODE_OACK:
      if (Len <= MTFTP4_OPCODE_LEN) {
        goto ON_EXIT;
      }

      Status = Mtftp4WrqHandleOack (Instance, Packet, Len, &Completed);
      break;

    case EFI_MTFTP4_OPCODE_ERROR:
      Status = EFI_TFTP_ERROR;
      break;

    default:
      break;
  }

ON_EXIT:
  //
  // Free the resources, then if !EFI_ERROR (Status) and not completed,
  // restart the receive, otherwise end the session.
  //
  if ((Packet != NULL) && (UdpPacket->BlockOpNum > 1)) {
    FreePool (Packet);
  }

  if (UdpPacket != NULL) {
    NetbufFree (UdpPacket);
  }

  if (!EFI_ERROR (Status) && !Completed) {
    Status = UdpIoRecvDatagram (Instance->UnicastPort, Mtftp4WrqInput, Instance, 0);
  }

  //
  // Status may have been updated by UdpIoRecvDatagram
  //
  if (EFI_ERROR (Status) || Completed) {
    Mtftp4CleanOperation (Instance, Status);
  }
}

/**
  Start the MTFTP session for upload.

  It will first init some states, then send the WRQ request packet,
  and start receiving the packet.

  @param  Instance              The MTFTP session
  @param  Operation             Redundant parameter, which is always
                                EFI_MTFTP4_OPCODE_WRQ here.

  @retval EFI_SUCCESS           The upload process has been started.
  @retval Others                Failed to start the upload.

**/
EFI_STATUS
Mtftp4WrqStart (
  IN MTFTP4_PROTOCOL  *Instance,
  IN UINT16           Operation
  )
{
  EFI_STATUS  Status;

  //
  // The valid block number range are [0, 0xffff]. For example:
  // the client sends an WRQ request to the server, the server
  // ACK with an ACK0 to let client start transfer the first
  // packet.
  //
  Status = Mtftp4InitBlockRange (&Instance->Blocks, 0, 0xffff);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = Mtftp4SendRequest (Instance);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  return UdpIoRecvDatagram (Instance->UnicastPort, Mtftp4WrqInput, Instance, 0);
}
