/** @file
  Mtftp6 Wrq process functions implementation.

  Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>

  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php.

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "Mtftp6Impl.h"



/**
  Build and send a Mtftp6 data packet for upload.

  @param[in]  Instance              The pointer to the Mtftp6 instance.
  @param[in]  BlockNum              The block num to be sent.

  @retval EFI_OUT_OF_RESOURCES  Failed to allocate memory for the packet.
  @retval EFI_SUCCESS           The data packet was sent.
  @retval EFI_ABORTED           The user aborted this process.

**/
EFI_STATUS
Mtftp6WrqSendBlock (
  IN MTFTP6_INSTANCE        *Instance,
  IN UINT16                 BlockNum
  )
{
  EFI_MTFTP6_PACKET         *Packet;
  EFI_MTFTP6_TOKEN          *Token;
  NET_BUF                   *UdpPacket;
  EFI_STATUS                Status;
  UINT16                    DataLen;
  UINT8                     *DataBuf;
  UINT64                    Start;

  //
  // Allocate net buffer to create data packet.
  //
  UdpPacket = NetbufAlloc (Instance->BlkSize + MTFTP6_DATA_HEAD_LEN);

  if (UdpPacket == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Packet = (EFI_MTFTP6_PACKET *) NetbufAllocSpace (
                                   UdpPacket,
                                   MTFTP6_DATA_HEAD_LEN,
                                   FALSE
                                   );
  ASSERT (Packet != NULL);

  Packet->Data.OpCode = HTONS (EFI_MTFTP6_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->LastBlk = BlockNum;
      Mtftp6SetLastBlockNum (&Instance->BlkList, 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->Mtftp6, Token, &DataLen, (VOID*) &DataBuf);

    if (EFI_ERROR (Status) || (DataLen > Instance->BlkSize)) {
      if (DataBuf != NULL) {
        gBS->FreePool (DataBuf);
      }
      //
      // The received packet has already been freed.
      //
      Mtftp6SendError (
        Instance,
        EFI_MTFTP6_ERRORCODE_REQUEST_DENIED,
        (UINT8 *) "User aborted the transfer"
        );

      return EFI_ABORTED;
    }

    if (DataLen < Instance->BlkSize) {
      Instance->LastBlk = BlockNum;
      Mtftp6SetLastBlockNum (&Instance->BlkList, BlockNum);
    }

    if (DataLen > 0) {
      NetbufAllocSpace (UdpPacket, DataLen, FALSE);
      CopyMem (Packet->Data.Data, DataBuf, DataLen);
      gBS->FreePool (DataBuf);
    }
  }

  //
  // Reset current retry count of the instance.
  //
  Instance->CurRetry = 0;

  return Mtftp6TransmitPacket (Instance, UdpPacket);
}


/**
  Function to handle received ACK packet. If the ACK number matches the
  expected block number, with more data pending, send the next
  block. Otherwise, tell the caller that we are done.

  @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 upload has been completed.
                                    Otherwise, the upload has not been completed.

  @retval EFI_SUCCESS           The ACK packet successfully processed.
  @retval EFI_TFTP_ERROR        The block number loops back.
  @retval Others                Failed to transmit the next data packet.

**/
EFI_STATUS
Mtftp6WrqHandleAck (
  IN  MTFTP6_INSTANCE       *Instance,
  IN  EFI_MTFTP6_PACKET     *Packet,
  IN  UINT32                Len,
  OUT NET_BUF               **UdpPacket,
  OUT BOOLEAN               *IsCompleted
  )
{
  UINT16                    AckNum;
  INTN                      Expected;
  UINT64                    TotalBlock;

  *IsCompleted = FALSE;
  AckNum       = NTOHS (Packet->Ack.Block[0]);
  Expected     = Mtftp6GetNextBlockNum (&Instance->BlkList);

  ASSERT (Expected >= 0);

  //
  // Get an unwanted ACK, return EFI_SUCCESS to let Mtftp6WrqInput
  // restart receive.
  //
  if (Expected != AckNum) {
    return EFI_SUCCESS;
  }

  //
  // Remove the acked block number, if this is the last block number,
  // tell the Mtftp6WrqInput to finish the transfer. This is the last
  // block number if the block range are empty..
  //
  Mtftp6RemoveBlockNum (&Instance->BlkList, AckNum, *IsCompleted, &TotalBlock);

  Expected = Mtftp6GetNextBlockNum (&Instance->BlkList);

  if (Expected < 0) {
    //
    // The block range is empty. It may either because the the last
    // block has been ACKed, or the sequence number just looped back,
    // that is, there is more than 0xffff blocks.
    //
    if (Instance->LastBlk == AckNum) {
      ASSERT (Instance->LastBlk >= 1);
      *IsCompleted = TRUE;
      return EFI_SUCCESS;

    } else {
      //
      // 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 block number rolls back.
      //
      Mtftp6SendError (
        Instance,
        EFI_MTFTP6_ERRORCODE_REQUEST_DENIED,
        (UINT8 *) "Block number rolls back, not supported, try blksize option"
        );

      return EFI_TFTP_ERROR;
    }
  }

  //
  // Free the receive buffer before send new packet since it might need
  // reconfigure udpio.
  //
  NetbufFree (*UdpPacket);
  *UdpPacket = NULL;

  return Mtftp6WrqSendBlock (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 MTFTP6 options as required.

  @param[in]  ReplyInfo             The pointer to options information in reply packet.
  @param[in]  RequestInfo           The pointer to requested options information.

  @retval     TRUE                  If the option in OACK is valid.
  @retval     FALSE                 If the option is invalid.

**/
BOOLEAN
Mtftp6WrqOackValid (
  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;
  }

  return TRUE;
}


/**
  Process the OACK packet for Wrq.

  @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 upload has been completed.
                                    Otherwise, the upload has not been completed.

  @retval EFI_SUCCESS           The OACK packet successfully processed.
  @retval EFI_TFTP_ERROR        An TFTP communication error happened.
  @retval Others                Failed to process the OACK packet.

**/
EFI_STATUS
Mtftp6WrqHandleOack (
  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_MTFTP6_PACKET         Dummy;
  EFI_STATUS                Status;
  INTN                      Expected;

  *IsCompleted = FALSE;

  //
  // Ignore the OACK if already started the upload
  //
  Expected = Mtftp6GetNextBlockNum (&Instance->BlkList);

  if (Expected != 0) {
    return EFI_SUCCESS;
  }

  //
  // Parse and validate the options from server
  //
  ZeroMem (&ExtInfo, sizeof (MTFTP6_EXT_OPTION_INFO));

  Status = Mtftp6ParseStart (Packet, Len, &Count, &Options);

  if (EFI_ERROR (Status)) {
    return Status;
  }
  ASSERT (Options != NULL);

  Status = Mtftp6ParseExtensionOption (Options, Count, FALSE, &ExtInfo);

  if (EFI_ERROR(Status) || !Mtftp6WrqOackValid (&ExtInfo, &Instance->ExtInfo)) {
    //
    // Don't send a MTFTP error packet when out of resource, it can
    // only make it worse.
    //
    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 Oack packet received.
      //
      Mtftp6SendError (
        Instance,
        EFI_MTFTP6_ERRORCODE_ILLEGAL_OPERATION,
        (UINT8 *) "Mal-formated OACK packet"
        );
    }

    return EFI_TFTP_ERROR;
  }

  if (ExtInfo.BlkSize != 0) {
    Instance->BlkSize = ExtInfo.BlkSize;
  }

  if (ExtInfo.Timeout != 0) {
    Instance->Timeout = ExtInfo.Timeout;
  }

  //
  // Build a bogus ACK0 packet then pass it to the Mtftp6WrqHandleAck,
  // which will start the transmission of the first data block.
  //
  Dummy.Ack.OpCode   = HTONS (EFI_MTFTP6_OPCODE_ACK);
  Dummy.Ack.Block[0] = 0;

  return Mtftp6WrqHandleAck (
           Instance,
           &Dummy,
           sizeof (EFI_MTFTP6_ACK_HEADER),
           UdpPacket,
           IsCompleted
           );
}


/**
  The packet process callback for Mtftp6 upload.

  @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
Mtftp6WrqInput (
  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;
  EFI_STATUS                Status;
  UINT32                    TotalNum;
  UINT32                    Len;
  UINT16                    Opcode;

  Instance = (MTFTP6_INSTANCE *) Context;

  NET_CHECK_SIGNATURE (Instance, MTFTP6_INSTANCE_SIGNATURE);

  IsCompleted = FALSE;
  Packet      = NULL;
  Status      = EFI_SUCCESS;
  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;
  }

  //
  // Client send initial request to server's listening port. Server
  // will select a UDP port to communicate with the client.
  //
  if (UdpEpt->RemotePort != Instance->ServerDataPort) {
    if (Instance->ServerDataPort != 0) {
      goto ON_EXIT;
    } else {
      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_ACK:
    if (Len != MTFTP6_OPCODE_LEN + MTFTP6_BLKNO_LEN) {
      goto ON_EXIT;
    }
    //
    // Handle the Ack packet of Wrq.
    //
    Status = Mtftp6WrqHandleAck (Instance, Packet, Len, &UdpPacket, &IsCompleted);
    break;

  case EFI_MTFTP6_OPCODE_OACK:
    if (Len <= MTFTP6_OPCODE_LEN) {
      goto ON_EXIT;
    }
    //
    // Handle the Oack packet of Wrq.
    //
    Status = Mtftp6WrqHandleOack (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) and not completed,
  // restart the receive, otherwise end the session.
  //
  if (Packet != NULL && TotalNum > 1) {
    FreePool (Packet);
  }

  if (UdpPacket != NULL) {
    NetbufFree (UdpPacket);
  }

  if (!EFI_ERROR (Status) && !IsCompleted) {
    Status = UdpIoRecvDatagram (
               Instance->UdpIo,
               Mtftp6WrqInput,
               Instance,
               0
               );
  }
  //
  // Clean up the current session if failed to continue.
  //
  if (EFI_ERROR (Status) || IsCompleted) {
    Mtftp6OperationClean (Instance, Status);
  }
}


/**
  Start the Mtftp6 instance to upload. It will first init some states,
  then send the WRQ request packet, and start to receive the packet.

  @param[in]  Instance              The pointer to the Mtftp6 instance.
  @param[in]  Operation             The operation code of the current packet.

  @retval EFI_SUCCESS           The Mtftp6 was started to upload.
  @retval Others                Failed to start to upload.

**/
EFI_STATUS
Mtftp6WrqStart (
  IN MTFTP6_INSTANCE        *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 = Mtftp6InitBlockRange (&Instance->BlkList, 0, 0xffff);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = Mtftp6SendRequest (Instance, Operation);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  return UdpIoRecvDatagram (
           Instance->UdpIo,
           Mtftp6WrqInput,
           Instance,
           0
           );
}

