/** @file
#
#  Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
#
#  SPDX-License-Identifier: BSD-2-Clause-Patent
#
#
#**/

#include <Protocol/AndroidFastbootTransport.h>
#include <Protocol/Dhcp4.h>
#include <Protocol/Tcp4.h>
#include <Protocol/ServiceBinding.h>
#include <Protocol/SimpleTextOut.h>

#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiRuntimeServicesTableLib.h>

#define IP4_ADDR_TO_STRING(IpAddr, IpAddrString)  UnicodeSPrint (      \
                                                   IpAddrString,       \
                                                   16 * 2,             \
                                                   L"%d.%d.%d.%d",     \
                                                   IpAddr.Addr[0],     \
                                                   IpAddr.Addr[1],     \
                                                   IpAddr.Addr[2],     \
                                                   IpAddr.Addr[3]      \
                                                   );

// Fastboot says max packet size is 512, but FASTBOOT_TRANSPORT_PROTOCOL
// doesn't place a limit on the size of buffers returned by Receive.
// (This isn't actually a packet size - it's just the size of the buffers we
//  pass to the TCP driver to fill with received data.)
// We can achieve much better performance by doing this in larger chunks.
#define RX_FRAGMENT_SIZE  2048

STATIC EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *mTextOut;

STATIC EFI_TCP4_PROTOCOL  *mTcpConnection;
STATIC EFI_TCP4_PROTOCOL  *mTcpListener;

STATIC EFI_EVENT  mReceiveEvent;

STATIC EFI_SERVICE_BINDING_PROTOCOL  *mTcpServiceBinding;
STATIC EFI_HANDLE                    mTcpHandle = NULL;

// We only ever use one IO token for receive and one for transmit. To save
// repeatedly allocating and freeing, just allocate statically and re-use.
#define NUM_RX_TOKENS  16
#define TOKEN_NEXT(Index)  (((Index) + 1) % NUM_RX_TOKENS)

STATIC UINTN                   mNextSubmitIndex;
STATIC UINTN                   mNextReceiveIndex;
STATIC EFI_TCP4_IO_TOKEN       mReceiveToken[NUM_RX_TOKENS];
STATIC EFI_TCP4_RECEIVE_DATA   mRxData[NUM_RX_TOKENS];
STATIC EFI_TCP4_IO_TOKEN       mTransmitToken;
STATIC EFI_TCP4_TRANSMIT_DATA  mTxData;
// We also reuse the accept token
STATIC EFI_TCP4_LISTEN_TOKEN  mAcceptToken;
// .. and the close token
STATIC EFI_TCP4_CLOSE_TOKEN  mCloseToken;

// List type for queued received packets
typedef struct _FASTBOOT_TCP_PACKET_LIST {
  LIST_ENTRY    Link;
  VOID          *Buffer;
  UINTN         BufferSize;
} FASTBOOT_TCP_PACKET_LIST;

STATIC LIST_ENTRY  mPacketListHead;

STATIC
VOID
EFIAPI
DataReceived (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  );

/*
  Helper function to set up a receive IO token and call Tcp->Receive
*/
STATIC
EFI_STATUS
SubmitRecieveToken (
  VOID
  )
{
  EFI_STATUS  Status;
  VOID        *FragmentBuffer;

  Status = EFI_SUCCESS;

  FragmentBuffer = AllocatePool (RX_FRAGMENT_SIZE);
  ASSERT (FragmentBuffer != NULL);
  if (FragmentBuffer == NULL) {
    DEBUG ((DEBUG_ERROR, "TCP Fastboot out of resources"));
    return EFI_OUT_OF_RESOURCES;
  }

  mRxData[mNextSubmitIndex].DataLength                      = RX_FRAGMENT_SIZE;
  mRxData[mNextSubmitIndex].FragmentTable[0].FragmentLength = RX_FRAGMENT_SIZE;
  mRxData[mNextSubmitIndex].FragmentTable[0].FragmentBuffer = FragmentBuffer;

  Status = mTcpConnection->Receive (mTcpConnection, &mReceiveToken[mNextSubmitIndex]);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "TCP Receive: %r\n", Status));
    FreePool (FragmentBuffer);
  }

  mNextSubmitIndex = TOKEN_NEXT (mNextSubmitIndex);
  return Status;
}

