/** @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
EFIAPI
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
EFIAPI
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
EFIAPI
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
EFIAPI
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
EFIAPI
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;
}
