/** @file
  Interface function of the Socket.

  Copyright (c) 2009 - 2018, 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 "SockImpl.h"

/**
  Check whether the Event is in the List.

  @param[in]  List             Pointer to the token list to be searched.
  @param[in]  Event            The event to be checked.

  @retval  TRUE                The specific Event exists in the List.
  @retval  FALSE               The specific Event is not in the List.

**/
BOOLEAN
SockTokenExistedInList (
  IN LIST_ENTRY     *List,
  IN EFI_EVENT      Event
  )
{
  LIST_ENTRY      *ListEntry;
  SOCK_TOKEN      *SockToken;

  NET_LIST_FOR_EACH (ListEntry, List) {
    SockToken = NET_LIST_USER_STRUCT (
                  ListEntry,
                  SOCK_TOKEN,
                  TokenList
                  );

    if (Event == SockToken->Token->Event) {
      return TRUE;
    }
  }

  return FALSE;
}

/**
  Call SockTokenExistedInList() to check whether the Event is
  in the related socket's lists.

  @param[in]  Sock             Pointer to the instance's socket.
  @param[in]  Event            The event to be checked.

  @retval  TRUE                The Event exists in related socket's lists.
  @retval  FALSE               The Event is not in related socket's lists.

**/
BOOLEAN
SockTokenExisted (
  IN SOCKET    *Sock,
  IN EFI_EVENT Event
  )
{

  if (SockTokenExistedInList (&Sock->SndTokenList, Event) ||
      SockTokenExistedInList (&Sock->ProcessingSndTokenList, Event) ||
      SockTokenExistedInList (&Sock->RcvTokenList, Event) ||
      SockTokenExistedInList (&Sock->ListenTokenList, Event)
        ) {

    return TRUE;
  }

  if ((Sock->ConnectionToken != NULL) && (Sock->ConnectionToken->Event == Event)) {

    return TRUE;
  }

  if ((Sock->CloseToken != NULL) && (Sock->CloseToken->Event == Event)) {
    return TRUE;
  }

  return FALSE;
}

/**
  Buffer a token into the specific list of the socket Sock.

  @param[in]  Sock             Pointer to the instance's socket.
  @param[in]  List             Pointer to the list to store the token.
  @param[in]  Token            Pointer to the token to be buffered.
  @param[in]  DataLen          The data length of the buffer contained in Token.

  @return Pointer to the token that wraps Token. If NULL, an error condition occurred.

**/
SOCK_TOKEN *
SockBufferToken (
  IN SOCKET         *Sock,
  IN LIST_ENTRY     *List,
  IN VOID           *Token,
  IN UINT32         DataLen
  )
{
  SOCK_TOKEN  *SockToken;

  SockToken = AllocateZeroPool (sizeof (SOCK_TOKEN));
  if (NULL == SockToken) {

    DEBUG (
      (EFI_D_ERROR,
      "SockBufferIOToken: No Memory to allocate SockToken\n")
      );

    return NULL;
  }

  SockToken->Sock           = Sock;
  SockToken->Token          = (SOCK_COMPLETION_TOKEN *) Token;
  SockToken->RemainDataLen  = DataLen;
  InsertTailList (List, &SockToken->TokenList);

  return SockToken;
}