/*
  Event notify function for when we have closed our TCP connection.
  We can now start listening for another connection.
*/
STATIC
VOID
ConnectionClosed (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  EFI_STATUS  Status;

  // Possible bug in EDK2 TCP4 driver: closing a connection doesn't remove its
  // PCB from the list of live connections. Subsequent attempts to Configure()
  // a TCP instance with the same local port will fail with INVALID_PARAMETER.
  // Calling Configure with NULL is a workaround for this issue.
  Status = mTcpConnection->Configure (mTcpConnection, NULL);

  mTcpConnection = NULL;

  Status = mTcpListener->Accept (mTcpListener, &mAcceptToken);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "TCP Accept: %r\n", Status));
  }
}

STATIC
VOID
CloseReceiveEvents (
  VOID
  )
{
  UINTN  Index;

  for (Index = 0; Index < NUM_RX_TOKENS; Index++) {
    gBS->CloseEvent (mReceiveToken[Index].CompletionToken.Event);
  }
}

/*
  Event notify function to be called when we receive TCP data.
*/
STATIC
VOID
EFIAPI
DataReceived (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  EFI_STATUS                Status;
  FASTBOOT_TCP_PACKET_LIST  *NewEntry;
  EFI_TCP4_IO_TOKEN         *ReceiveToken;

  ReceiveToken = &mReceiveToken[mNextReceiveIndex];

  Status = ReceiveToken->CompletionToken.Status;

  if (Status == EFI_CONNECTION_FIN) {
    //
    // Remote host closed connection. Close our end.
    //

    CloseReceiveEvents ();

    Status = mTcpConnection->Close (mTcpConnection, &mCloseToken);
    ASSERT_EFI_ERROR (Status);

    return;
  }

  //
  // Add an element to the receive queue
  //

  NewEntry = AllocatePool (sizeof (FASTBOOT_TCP_PACKET_LIST));
  if (NewEntry == NULL) {
    DEBUG ((DEBUG_ERROR, "TCP Fastboot: Out of resources\n"));
    return;
  }

  mNextReceiveIndex = TOKEN_NEXT (mNextReceiveIndex);

  if (!EFI_ERROR (Status)) {
    NewEntry->Buffer
      = ReceiveToken->Packet.RxData->FragmentTable[0].FragmentBuffer;
    NewEntry->BufferSize
      = ReceiveToken->Packet.RxData->FragmentTable[0].FragmentLength;

    // Prepare to receive more data
    SubmitRecieveToken ();
  } else {
    // Fatal receive error. Put an entry with NULL in the queue, signifying
    // to return EFI_DEVICE_ERROR from TcpFastbootTransportReceive.
    NewEntry->Buffer     = NULL;
    NewEntry->BufferSize = 0;

    DEBUG ((DEBUG_ERROR, "\nTCP Fastboot Receive error: %r\n", Status));
  }

  InsertTailList (&mPacketListHead, &NewEntry->Link);

  Status = gBS->SignalEvent (mReceiveEvent);
  ASSERT_EFI_ERROR (Status);
}

