/** @file
  This library is used to share code between UEFI network stack modules.
  It provides the helper routines to access TCP service.

Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#ifndef _TCP_IO_H_
#define _TCP_IO_H_


#include <Protocol/Tcp4.h>
#include <Protocol/Tcp6.h>

#include <Library/NetLib.h>

#define TCP_VERSION_4 IP_VERSION_4
#define TCP_VERSION_6 IP_VERSION_6

///
/// 10 seconds
///
#define TCP_GET_MAPPING_TIMEOUT 100000000U


typedef struct {
  EFI_IPv4_ADDRESS          LocalIp;
  EFI_IPv4_ADDRESS          SubnetMask;
  EFI_IPv4_ADDRESS          Gateway;

  UINT16                    StationPort;
  EFI_IPv4_ADDRESS          RemoteIp;
  UINT16                    RemotePort;
  BOOLEAN                   ActiveFlag;
} TCP4_IO_CONFIG_DATA;

typedef struct {
  UINT16                    StationPort;
  EFI_IPv6_ADDRESS          RemoteIp;
  UINT16                    RemotePort;
  BOOLEAN                   ActiveFlag;
} TCP6_IO_CONFIG_DATA;

typedef union {
  TCP4_IO_CONFIG_DATA       Tcp4IoConfigData;
  TCP6_IO_CONFIG_DATA       Tcp6IoConfigData;
} TCP_IO_CONFIG_DATA;

typedef union {
  EFI_TCP4_PROTOCOL         *Tcp4;
  EFI_TCP6_PROTOCOL         *Tcp6;
} TCP_IO_PROTOCOL;

typedef union {
  EFI_TCP4_CONNECTION_TOKEN Tcp4Token;
  EFI_TCP6_CONNECTION_TOKEN Tcp6Token;
} TCP_IO_CONNECTION_TOKEN;

typedef union {
  EFI_TCP4_IO_TOKEN         Tcp4Token;
  EFI_TCP6_IO_TOKEN         Tcp6Token;
} TCP_IO_IO_TOKEN;

typedef union {
  EFI_TCP4_CLOSE_TOKEN      Tcp4Token;
  EFI_TCP6_CLOSE_TOKEN      Tcp6Token;
} TCP_IO_CLOSE_TOKEN;

typedef union {
  EFI_TCP4_LISTEN_TOKEN     Tcp4Token;
  EFI_TCP6_LISTEN_TOKEN     Tcp6Token;
} TCP_IO_LISTEN_TOKEN;


typedef struct {
  UINT8                     TcpVersion;
  EFI_HANDLE                Image;
  EFI_HANDLE                Controller;
  EFI_HANDLE                Handle;

  TCP_IO_PROTOCOL           Tcp;
  TCP_IO_PROTOCOL           NewTcp;
  TCP_IO_CONNECTION_TOKEN   ConnToken;
  TCP_IO_IO_TOKEN           TxToken;
  TCP_IO_IO_TOKEN           RxToken;
  TCP_IO_CLOSE_TOKEN        CloseToken;
  TCP_IO_LISTEN_TOKEN       ListenToken;

  BOOLEAN                   IsConnDone;
  BOOLEAN                   IsTxDone;
  BOOLEAN                   IsRxDone;
  BOOLEAN                   IsCloseDone;
  BOOLEAN                   IsListenDone;
} TCP_IO;

/**
  Create a TCP socket with the specified configuration data.

  @param[in]  Image      The handle of the driver image.
  @param[in]  Controller The handle of the controller.
  @param[in]  TcpVersion The version of Tcp, TCP_VERSION_4 or TCP_VERSION_6.
  @param[in]  ConfigData The Tcp configuration data.
  @param[out] TcpIo      The TcpIo.

  @retval EFI_SUCCESS            The TCP socket is created and configured.
  @retval EFI_INVALID_PARAMETER  One or more parameters are invalid.
  @retval EFI_UNSUPPORTED        One or more of the control options are not
                                 supported in the implementation.
  @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory.
  @retval Others                 Failed to create the TCP socket or configure it.

**/
EFI_STATUS
EFIAPI
TcpIoCreateSocket (
  IN EFI_HANDLE             Image,
  IN EFI_HANDLE             Controller,
  IN UINT8                  TcpVersion,
  IN TCP_IO_CONFIG_DATA     *ConfigData,
  OUT TCP_IO                *TcpIo
  );

