/** @file
  Interface function of the Socket.

  Copyright (c) 2009 - 2012, 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;

  ASSERT ((Sock != NULL) && (Sock->ProtoHandler != NULL));

  if (Sock->InDestroy) {
    return EFI_SUCCESS;
  }

  Sock->InDestroy = TRUE;

  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;

  //
  // 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)
      );

    SockDestroy (Sock);
    return NULL;
  }
  //
  // 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)
      );

    SockDestroy (Sock);
    Sock = NULL;
  }

  return Sock;
}

/**
  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_INFO,
        "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) {
    Status = SockProcessRcvToken (Sock, RcvToken);

    if (EFI_ERROR (Status)) {
      goto Exit;
    }

    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;
}

/**
  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);
}

/**
  Configure the low level protocol to join a multicast group for
  this socket's connection.

  @param[in]  Sock             Pointer to the socket of the connection to join the
                               specific multicast group.
  @param[in]  GroupInfo        Pointer to the multicast group info.

  @retval EFI_SUCCESS          The configuration completed successfully.
  @retval EFI_ACCESS_DENIED    Failed to get the lock to access the socket.
  @retval EFI_NOT_STARTED      The socket is not configured.

**/
EFI_STATUS
SockGroup (
  IN SOCKET *Sock,
  IN VOID   *GroupInfo
  )
{
  EFI_STATUS  Status;

  Status = EfiAcquireLockOrFail (&(Sock->Lock));

  if (EFI_ERROR (Status)) {

    DEBUG (
      (EFI_D_ERROR,
      "SockGroup: Get the access for socket failed with %r",
      Status)
      );

    return EFI_ACCESS_DENIED;
  }

  if (SOCK_IS_UNCONFIGURED (Sock)) {
    Status = EFI_NOT_STARTED;
    goto Exit;
  }

  Status = Sock->ProtoHandler (Sock, SOCK_GROUP, GroupInfo);

Exit:
  EfiReleaseLock (&(Sock->Lock));
  return Status;
}

/**
  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;
}