/*
  Event notify function to be called when we accept an incoming TCP connection.
*/
STATIC
VOID
EFIAPI
ConnectionAccepted (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  EFI_TCP4_LISTEN_TOKEN  *AcceptToken;
  EFI_STATUS             Status;
  UINTN                  Index;

  AcceptToken = (EFI_TCP4_LISTEN_TOKEN *)Context;
  Status      = AcceptToken->CompletionToken.Status;

  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "TCP Fastboot: Connection Error: %r\n", Status));
    return;
  }

  DEBUG ((DEBUG_ERROR, "TCP Fastboot: Connection Received.\n"));

  //
  // Accepting a new TCP connection creates a new instance of the TCP protocol.
  // Open it and prepare to receive on it.
  //

  Status = gBS->OpenProtocol (
                  AcceptToken->NewChildHandle,
                  &gEfiTcp4ProtocolGuid,
                  (VOID **)&mTcpConnection,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Open TCP Connection: %r\n", Status));
    return;
  }

  mNextSubmitIndex  = 0;
  mNextReceiveIndex = 0;

  for (Index = 0; Index < NUM_RX_TOKENS; Index++) {
    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_CALLBACK,
                    DataReceived,
                    NULL,
                    &(mReceiveToken[Index].CompletionToken.Event)
                    );
    ASSERT_EFI_ERROR (Status);
  }

  for (Index = 0; Index < NUM_RX_TOKENS; Index++) {
    SubmitRecieveToken ();
  }
}

/*
  Set up TCP Fastboot transport: Configure the network device via DHCP then
  start waiting for a TCP connection on the Fastboot port.
*/
EFI_STATUS
TcpFastbootTransportStart (
  EFI_EVENT  ReceiveEvent
  )
{
  EFI_STATUS         Status;
  EFI_HANDLE         NetDeviceHandle;
  EFI_HANDLE         *HandleBuffer;
  EFI_IP4_MODE_DATA  Ip4ModeData;
  UINTN              NumHandles;
  CHAR16             IpAddrString[16];
  UINTN              Index;

  EFI_TCP4_CONFIG_DATA  TcpConfigData = {
    0x00,                                           // IPv4 Type of Service
    255,                                            // IPv4 Time to Live
    {                                               // AccessPoint:
      TRUE,                                         // Use default address
      {
        { 0, 0, 0, 0 }
      },                                            // IP Address  (ignored - use default)
      {
        { 0, 0, 0, 0 }
      },                                            // Subnet mask (ignored - use default)
      FixedPcdGet32 (PcdAndroidFastbootTcpPort),    // Station port
      {
        { 0, 0, 0, 0 }
      },                                            // Remote address: accept any
      0,                                            // Remote Port: accept any
      FALSE                                         // ActiveFlag: be a "server"
    },
    NULL                                            // Default advanced TCP options
  };

  mReceiveEvent = ReceiveEvent;
  InitializeListHead (&mPacketListHead);

  mTextOut->OutputString (mTextOut, L"Initialising TCP Fastboot transport...\r\n");

  //
  // Open a passive TCP instance
  //

  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiTcp4ServiceBindingProtocolGuid,
                  NULL,
                  &NumHandles,
                  &HandleBuffer
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Find TCP Service Binding: %r\n", Status));
    return Status;
  }

  // We just use the first network device
  NetDeviceHandle = HandleBuffer[0];

  Status =  gBS->OpenProtocol (
                   NetDeviceHandle,
                   &gEfiTcp4ServiceBindingProtocolGuid,
                   (VOID **)&mTcpServiceBinding,
                   gImageHandle,
                   NULL,
                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
                   );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Open TCP Service Binding: %r\n", Status));
    return Status;
  }

  Status = mTcpServiceBinding->CreateChild (mTcpServiceBinding, &mTcpHandle);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "TCP ServiceBinding Create: %r\n", Status));
    return Status;
  }

  Status =  gBS->OpenProtocol (
                   mTcpHandle,
                   &gEfiTcp4ProtocolGuid,
                   (VOID **)&mTcpListener,
                   gImageHandle,
                   NULL,
                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
                   );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Open TCP Protocol: %r\n", Status));
  }

  //
  // Set up re-usable tokens
  //

  for (Index = 0; Index < NUM_RX_TOKENS; Index++) {
    mRxData[Index].UrgentFlag          = FALSE;
    mRxData[Index].FragmentCount       = 1;
    mReceiveToken[Index].Packet.RxData = &mRxData[Index];
  }

  mTxData.Push                 = TRUE;
  mTxData.Urgent               = FALSE;
  mTxData.FragmentCount        = 1;
  mTransmitToken.Packet.TxData = &mTxData;

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  ConnectionAccepted,
                  &mAcceptToken,
                  &mAcceptToken.CompletionToken.Event
                  );
  ASSERT_EFI_ERROR (Status);

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  ConnectionClosed,
                  &mCloseToken,
                  &mCloseToken.CompletionToken.Event
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Configure the TCP instance
  //

  Status = mTcpListener->Configure (mTcpListener, &TcpConfigData);
  if (Status == EFI_NO_MAPPING) {
    // Wait until the IP configuration process (probably DHCP) has finished
    do {
      Status = mTcpListener->GetModeData (
                               mTcpListener,
                               NULL,
                               NULL,
                               &Ip4ModeData,
                               NULL,
                               NULL
                               );
      ASSERT_EFI_ERROR (Status);
    } while (!Ip4ModeData.IsConfigured);

    Status = mTcpListener->Configure (mTcpListener, &TcpConfigData);
  } else if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "TCP Configure: %r\n", Status));
    return Status;
  }

  //
  // Tell the user our address and hostname
  //
  IP4_ADDR_TO_STRING (Ip4ModeData.ConfigData.StationAddress, IpAddrString);

  mTextOut->OutputString (mTextOut, L"TCP Fastboot transport configured.");
  mTextOut->OutputString (mTextOut, L"\r\nIP address: ");
  mTextOut->OutputString (mTextOut, IpAddrString);
  mTextOut->OutputString (mTextOut, L"\r\n");

  //
  // Start listening for a connection
  //

  Status = mTcpListener->Accept (mTcpListener, &mAcceptToken);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "TCP Accept: %r\n", Status));
    return Status;
  }

  mTextOut->OutputString (mTextOut, L"TCP Fastboot transport initialised.\r\n");

  FreePool (HandleBuffer);

  return EFI_SUCCESS;
}

