/** @file
  Mtftp6 Wrq process functions implementation.

  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>

  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php.

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "Mtftp6Impl.h"



/**
  Build and send a 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;
  }

  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
           );
}

