sockinterface.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,058 行 · 第 1/2 页

C
1,058
字号
  // Buffer this token for latter incoming connection request
  //
  if (NULL == SockBufferToken (Sock, &(Sock->ListenTokenList), Token, 0)) {

    Status = EFI_OUT_OF_RESOURCES;
  }

Exit:
  NET_UNLOCK (&(Sock->Lock));

  return Status;
}

EFI_STATUS
SockSend (
  IN SOCKET *Sock,
  IN VOID   *Token
  )
/*++

Routine Description:

  Issue a token with data to the socket to send out.

Arguments:

  Sock  - Pointer to the socket to process the token with data.
  Token - The token with data that needs to send out.

Returns:

  EFI_SUCCESS       - The token is processed successfully.
  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.
  EFI_NO_MAPPING    - The IP address configuration operation is not finished.
  EFI_NOT_STARTED   - The socket is not configured.
  EFI_OUT_OF_RESOURCE - Failed to buffer the token due to memory limit.

--*/
{
  SOCK_IO_TOKEN           *SndToken;
  EFI_EVENT               Event;
  UINT32                  FreeSpace;
  EFI_TCP4_TRANSMIT_DATA  *TxData;
  EFI_STATUS              Status;
  SOCK_TOKEN              *SockToken;
  UINT32                  DataLen;

  ASSERT (SOCK_STREAM == Sock->Type);

  Status = NET_TRYLOCK (&(Sock->Lock));
  if (EFI_ERROR (Status)) {

    SOCK_DEBUG_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) {
      SOCK_DEBUG_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)) {
      SOCK_DEBUG_ERROR (("SockSend: Failed to process "
        "Snd Data\n", Status));

      NetListRemoveEntry (&(SockToken->TokenList));
      NetFreePool (SockToken);
    }
  }

Exit:
  NET_UNLOCK (&(Sock->Lock));
  return Status;
}

EFI_STATUS
SockRcv (
  IN SOCKET *Sock,
  IN VOID   *Token
  )
/*++

Routine Description:

  Issue a token to get data from the socket.

Arguments:

  Sock  - Pointer to the socket to get data from.
  Token - The token to store the received data from the socket.

Returns:

  EFI_SUCCESS       - The token is processed successfully.
  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.
  EFI_NO_MAPPING    - The IP address configuration operation is not finished.
  EFI_NOT_STARTED   - The socket is not configured.
  EFI_CONNECTION_FIN  - The connection is closed and there is no more data.
  EFI_OUT_OF_RESOURCE - Failed to buffer the token due to memory limit.

--*/
{
  SOCK_IO_TOKEN *RcvToken;
  UINT32        RcvdBytes;
  EFI_STATUS    Status;
  EFI_EVENT     Event;

  ASSERT (SOCK_STREAM == Sock->Type);

  Status = NET_TRYLOCK (&(Sock->Lock));
  if (EFI_ERROR (Status)) {

    SOCK_DEBUG_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:
  NET_UNLOCK (&(Sock->Lock));
  return Status;
}

EFI_STATUS
SockFlush (
  IN SOCKET *Sock
  )
/*++

Routine Description:

  Reset the socket and its associated protocol control block.

Arguments:

  Sock  - Pointer to the socket to be flushed.

Returns:

  EFI_SUCCESS       - The socket is flushed successfully.
  EFI_ACCESS_DENIED - Failed to get the lock to access the socket.

--*/
{
  EFI_STATUS  Status;

  ASSERT (SOCK_STREAM == Sock->Type);

  Status = NET_TRYLOCK (&(Sock->Lock));
  if (EFI_ERROR (Status)) {

    SOCK_DEBUG_ERROR (("SockFlush: Get the access for socket"
      " failed with %r", Status));

    return EFI_ACCESS_DENIED;
  }

  if (!SOCK_IS_CONFIGURED (Sock)) {
    goto Exit;
  }

  Status = Sock->ProtoHandler (Sock, SOCK_FLUSH, NULL);
  if (EFI_ERROR (Status)) {

    SOCK_DEBUG_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:
  NET_UNLOCK (&(Sock->Lock));
  return Status;
}

EFI_STATUS
SockClose (
  IN SOCKET  *Sock,
  IN VOID    *Token,
  IN BOOLEAN OnAbort
  )
/*++

Routine Description:

  Close or abort the socket associated connection.

Arguments:

  Sock    - Pointer to the socket of the connection to close or abort.
  Token   - The token for close operation.
  OnAbort - TRUE for aborting the connection, FALSE to close it.

Returns:

  EFI_SUCCESS       - The close or abort operation is initialized successfully.
  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.
  EFI_NO_MAPPING    - The IP address configuration operation is not finished.
  EFI_NOT_STARTED   - The socket is not configured.

--*/
{
  EFI_STATUS  Status;
  EFI_EVENT   Event;

  ASSERT (SOCK_STREAM == Sock->Type);

  Status = NET_TRYLOCK (&(Sock->Lock));
  if (EFI_ERROR (Status)) {
    SOCK_DEBUG_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:
  NET_UNLOCK (&(Sock->Lock));
  return Status;
}

EFI_STATUS
SockGetMode (
  IN SOCKET *Sock,
  IN VOID   *Mode
  )
/*++

Routine Description:

  Get the mode data of the low layer protocol.

Arguments:

  Sock  - Pointer to the socket to get mode data from.
  Mode  - Pointer to the data to store the low layer mode
          information.

Returns:

  EFI_SUCCESS     - The mode data is got successfully.
  EFI_NOT_STARTED - The socket is not configured.

--*/
{
  return Sock->ProtoHandler (Sock, SOCK_MODE, Mode);
}

EFI_STATUS
SockGroup (
  IN SOCKET *Sock,
  IN VOID   *GroupInfo
  )
/*++

Routine Description:

  Configure the low level protocol to join a multicast group for
  this socket's connection.

Arguments:

  Sock      - Pointer to the socket of the connection to join the
              specific multicast group.
  GroupInfo - Pointer to the multicast group info.

Returns:

  EFI_SUCCESS       - The configuration is done successfully.
  EFI_ACCESS_DENIED - Failed to get the lock to access the socket.
  EFI_NOT_STARTED   - The socket is not configured.

--*/
{
  EFI_STATUS  Status;

  Status = NET_TRYLOCK (&(Sock->Lock));

  if (EFI_ERROR (Status)) {

    SOCK_DEBUG_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:
  NET_UNLOCK (&(Sock->Lock));
  return Status;
}

EFI_STATUS
SockRoute (
  IN SOCKET    *Sock,
  IN VOID      *RouteInfo
  )
/*++

Routine Description:

  Add or remove route information in IP route table associated
  with this socket.

Arguments:

  Sock      - Pointer to the socket associated with the IP route
              table to operate on.
  RouteInfo - Pointer to the route information to be processed.

Returns:

  EFI_SUCCESS       - The route table is updated successfully.
  EFI_ACCESS_DENIED - Failed to get the lock to access the socket.
  EFI_NO_MAPPING    - The IP address configuration operation is 
                      not finished.
  EFI_NOT_STARTED   - The socket is not configured.

--*/
{
  EFI_STATUS  Status;

  Status = NET_TRYLOCK (&(Sock->Lock));
  if (EFI_ERROR (Status)) {
    SOCK_DEBUG_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:
  NET_UNLOCK (&(Sock->Lock));
  return Status;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?