EFI_STATUS
TcpFastbootTransportStop (
  VOID
  )
{
  EFI_TCP4_CLOSE_TOKEN      CloseToken;
  EFI_STATUS                Status;
  UINTN                     EventIndex;
  FASTBOOT_TCP_PACKET_LIST  *Entry;
  FASTBOOT_TCP_PACKET_LIST  *NextEntry;

  // Close any existing TCP connection, blocking until it's done.
  if (mTcpConnection != NULL) {
    CloseReceiveEvents ();

    CloseToken.AbortOnClose = FALSE;

    Status = gBS->CreateEvent (0, 0, NULL, NULL, &CloseToken.CompletionToken.Event);
    ASSERT_EFI_ERROR (Status);

    Status = mTcpConnection->Close (mTcpConnection, &CloseToken);
    ASSERT_EFI_ERROR (Status);

    Status = gBS->WaitForEvent (
                    1,
                    &CloseToken.CompletionToken.Event,
                    &EventIndex
                    );
    ASSERT_EFI_ERROR (Status);

    ASSERT_EFI_ERROR (CloseToken.CompletionToken.Status);

    // Possible bug in EDK2 TCP4 driver: closing a connection doesn't remove its
    // PCB from the list of live connections. Subsequent attempts to Configure()
    // a TCP instance with the same local port will fail with INVALID_PARAMETER.
    // Calling Configure with NULL is a workaround for this issue.
    Status = mTcpConnection->Configure (mTcpConnection, NULL);
    ASSERT_EFI_ERROR (Status);
  }

  gBS->CloseEvent (mAcceptToken.CompletionToken.Event);

  // Stop listening for connections.
  // Ideally we would do this with Cancel, but it isn't implemented by EDK2.
  // So we just "reset this TCPv4 instance brutally".
  Status = mTcpListener->Configure (mTcpListener, NULL);
  ASSERT_EFI_ERROR (Status);

  Status = mTcpServiceBinding->DestroyChild (mTcpServiceBinding, mTcpHandle);

  // Free any data the user didn't pick up
  Entry = (FASTBOOT_TCP_PACKET_LIST *)GetFirstNode (&mPacketListHead);
  while (!IsNull (&mPacketListHead, &Entry->Link)) {
    NextEntry = (FASTBOOT_TCP_PACKET_LIST *)GetNextNode (&mPacketListHead, &Entry->Link);

    RemoveEntryList (&Entry->Link);
    if (Entry->Buffer) {
      FreePool (Entry->Buffer);
    }

    FreePool (Entry);

    Entry = NextEntry;
  }

  return EFI_SUCCESS;
}