/**
  Destroy the socket.

  @param[in]  TcpIo The TcpIo which wraps the socket to be destroyed.

**/
VOID
EFIAPI
TcpIoDestroySocket (
  IN TCP_IO                 *TcpIo
  );

/**
  Connect to the other endpoint of the TCP socket.

  @param[in, out]  TcpIo     The TcpIo wrapping the TCP socket.
  @param[in]       Timeout   The time to wait for connection done. Set to NULL for infinite wait.

  @retval EFI_SUCCESS            Connect to the other endpoint of the TCP socket
                                 successfully.
  @retval EFI_TIMEOUT            Failed to connect to the other endpoint of the
                                 TCP socket in the specified time period.
  @retval EFI_INVALID_PARAMETER  One or more parameters are invalid.
  @retval EFI_UNSUPPORTED        One or more of the control options are not
                                 supported in the implementation.
  @retval Others                 Other errors as indicated.

**/
EFI_STATUS
EFIAPI
TcpIoConnect (
  IN OUT TCP_IO             *TcpIo,
  IN     EFI_EVENT          Timeout        OPTIONAL
  );

/**
  Accept the incomding request from the other endpoint of the TCP socket.

  @param[in, out]  TcpIo     The TcpIo wrapping the TCP socket.
  @param[in]       Timeout   The time to wait for connection done. Set to NULL for infinite wait.


  @retval EFI_SUCCESS            Connect to the other endpoint of the TCP socket
                                 successfully.
  @retval EFI_INVALID_PARAMETER  One or more parameters are invalid.
  @retval EFI_UNSUPPORTED        One or more of the control options are not
                                 supported in the implementation.

  @retval EFI_TIMEOUT            Failed to connect to the other endpoint of the
                                 TCP socket in the specified time period.
  @retval Others                 Other errors as indicated.

**/
EFI_STATUS
EFIAPI
TcpIoAccept (
  IN OUT TCP_IO             *TcpIo,
  IN     EFI_EVENT          Timeout        OPTIONAL
  );

/**
  Reset the socket.

  @param[in, out]  TcpIo The TcpIo wrapping the TCP socket.

**/
VOID
EFIAPI
TcpIoReset (
  IN OUT TCP_IO             *TcpIo
  );

/**
  Transmit the Packet to the other endpoint of the socket.

  @param[in]   TcpIo           The TcpIo wrapping the TCP socket.
  @param[in]   Packet          The packet to transmit.

  @retval EFI_SUCCESS            The packet is transmitted.
  @retval EFI_INVALID_PARAMETER  One or more parameters are invalid.
  @retval EFI_UNSUPPORTED        One or more of the control options are not
                                 supported in the implementation.
  @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory.
  @retval EFI_DEVICE_ERROR       An unexpected network or system error occurred.
  @retval Others                 Other errors as indicated.

**/
EFI_STATUS
EFIAPI
TcpIoTransmit (
  IN TCP_IO                 *TcpIo,
  IN NET_BUF                *Packet
  );

/**
  Receive data from the socket.

  @param[in, out]  TcpIo       The TcpIo which wraps the socket to be destroyed.
  @param[in]       Packet      The buffer to hold the data copy from the socket rx buffer.
  @param[in]       AsyncMode   Is this receive asynchronous or not.
  @param[in]       Timeout     The time to wait for receiving the amount of data the Packet
                               can hold. Set to NULL for infinite wait.

  @retval EFI_SUCCESS            The required amount of data is received from the socket.
  @retval EFI_INVALID_PARAMETER  One or more parameters are invalid.
  @retval EFI_DEVICE_ERROR       An unexpected network or system error occurred.
  @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory.
  @retval EFI_TIMEOUT            Failed to receive the required amount of data in the
                                 specified time period.
  @retval Others                 Other errors as indicated.

**/
EFI_STATUS
EFIAPI
TcpIoReceive (
  IN OUT TCP_IO             *TcpIo,
  IN     NET_BUF            *Packet,
  IN     BOOLEAN            AsyncMode,
  IN     EFI_EVENT          Timeout       OPTIONAL
  );

#endif