/**
  Destroy the socket Sock and its associated protocol control block.

  @param[in, out]  Sock                 The socket to be destroyed.

  @retval EFI_SUCCESS          The socket Sock was destroyed successfully.
  @retval EFI_ACCESS_DENIED    Failed to get the lock to access the socket.

**/
EFI_STATUS
SockDestroyChild (
  IN OUT SOCKET *Sock
  )
{
  EFI_STATUS       Status;
  TCP_PROTO_DATA   *ProtoData;
  TCP_CB           *Tcb;
  EFI_GUID         *IpProtocolGuid;
  EFI_GUID         *TcpProtocolGuid;
  VOID             *SockProtocol;

  ASSERT ((Sock != NULL) && (Sock->ProtoHandler != NULL));

  if (Sock->InDestroy) {
    return EFI_SUCCESS;
  }

  Sock->InDestroy = TRUE;

  if (Sock->IpVersion == IP_VERSION_4) {
    IpProtocolGuid = &gEfiIp4ProtocolGuid;
    TcpProtocolGuid = &gEfiTcp4ProtocolGuid;
  } else {
    IpProtocolGuid = &gEfiIp6ProtocolGuid;
    TcpProtocolGuid = &gEfiTcp6ProtocolGuid;
  }
  ProtoData = (TCP_PROTO_DATA *) Sock->ProtoReserved;
  Tcb       = ProtoData->TcpPcb;

  ASSERT (Tcb != NULL);

  //
  // Close the IP protocol.
  //
  gBS->CloseProtocol (
         Tcb->IpInfo->ChildHandle,
         IpProtocolGuid,
         ProtoData->TcpService->IpIo->Image,
         Sock->SockHandle
         );

  if (Sock->DestroyCallback != NULL) {
    Sock->DestroyCallback (Sock, Sock->Context);
  }

  //
  // Retrieve the protocol installed on this sock
  //
  Status = gBS->OpenProtocol (
                  Sock->SockHandle,
                  TcpProtocolGuid,
                  &SockProtocol,
                  Sock->DriverBinding,
                  Sock->SockHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {

    DEBUG (
      (EFI_D_ERROR,
      "SockDestroyChild: Open protocol installed on socket failed with %r\n",
      Status)
      );
  }

  //
  // Uninstall the protocol installed on this sock
  //
  gBS->UninstallMultipleProtocolInterfaces (
        Sock->SockHandle,
        TcpProtocolGuid,
        SockProtocol,
        NULL
        );


  Status            = EfiAcquireLockOrFail (&(Sock->Lock));
  if (EFI_ERROR (Status)) {

    DEBUG (
      (EFI_D_ERROR,
      "SockDestroyChild: Get the lock to access socket failed with %r\n",
      Status)
      );

    return EFI_ACCESS_DENIED;
  }

  //
  // force protocol layer to detach the PCB
  //
  Status = Sock->ProtoHandler (Sock, SOCK_DETACH, NULL);

  if (EFI_ERROR (Status)) {

    DEBUG (
      (EFI_D_ERROR,
      "SockDestroyChild: Protocol detach socket failed with %r\n",
      Status)
      );

    Sock->InDestroy = FALSE;
  } else if (SOCK_IS_CONFIGURED (Sock)) {

    SockConnFlush (Sock);
    SockSetState (Sock, SO_CLOSED);

    Sock->ConfigureState = SO_UNCONFIGURED;
  }

  EfiReleaseLock (&(Sock->Lock));

  if (EFI_ERROR (Status)) {
    return Status;
  }

  SockDestroy (Sock);
  return EFI_SUCCESS;
}

/**
  Create a socket and its associated protocol control block
  with the intial data SockInitData and protocol specific
  data ProtoData.

  @param[in]  SockInitData         Inital data to setting the socket.

  @return Pointer to the newly created socket. If NULL, an error condition occured.

**/
SOCKET *
SockCreateChild (
  IN SOCK_INIT_DATA *SockInitData
  )
{
  SOCKET      *Sock;
  EFI_STATUS  Status;
  VOID        *SockProtocol;
  EFI_GUID    *TcpProtocolGuid;

  //
  // create a new socket
  //
  Sock = SockCreate (SockInitData);
  if (NULL == Sock) {

    DEBUG (
      (EFI_D_ERROR,
      "SockCreateChild: No resource to create a new socket\n")
      );

    return NULL;
  }

  Status = EfiAcquireLockOrFail (&(Sock->Lock));
  if (EFI_ERROR (Status)) {

    DEBUG (
      (EFI_D_ERROR,
      "SockCreateChild: Get the lock to access socket failed with %r\n",
      Status)
      );
    goto ERROR;
  }
  //
  // inform the protocol layer to attach the socket
  // with a new protocol control block
  //
  Status = Sock->ProtoHandler (Sock, SOCK_ATTACH, NULL);
  EfiReleaseLock (&(Sock->Lock));
  if (EFI_ERROR (Status)) {

    DEBUG (
      (EFI_D_ERROR,
      "SockCreateChild: Protocol failed to attach a socket with %r\n",
      Status)
      );
    goto ERROR;
  }

  return Sock;

ERROR:

  if (Sock->DestroyCallback != NULL) {
    Sock->DestroyCallback (Sock, Sock->Context);
  }

  if (Sock->IpVersion == IP_VERSION_4) {
    TcpProtocolGuid = &gEfiTcp4ProtocolGuid;
  } else {
    TcpProtocolGuid = &gEfiTcp6ProtocolGuid;
  }

  gBS->OpenProtocol (
         Sock->SockHandle,
         TcpProtocolGuid,
         &SockProtocol,
         Sock->DriverBinding,
         Sock->SockHandle,
         EFI_OPEN_PROTOCOL_GET_PROTOCOL
         );
  //
  // Uninstall the protocol installed on this sock
  //
  gBS->UninstallMultipleProtocolInterfaces (
        Sock->SockHandle,
        TcpProtocolGuid,
        SockProtocol,
        NULL
        );
   SockDestroy (Sock);
   return NULL;
}

/**
  Configure the specific socket Sock using configuration data ConfigData.

  @param[in]  Sock             Pointer to the socket to be configured.
  @param[in]  ConfigData       Pointer to the configuration data.

  @retval EFI_SUCCESS          The socket configured successfully.
  @retval EFI_ACCESS_DENIED    Failed to get the lock to access the socket, or the
                               socket is already configured.

**/
EFI_STATUS
SockConfigure (
  IN SOCKET *Sock,
  IN VOID   *ConfigData
  )
{
  EFI_STATUS  Status;

  Status = EfiAcquireLockOrFail (&(Sock->Lock));
  if (EFI_ERROR (Status)) {

    DEBUG (
      (EFI_D_ERROR,
      "SockConfigure: Get the access for socket failed with %r",
      Status)
      );

    return EFI_ACCESS_DENIED;
  }

  if (SOCK_IS_CONFIGURED (Sock)) {
    Status = EFI_ACCESS_DENIED;
    goto OnExit;
  }

  ASSERT (Sock->State == SO_CLOSED);

  Status = Sock->ProtoHandler (Sock, SOCK_CONFIGURE, ConfigData);

OnExit:
  EfiReleaseLock (&(Sock->Lock));

  return Status;
}

/**
  Initiate a connection establishment process.

  @param[in]  Sock             Pointer to the socket to initiate the initate the
                               connection.
  @param[in]  Token            Pointer to the token used for the connection
                               operation.

  @retval EFI_SUCCESS          The connection initialized successfully.
  @retval EFI_ACCESS_DENIED    Failed to get the lock to access the socket, or the
                               socket is closed, or the socket is not configured to
                               be an active one, or the token is already in one of
                               this socket's lists.
  @retval EFI_NO_MAPPING       The IP address configuration operation is not
                               finished.
  @retval EFI_NOT_STARTED      The socket is not configured.

**/
EFI_STATUS
SockConnect (
  IN SOCKET *Sock,
  IN VOID   *Token
  )
{
  EFI_STATUS  Status;
  EFI_EVENT   Event;

  Status = EfiAcquireLockOrFail (&(Sock->Lock));
  if (EFI_ERROR (Status)) {

    DEBUG (
      (EFI_D_ERROR,
      "SockConnect: Get the access for socket failed with %r",
      Status)
      );

    return EFI_ACCESS_DENIED;
  }

  if (SOCK_IS_NO_MAPPING (Sock)) {
    Status = EFI_NO_MAPPING;
    goto OnExit;
  }

  if (SOCK_IS_UNCONFIGURED (Sock)) {

    Status = EFI_NOT_STARTED;
    goto OnExit;
  }

  if (!SOCK_IS_CLOSED (Sock) || !SOCK_IS_CONFIGURED_ACTIVE (Sock)) {

    Status = EFI_ACCESS_DENIED;
    goto OnExit;
  }

  Event = ((SOCK_COMPLETION_TOKEN *) Token)->Event;

  if (SockTokenExisted (Sock, Event)) {

    Status = EFI_ACCESS_DENIED;
    goto OnExit;
  }

  Sock->ConnectionToken = (SOCK_COMPLETION_TOKEN *) Token;
  SockSetState (Sock, SO_CONNECTING);
  Status = Sock->ProtoHandler (Sock, SOCK_CONNECT, NULL);

OnExit:
  EfiReleaseLock (&(Sock->Lock));
  return Status;
}

/**
  Issue a listen token to get an existed connected network instance
  or wait for a connection if there is none.

  @param[in]  Sock             Pointer to the socket to accept connections.
  @param[in]  Token            The token to accept a connection.

  @retval EFI_SUCCESS          Either a connection is accpeted or the Token is
                               buffered for further acception.
  @retval EFI_ACCESS_DENIED    Failed to get the lock to access the socket, or the
                               socket is closed, or the socket is not configured to
                               be a passive one, or the token is already in one of
                               this socket's lists.
  @retval EFI_NO_MAPPING       The IP address configuration operation is not
                               finished.
  @retval EFI_NOT_STARTED      The socket is not configured.
  @retval EFI_OUT_OF_RESOURCE  Failed to buffer the Token due to memory limits.

**/
EFI_STATUS
SockAccept (
  IN SOCKET *Sock,
  IN VOID   *Token
  )
{
  EFI_TCP4_LISTEN_TOKEN *ListenToken;
  LIST_ENTRY            *ListEntry;
  EFI_STATUS            Status;
  SOCKET                *Socket;
  EFI_EVENT             Event;

  ASSERT (SockStream == Sock->Type);

  Status = EfiAcquireLockOrFail (&(Sock->Lock));
  if (EFI_ERROR (Status)) {

    DEBUG (
      (EFI_D_ERROR,
      "SockAccept: Get the access for socket failed with %r",
      Status)
      );

    return EFI_ACCESS_DENIED;
  }

  if (SOCK_IS_NO_MAPPING (Sock)) {
    Status = EFI_NO_MAPPING;
    goto Exit;
  }

  if (SOCK_IS_UNCONFIGURED (Sock)) {

    Status = EFI_NOT_STARTED;
    goto Exit;
  }

  if (!SOCK_IS_LISTENING (Sock)) {

    Status = EFI_ACCESS_DENIED;
    goto Exit;
  }

  Event = ((SOCK_COMPLETION_TOKEN *) Token)->Event;

  if (SockTokenExisted (Sock, Event)) {

    Status = EFI_ACCESS_DENIED;
    goto Exit;
  }

  ListenToken = (EFI_TCP4_LISTEN_TOKEN *) Token;

  //
  // Check if a connection has already in this Sock->ConnectionList
  //
  NET_LIST_FOR_EACH (ListEntry, &Sock->ConnectionList) {

    Socket = NET_LIST_USER_STRUCT (ListEntry, SOCKET, ConnectionList);

    if (SOCK_IS_CONNECTED (Socket)) {
      ListenToken->NewChildHandle = Socket->SockHandle;
      SIGNAL_TOKEN (&(ListenToken->CompletionToken), EFI_SUCCESS);

      RemoveEntryList (ListEntry);

      ASSERT (Socket->Parent != NULL);

      Socket->Parent->ConnCnt--;

      DEBUG (
        (EFI_D_NET,
        "SockAccept: Accept a socket, now conncount is %d",
        Socket->Parent->ConnCnt)
        );
      Socket->Parent = NULL;

      goto Exit;
    }
  }

  //
  // Buffer this token for latter incoming connection request
  //
  if (NULL == SockBufferToken (Sock, &(Sock->ListenTokenList), Token, 0)) {

    Status = EFI_OUT_OF_RESOURCES;
  }

Exit:
  EfiReleaseLock (&(Sock->Lock));

  return Status;
}

/**
  Issue a token with data to the socket to send out.

  @param[in]  Sock             Pointer to the socket to process the token with
                               data.
  @param[in]  Token            The token with data that needs to send out.

  @retval EFI_SUCCESS          The token processed successfully.
  @retval EFI_ACCESS_DENIED    Failed to get the lock to access the socket, or the
                               socket is closed, or the socket is not in a
                               synchronized state , or the token is already in one
                               of this socket's lists.
  @retval EFI_NO_MAPPING       The IP address configuration operation is not
                               finished.
  @retval EFI_NOT_STARTED      The socket is not configured.
  @retval EFI_OUT_OF_RESOURCE  Failed to buffer the token due to memory limits.

**/
EFI_STATUS
SockSend (
  IN SOCKET *Sock,
  IN VOID   *Token
  )
{
  SOCK_IO_TOKEN           *SndToken;
  EFI_EVENT               Event;
  UINT32                  FreeSpace;
  EFI_TCP4_TRANSMIT_DATA  *TxData;
  EFI_STATUS              Status;
  SOCK_TOKEN              *SockToken;
  UINT32                  DataLen;

  ASSERT (SockStream == Sock->Type);

  Status = EfiAcquireLockOrFail (&(Sock->Lock));
  if (EFI_ERROR (Status)) {

    DEBUG (
      (EFI_D_ERROR,
      "SockSend: Get the access for socket failed with %r",
      Status)
      );

    return EFI_ACCESS_DENIED;
  }

  if (SOCK_IS_NO_MAPPING (Sock)) {
    Status = EFI_NO_MAPPING;
    goto Exit;
  }

  SndToken  = (SOCK_IO_TOKEN *) Token;
  TxData    = (EFI_TCP4_TRANSMIT_DATA *) SndToken->Packet.TxData;

  if (SOCK_IS_UNCONFIGURED (Sock)) {
    Status = EFI_NOT_STARTED;
    goto Exit;
  }

  if (!(SOCK_IS_CONNECTING (Sock) || SOCK_IS_CONNECTED (Sock))) {

    Status = EFI_ACCESS_DENIED;
    goto Exit;
  }

  //
  // check if a token is already in the token buffer
  //
  Event = SndToken->Token.Event;

  if (SockTokenExisted (Sock, Event)) {
    Status = EFI_ACCESS_DENIED;
    goto Exit;
  }

  DataLen = TxData->DataLength;

  //
  // process this sending token now or buffer it only?
  //
  FreeSpace = SockGetFreeSpace (Sock, SOCK_SND_BUF);

  if ((FreeSpace < Sock->SndBuffer.LowWater) || !SOCK_IS_CONNECTED (Sock)) {

    SockToken = SockBufferToken (
                  Sock,
                  &Sock->SndTokenList,
                  SndToken,
                  DataLen
                  );

    if (NULL == SockToken) {
      Status = EFI_OUT_OF_RESOURCES;
    }
  } else {

    SockToken = SockBufferToken (
                  Sock,
                  &Sock->ProcessingSndTokenList,
                  SndToken,
                  DataLen
                  );

    if (NULL == SockToken) {
      DEBUG (
        (EFI_D_ERROR,
        "SockSend: Failed to buffer IO token into socket processing SndToken List\n",
        Status)
        );

      Status = EFI_OUT_OF_RESOURCES;
      goto Exit;
    }

    Status = SockProcessTcpSndData (Sock, TxData);

    if (EFI_ERROR (Status)) {
      DEBUG (
        (EFI_D_ERROR,
        "SockSend: Failed to process Snd Data\n",
        Status)
        );

      RemoveEntryList (&(SockToken->TokenList));
      FreePool (SockToken);
    }
  }

Exit:
  EfiReleaseLock (&(Sock->Lock));
  return Status;
}

/**
  Issue a token to get data from the socket.

  @param[in]  Sock             Pointer to the socket to get data from.
  @param[in]  Token            The token to store the received data from the
                               socket.

  @retval EFI_SUCCESS          The token processed successfully.
  @retval EFI_ACCESS_DENIED    Failed to get the lock to access the socket, or the
                               socket is closed, or the socket is not in a
                               synchronized state , or the token is already in one
                               of this socket's lists.
  @retval EFI_NO_MAPPING       The IP address configuration operation is not
                               finished.
  @retval EFI_NOT_STARTED      The socket is not configured.
  @retval EFI_CONNECTION_FIN   The connection is closed and there is no more data.
  @retval EFI_OUT_OF_RESOURCE  Failed to buffer the token due to memory limit.

**/
EFI_STATUS
SockRcv (
  IN SOCKET *Sock,
  IN VOID   *Token
  )
{
  SOCK_IO_TOKEN *RcvToken;
  UINT32        RcvdBytes;
  EFI_STATUS    Status;
  EFI_EVENT     Event;

  ASSERT (SockStream == Sock->Type);

  Status = EfiAcquireLockOrFail (&(Sock->Lock));
  if (EFI_ERROR (Status)) {

    DEBUG (
      (EFI_D_ERROR,
      "SockRcv: Get the access for socket failed with %r",
      Status)
      );

    return EFI_ACCESS_DENIED;
  }

  if (SOCK_IS_NO_MAPPING (Sock)) {

    Status = EFI_NO_MAPPING;
    goto Exit;
  }

  if (SOCK_IS_UNCONFIGURED (Sock)) {

    Status = EFI_NOT_STARTED;
    goto Exit;
  }

  if (!(SOCK_IS_CONNECTED (Sock) || SOCK_IS_CONNECTING (Sock))) {

    Status = EFI_ACCESS_DENIED;
    goto Exit;
  }

  RcvToken = (SOCK_IO_TOKEN *) Token;

  //
  // check if a token is already in the token buffer of this socket
  //
  Event = RcvToken->Token.Event;
  if (SockTokenExisted (Sock, Event)) {
    Status = EFI_ACCESS_DENIED;
    goto Exit;
  }

  RcvToken  = (SOCK_IO_TOKEN *) Token;
  RcvdBytes = GET_RCV_DATASIZE (Sock);

  //
  // check whether an error has happened before
  //
  if (EFI_ABORTED != Sock->SockError) {

    SIGNAL_TOKEN (&(RcvToken->Token), Sock->SockError);
    Sock->SockError = EFI_ABORTED;
    goto Exit;
  }

  //
  // check whether can not receive and there is no any
  // data buffered in Sock->RcvBuffer
  //
  if (SOCK_IS_NO_MORE_DATA (Sock) && (0 == RcvdBytes)) {

    Status = EFI_CONNECTION_FIN;
    goto Exit;
  }

  if (RcvdBytes != 0) {
    SockProcessRcvToken (Sock, RcvToken);

    Status = Sock->ProtoHandler (Sock, SOCK_CONSUMED, NULL);
  } else {

    if (NULL == SockBufferToken (Sock, &Sock->RcvTokenList, RcvToken, 0)) {
      Status = EFI_OUT_OF_RESOURCES;
    }
  }

Exit:
  EfiReleaseLock (&(Sock->Lock));
  return Status;
}

/**
  Reset the socket and its associated protocol control block.

  @param[in, out]  Sock        Pointer to the socket to be flushed.

  @retval EFI_SUCCESS          The socket is flushed successfully.
  @retval EFI_ACCESS_DENIED    Failed to get the lock to access the socket.

**/
EFI_STATUS
SockFlush (
  IN OUT SOCKET *Sock
  )
{
  EFI_STATUS  Status;

  ASSERT (SockStream == Sock->Type);

  Status = EfiAcquireLockOrFail (&(Sock->Lock));
  if (EFI_ERROR (Status)) {

    DEBUG (
      (EFI_D_ERROR,
      "SockFlush: Get the access for socket failed with %r",
      Status)
      );

    return EFI_ACCESS_DENIED;
  }

  if (!SOCK_IS_CONFIGURED (Sock)) {

    Status = EFI_ACCESS_DENIED;
    goto Exit;
  }

  Status = Sock->ProtoHandler (Sock, SOCK_FLUSH, NULL);
  if (EFI_ERROR (Status)) {

    DEBUG (
      (EFI_D_ERROR,
      "SockFlush: Protocol failed handling SOCK_FLUSH with %r",
      Status)
      );

    goto Exit;
  }

  SOCK_ERROR (Sock, EFI_ABORTED);
  SockConnFlush (Sock);
  SockSetState (Sock, SO_CLOSED);

  Sock->ConfigureState = SO_UNCONFIGURED;

Exit:
  EfiReleaseLock (&(Sock->Lock));
  return Status;
}

/**
  Close or abort the socket associated connection.

  @param[in, out]  Sock        Pointer to the socket of the connection to close
                               or abort.
  @param[in]  Token            The token for a close operation.
  @param[in]  OnAbort          TRUE for aborting the connection; FALSE to close it.

  @retval EFI_SUCCESS          The close or abort operation initialized
                               successfully.
  @retval EFI_ACCESS_DENIED    Failed to get the lock to access the socket, or the
                               socket is closed, or the socket is not in a
                               synchronized state , or the token is already in one
                               of this socket's lists.
  @retval EFI_NO_MAPPING       The IP address configuration operation is not
                               finished.
  @retval EFI_NOT_STARTED      The socket is not configured.

**/
EFI_STATUS
SockClose (
  IN OUT SOCKET  *Sock,
  IN     VOID    *Token,
  IN     BOOLEAN OnAbort
  )
{
  EFI_STATUS  Status;
  EFI_EVENT   Event;

  ASSERT (SockStream == Sock->Type);

  Status = EfiAcquireLockOrFail (&(Sock->Lock));
  if (EFI_ERROR (Status)) {
    DEBUG (
      (EFI_D_ERROR,
      "SockClose: Get the access for socket failed with %r",
      Status)
      );

    return EFI_ACCESS_DENIED;
  }

  if (SOCK_IS_NO_MAPPING (Sock)) {
    Status = EFI_NO_MAPPING;
    goto Exit;
  }

  if (SOCK_IS_UNCONFIGURED (Sock)) {
    Status = EFI_NOT_STARTED;
    goto Exit;
  }

  if (SOCK_IS_DISCONNECTING (Sock)) {
    Status = EFI_ACCESS_DENIED;
    goto Exit;
  }

  Event = ((SOCK_COMPLETION_TOKEN *) Token)->Event;

  if (SockTokenExisted (Sock, Event)) {
    Status = EFI_ACCESS_DENIED;
    goto Exit;
  }

  Sock->CloseToken = Token;
  SockSetState (Sock, SO_DISCONNECTING);

  if (OnAbort) {
    Status = Sock->ProtoHandler (Sock, SOCK_ABORT, NULL);
  } else {
    Status = Sock->ProtoHandler (Sock, SOCK_CLOSE, NULL);
  }

Exit:
  EfiReleaseLock (&(Sock->Lock));
  return Status;
}

/**
  Abort the socket associated connection, listen, transmission or receive request.

  @param[in, out]  Sock        Pointer to the socket to abort.
  @param[in]       Token       Pointer to a token that has been issued by
                               Connect(), Accept(), Transmit() or Receive(). If
                               NULL, all pending tokens issued by the four
                               functions listed above will be aborted.

  @retval EFI_UNSUPPORTED      The operation is not supported in the current
                               implementation.
**/
EFI_STATUS
SockCancel (
  IN OUT SOCKET  *Sock,
  IN     VOID    *Token
  )
{
  EFI_STATUS     Status;

  Status    = EFI_SUCCESS;

  ASSERT (SockStream == Sock->Type);

  Status = EfiAcquireLockOrFail (&(Sock->Lock));
  if (EFI_ERROR (Status)) {
    DEBUG (
      (EFI_D_ERROR,
      "SockCancel: Get the access for socket failed with %r",
      Status)
      );

    return EFI_ACCESS_DENIED;
  }

  if (SOCK_IS_UNCONFIGURED (Sock)) {
    Status = EFI_NOT_STARTED;
    goto Exit;
  }

  //
  // 1. Check ConnectionToken.
  //
  if (Token == NULL || (SOCK_COMPLETION_TOKEN *) Token == Sock->ConnectionToken) {
    if (Sock->ConnectionToken != NULL) {
      SIGNAL_TOKEN (Sock->ConnectionToken, EFI_ABORTED);
      Sock->ConnectionToken = NULL;
    }

    if (Token != NULL) {
      Status = EFI_SUCCESS;
      goto Exit;
    }
  }

  //
  // 2. Check ListenTokenList.
  //
  Status = SockCancelToken (Token, &Sock->ListenTokenList);
  if (Token != NULL && !EFI_ERROR (Status)) {
    goto Exit;
  }

  //
  // 3. Check RcvTokenList.
  //
  Status = SockCancelToken (Token, &Sock->RcvTokenList);
  if (Token != NULL && !EFI_ERROR (Status)) {
    goto Exit;
  }

  //
  // 4. Check SndTokenList.
  //
  Status = SockCancelToken (Token, &Sock->SndTokenList);
  if (Token != NULL && !EFI_ERROR (Status)) {
    goto Exit;
  }

  //
  // 5. Check ProcessingSndTokenList.
  //
  Status = SockCancelToken (Token, &Sock->ProcessingSndTokenList);

Exit:
  EfiReleaseLock (&(Sock->Lock));
  return Status;
}


/**
  Get the mode data of the low layer protocol.

  @param[in]       Sock        Pointer to the socket to get mode data from.
  @param[in, out]  Mode        Pointer to the data to store the low layer mode
                               information.

  @retval EFI_SUCCESS          The mode data was obtained successfully.
  @retval EFI_NOT_STARTED      The socket is not configured.

**/
EFI_STATUS
SockGetMode (
  IN     SOCKET *Sock,
  IN OUT VOID   *Mode
  )
{
  return Sock->ProtoHandler (Sock, SOCK_MODE, Mode);
}

/**
  Add or remove route information in IP route table associated
  with this socket.

  @param[in]  Sock             Pointer to the socket associated with the IP route
                               table to operate on.
  @param[in]  RouteInfo        Pointer to the route information to be processed.

  @retval EFI_SUCCESS          The route table updated successfully.
  @retval EFI_ACCESS_DENIED    Failed to get the lock to access the socket.
  @retval EFI_NO_MAPPING       The IP address configuration operation is  not
                               finished.
  @retval EFI_NOT_STARTED      The socket is not configured.

**/
EFI_STATUS
SockRoute (
  IN SOCKET    *Sock,
  IN VOID      *RouteInfo
  )
{
  EFI_STATUS  Status;

  Status = EfiAcquireLockOrFail (&(Sock->Lock));
  if (EFI_ERROR (Status)) {
    DEBUG (
      (EFI_D_ERROR,
      "SockRoute: Get the access for socket failed with %r",
      Status)
      );

    return EFI_ACCESS_DENIED;
  }

  if (SOCK_IS_NO_MAPPING (Sock)) {
    Status = EFI_NO_MAPPING;
    goto Exit;
  }

  if (SOCK_IS_UNCONFIGURED (Sock)) {
    Status = EFI_NOT_STARTED;
    goto Exit;
  }

  Status = Sock->ProtoHandler (Sock, SOCK_ROUTE, RouteInfo);

Exit:
  EfiReleaseLock (&(Sock->Lock));
  return Status;
}