/*
  Event notify function for when data has been sent. Free resources and report
  errors.
  Context should point to the transmit IO token passed to
  TcpConnection->Transmit.
*/
STATIC
VOID
DataSent (
  EFI_EVENT  Event,
  VOID       *Context
  )
{
  EFI_STATUS  Status;

  Status = mTransmitToken.CompletionToken.Status;
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "TCP Fastboot transmit result: %r\n", Status));
    gBS->SignalEvent (*(EFI_EVENT *)Context);
  }

  FreePool (mTransmitToken.Packet.TxData->FragmentTable[0].FragmentBuffer);
}

EFI_STATUS
TcpFastbootTransportSend (
  IN        UINTN      BufferSize,
  IN  CONST VOID       *Buffer,
  IN        EFI_EVENT  *FatalErrorEvent
  )
{
  EFI_STATUS  Status;

  if (BufferSize > 512) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Build transmit IO token
  //

  // Create an event so we are notified when a transmission is complete.
  // We use this to free resources and report errors.
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  DataSent,
                  FatalErrorEvent,
                  &mTransmitToken.CompletionToken.Event
                  );
  ASSERT_EFI_ERROR (Status);

  mTxData.DataLength = BufferSize;

  mTxData.FragmentTable[0].FragmentLength = BufferSize;
  mTxData.FragmentTable[0].FragmentBuffer = AllocateCopyPool (
                                              BufferSize,
                                              Buffer
                                              );

  Status = mTcpConnection->Transmit (mTcpConnection, &mTransmitToken);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "TCP Transmit: %r\n", Status));
    return Status;
  }

  return EFI_SUCCESS;
}

EFI_STATUS
TcpFastbootTransportReceive (
  OUT UINTN  *BufferSize,
  OUT VOID   **Buffer
  )
{
  FASTBOOT_TCP_PACKET_LIST  *Entry;

  if (IsListEmpty (&mPacketListHead)) {
    return EFI_NOT_READY;
  }

  Entry = (FASTBOOT_TCP_PACKET_LIST *)GetFirstNode (&mPacketListHead);

  if (Entry->Buffer == NULL) {
    // There was an error receiving this packet.
    return EFI_DEVICE_ERROR;
  }

  *Buffer     = Entry->Buffer;
  *BufferSize = Entry->BufferSize;

  RemoveEntryList (&Entry->Link);
  FreePool (Entry);

  return EFI_SUCCESS;
}

FASTBOOT_TRANSPORT_PROTOCOL  mTransportProtocol = {
  TcpFastbootTransportStart,
  TcpFastbootTransportStop,
  TcpFastbootTransportSend,
  TcpFastbootTransportReceive
};

EFI_STATUS
TcpFastbootTransportEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  Status = gBS->LocateProtocol (
                  &gEfiSimpleTextOutProtocolGuid,
                  NULL,
                  (VOID **)&mTextOut
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Fastboot: Open Text Output Protocol: %r\n", Status));
    return Status;
  }

  Status = gBS->InstallProtocolInterface (
                  &ImageHandle,
                  &gAndroidFastbootTransportProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &mTransportProtocol
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Fastboot: Install transport Protocol: %r\n", Status));
  }

  return Status;
}
