Ejemplo n.º 1
0
/**
  Flush the tokens in the specific token list.

  @param  Sock                  Pointer to the socket.
  @param  PendingTokenList      Pointer to the token list to be flushed.

**/
VOID
SockFlushPendingToken (
  IN SOCKET         *Sock,
  IN LIST_ENTRY     *PendingTokenList
  )
{
  SOCK_TOKEN            *SockToken;
  SOCK_COMPLETION_TOKEN *Token;

  ASSERT ((Sock != NULL) && (PendingTokenList != NULL));

  while (!IsListEmpty (PendingTokenList)) {
    SockToken = NET_LIST_HEAD (
                  PendingTokenList,
                  SOCK_TOKEN,
                  TokenList
                  );

    Token = SockToken->Token;
    SIGNAL_TOKEN (Token, Sock->SockError);

    RemoveEntryList (&(SockToken->TokenList));
    FreePool (SockToken);
  }
}
Ejemplo n.º 2
0
INTN
Mtftp4GetNextBlockNum (
  IN NET_LIST_ENTRY         *Head
  )
/*++

Routine Description:

  Get the first valid block number on the range list. 

Arguments:

  Head  - The block range head

Returns:

  -1: if the block range is empty. Otherwise the first valid block number.

--*/
{
  MTFTP4_BLOCK_RANGE  *Range;

  if (NetListIsEmpty (Head)) {
    return -1;
  }

  Range = NET_LIST_HEAD (Head, MTFTP4_BLOCK_RANGE, Link);
  return Range->Start;
}
Ejemplo n.º 3
0
/**
  Signal the receive token with the specific error or
  set socket error code after error is received.

  @param  Sock                  Pointer to the socket.
  @param  Error                 The error code received.

**/
VOID
SockRcvdErr (
  IN OUT SOCKET       *Sock,
  IN     EFI_STATUS   Error
  )
{
  SOCK_TOKEN  *SockToken;

  if (!IsListEmpty (&Sock->RcvTokenList)) {

    SockToken = NET_LIST_HEAD (
                  &Sock->RcvTokenList,
                  SOCK_TOKEN,
                  TokenList
                  );

    RemoveEntryList (&SockToken->TokenList);

    SIGNAL_TOKEN (SockToken->Token, Error);

    FreePool (SockToken);
  } else {

    SOCK_ERROR (Sock, Error);
  }
}
Ejemplo n.º 4
0
/**
  Flush the sndBuffer and rcvBuffer of socket.

  @param  Sock                  Pointer to the socket.

**/
VOID
SockConnFlush (
  IN OUT SOCKET *Sock
  )
{
  SOCKET  *Child;

  ASSERT (Sock != NULL);

  //
  // Clear the flag in this socket
  //
  Sock->Flag = 0;

  //
  // Flush the SndBuffer and RcvBuffer of Sock
  //
  NetbufQueFlush (Sock->SndBuffer.DataQueue);
  NetbufQueFlush (Sock->RcvBuffer.DataQueue);

  //
  // Signal the pending token
  //
  if (Sock->ConnectionToken != NULL) {
    SIGNAL_TOKEN (Sock->ConnectionToken, Sock->SockError);
    Sock->ConnectionToken = NULL;
  }

  if (Sock->CloseToken != NULL) {
    SIGNAL_TOKEN (Sock->CloseToken, Sock->SockError);
    Sock->CloseToken = NULL;
  }

  SockFlushPendingToken (Sock, &(Sock->ListenTokenList));
  SockFlushPendingToken (Sock, &(Sock->RcvTokenList));
  SockFlushPendingToken (Sock, &(Sock->SndTokenList));
  SockFlushPendingToken (Sock, &(Sock->ProcessingSndTokenList));

  //
  // Destroy the pending connection, if it is a listening socket
  //
  if (SOCK_IS_LISTENING (Sock)) {
    while (!IsListEmpty (&Sock->ConnectionList)) {
      Child = NET_LIST_HEAD (
                &Sock->ConnectionList,
                SOCKET,
                ConnectionList
                );

      SockDestroyChild (Child);
    }

    Sock->ConnCnt = 0;
  }

  return ;
}
Ejemplo n.º 5
0
/**
  Get the first valid block number on the range list.

  @param[in]  Head                   The block range head.

  @retval     ==-1                   If the block range is empty.
  @retval     >-1                    The first valid block number.

**/
INTN
Mtftp6GetNextBlockNum (
  IN LIST_ENTRY              *Head
  )
{
  MTFTP6_BLOCK_RANGE  *Range;

  if (IsListEmpty (Head)) {
    return -1;
  }

  Range = NET_LIST_HEAD (Head, MTFTP6_BLOCK_RANGE, Link);
  return Range->Start;
}
Ejemplo n.º 6
0
/**
  Get the first buffer block in the specific socket buffer.

  @param  Sockbuf               Pointer to the socket buffer.

  @return Pointer to the first buffer in the queue. NULL if the queue is empty.

**/
NET_BUF *
SockBufFirst (
  IN SOCK_BUFFER *Sockbuf
  )
{
  LIST_ENTRY      *NetbufList;

  NetbufList = &(Sockbuf->DataQueue->BufList);

  if (IsListEmpty (NetbufList)) {
    return NULL;
  }

  return NET_LIST_HEAD (NetbufList, NET_BUF, List);
}
Ejemplo n.º 7
0
/**
  Called by low layer protocol to indicate that some data is sent or processed.

  This function trims the sent data in the socket send buffer, signals the data
  token if proper.

  @param  Sock                  Pointer to the socket.
  @param  Count                 The length of the data processed or sent, in bytes.

**/
VOID
SockDataSent (
  IN SOCKET     *Sock,
  IN UINT32     Count
  )
{
  SOCK_TOKEN            *SockToken;
  SOCK_COMPLETION_TOKEN *SndToken;

  ASSERT (!IsListEmpty (&Sock->ProcessingSndTokenList));
  ASSERT (Count <= (Sock->SndBuffer.DataQueue)->BufSize);

  NetbufQueTrim (Sock->SndBuffer.DataQueue, Count);

  //
  // To check if we can signal some snd token in this socket
  //
  while (Count > 0) {
    SockToken = NET_LIST_HEAD (
                  &(Sock->ProcessingSndTokenList),
                  SOCK_TOKEN,
                  TokenList
                  );

    SndToken = SockToken->Token;

    if (SockToken->RemainDataLen <= Count) {

      RemoveEntryList (&(SockToken->TokenList));
      SIGNAL_TOKEN (SndToken, EFI_SUCCESS);
      Count -= SockToken->RemainDataLen;
      FreePool (SockToken);
    } else {

      SockToken->RemainDataLen -= Count;
      Count = 0;
    }
  }

  //
  // to judge if we can process some send token in
  // Sock->SndTokenList, if so process those send token
  //
  SockProcessSndToken (Sock);
  return ;
}
Ejemplo n.º 8
0
/**
  Wake up the listen token while the connection is established successfully.

  @param[in, out]  Sock                  Pointer to the socket.

**/
VOID
SockWakeListenToken (
  IN OUT SOCKET *Sock
  )
{
  SOCKET                *Parent;
  SOCK_TOKEN            *SockToken;
  EFI_TCP4_LISTEN_TOKEN *ListenToken;

  Parent = Sock->Parent;

  ASSERT ((Parent != NULL) && SOCK_IS_LISTENING (Parent) && SOCK_IS_CONNECTED (Sock));

  if (!IsListEmpty (&Parent->ListenTokenList)) {
    SockToken = NET_LIST_HEAD (
                  &Parent->ListenTokenList,
                  SOCK_TOKEN,
                  TokenList
                  );

    ListenToken                 = (EFI_TCP4_LISTEN_TOKEN *) SockToken->Token;
    ListenToken->NewChildHandle = Sock->SockHandle;

    SIGNAL_TOKEN (&(ListenToken->CompletionToken), EFI_SUCCESS);

    RemoveEntryList (&SockToken->TokenList);
    FreePool (SockToken);

    RemoveEntryList (&Sock->ConnectionList);

    Parent->ConnCnt--;
    DEBUG (
      (EFI_D_NET,
      "SockWakeListenToken: accept a socket, now conncnt is %d",
      Parent->ConnCnt)
      );

    Sock->Parent = NULL;
  }
}
Ejemplo n.º 9
0
/**
  Wake up the receive token while some data is received.

  @param  Sock                  Pointer to the socket.

**/
VOID
SockWakeRcvToken (
  IN SOCKET *Sock
  )
{
  UINT32        RcvdBytes;
  UINT32        TokenRcvdBytes;
  SOCK_TOKEN    *SockToken;
  SOCK_IO_TOKEN *RcvToken;

  ASSERT (Sock->RcvBuffer.DataQueue != NULL);

  RcvdBytes = (Sock->RcvBuffer.DataQueue)->BufSize;

  ASSERT (RcvdBytes > 0);

  while (RcvdBytes > 0 && !IsListEmpty (&Sock->RcvTokenList)) {

    SockToken = NET_LIST_HEAD (
                  &Sock->RcvTokenList,
                  SOCK_TOKEN,
                  TokenList
                  );

    RcvToken        = (SOCK_IO_TOKEN *) SockToken->Token;
    TokenRcvdBytes  = SockProcessRcvToken (Sock, RcvToken);

    if (0 == TokenRcvdBytes) {
      return ;
    }

    RemoveEntryList (&(SockToken->TokenList));
    FreePool (SockToken);
    RcvdBytes -= TokenRcvdBytes;
  }
}
Ejemplo n.º 10
0
/**
  Process the send token.

  @param  Sock                  Pointer to the socket.

**/
VOID
SockProcessSndToken (
  IN OUT SOCKET *Sock
  )
{
  UINT32                  FreeSpace;
  SOCK_TOKEN              *SockToken;
  UINT32                  DataLen;
  SOCK_IO_TOKEN           *SndToken;
  EFI_TCP4_TRANSMIT_DATA  *TxData;
  EFI_STATUS              Status;

  ASSERT ((Sock != NULL) && (SockStream == Sock->Type));

  FreeSpace = SockGetFreeSpace (Sock, SOCK_SND_BUF);

  //
  // to determine if process a send token using
  // socket layer flow control policy
  //
  while ((FreeSpace >= Sock->SndBuffer.LowWater) &&
         !IsListEmpty (&Sock->SndTokenList)) {

    SockToken = NET_LIST_HEAD (
                  &(Sock->SndTokenList),
                  SOCK_TOKEN,
                  TokenList
                  );

    //
    // process this token
    //
    RemoveEntryList (&(SockToken->TokenList));
    InsertTailList (
      &(Sock->ProcessingSndTokenList),
      &(SockToken->TokenList)
      );

    //
    // Proceess it in the light of  SockType
    //
    SndToken  = (SOCK_IO_TOKEN *) SockToken->Token;
    TxData    = SndToken->Packet.TxData;

    DataLen = (UINT32) TxData->DataLength;
    Status  = SockProcessTcpSndData (Sock, TxData);

    if (EFI_ERROR (Status)) {
      goto OnError;
    }

    if (DataLen >= FreeSpace) {
      FreeSpace = 0;

    } else {
      FreeSpace -= DataLen;

    }
  }

  return ;

OnError:

  RemoveEntryList (&SockToken->TokenList);
  SIGNAL_TOKEN (SockToken->Token, Status);
  FreePool (SockToken);
}
Ejemplo n.º 11
0
EFI_STATUS
Mtftp4DriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL *This,
  IN  EFI_HANDLE                  Controller,
  IN  UINTN                       NumberOfChildren,
  IN  EFI_HANDLE                  *ChildHandleBuffer
  )
/*++

Routine Description:

  Stop the MTFTP driver on controller. The controller is a UDP 
  child handle.

Arguments:

  This              - The MTFTP driver binding protocol
  Controller        - The controller to stop 
  NumberOfChildren  - The number of children
  ChildHandleBuffer - The array of the child handle.

Returns:

  EFI_SUCCESS      - The driver is stopped on the controller.
  EFI_DEVICE_ERROR - Failed to stop the driver on the controller.

--*/
{
  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;
  MTFTP4_SERVICE                *MtftpSb;
  MTFTP4_PROTOCOL               *Instance;
  EFI_HANDLE                    NicHandle;
  EFI_STATUS                    Status;
  EFI_TPL                       OldTpl;

  //
  // MTFTP driver opens UDP child, So, Controller is a UDP 
  // child handle. Locate the Nic handle first. Then get the
  // MTFTP private data back.
  //
  NicHandle = NetLibGetNicHandle (Controller, &gEfiUdp4ProtocolGuid);
  
  if (NicHandle == NULL) {
    return EFI_DEVICE_ERROR;
  }
  
  Status = gBS->OpenProtocol (
                  NicHandle,
                  &gEfiMtftp4ServiceBindingProtocolGuid,
                  (VOID **) &ServiceBinding,
                  This->DriverBindingHandle,
                  NicHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  MtftpSb = MTFTP4_SERVICE_FROM_THIS (ServiceBinding);

  if (MtftpSb->InDestory) {
    return EFI_SUCCESS;
  }

  OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);

  if (NumberOfChildren == 0) {

    MtftpSb->InDestory = TRUE;

    gBS->UninstallProtocolInterface (
           NicHandle,
           &gEfiMtftp4ServiceBindingProtocolGuid,
           ServiceBinding
           );

    Mtftp4CleanService (MtftpSb);

    NetFreePool (MtftpSb);
  } else {

    while (!NetListIsEmpty (&MtftpSb->Children)) {
      Instance = NET_LIST_HEAD (&MtftpSb->Children, MTFTP4_PROTOCOL, Link);
      Mtftp4ServiceBindingDestroyChild (ServiceBinding, Instance->Handle);
    }

    if (MtftpSb->ChildrenNum != 0) {
      Status = EFI_DEVICE_ERROR;
    }
  }

  NET_RESTORE_TPL (OldTpl);
  return Status;
}
Ejemplo n.º 12
0
/**
  Stop the MTFTP driver on controller. The controller is a UDP
  child handle.

  @param  This                   The MTFTP driver binding protocol
  @param  Controller             The controller to stop
  @param  NumberOfChildren       The number of children
  @param  ChildHandleBuffer      The array of the child handle.

  @retval EFI_SUCCESS            The driver is stopped on the controller.
  @retval EFI_DEVICE_ERROR       Failed to stop the driver on the controller.

**/
EFI_STATUS
EFIAPI
Mtftp4DriverBindingStop (
  IN EFI_DRIVER_BINDING_PROTOCOL *This,
  IN EFI_HANDLE                  Controller,
  IN UINTN                       NumberOfChildren,
  IN EFI_HANDLE                  *ChildHandleBuffer
  )
{
  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;
  MTFTP4_SERVICE                *MtftpSb;
  MTFTP4_PROTOCOL               *Instance;
  EFI_HANDLE                    NicHandle;
  EFI_STATUS                    Status;
  EFI_TPL                       OldTpl;

  //
  // MTFTP driver opens UDP child, So, Controller is a UDP
  // child handle. Locate the Nic handle first. Then get the
  // MTFTP private data back.
  //
  NicHandle = NetLibGetNicHandle (Controller, &gEfiUdp4ProtocolGuid);

  if (NicHandle == NULL) {
    return EFI_DEVICE_ERROR;
  }

  Status = gBS->OpenProtocol (
                  NicHandle,
                  &gEfiMtftp4ServiceBindingProtocolGuid,
                  (VOID **) &ServiceBinding,
                  This->DriverBindingHandle,
                  NicHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  MtftpSb = MTFTP4_SERVICE_FROM_THIS (ServiceBinding);

  if (MtftpSb->InDestory) {
    return EFI_SUCCESS;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  if (NumberOfChildren == 0) {

    MtftpSb->InDestory = TRUE;

    gBS->UninstallProtocolInterface (
           NicHandle,
           &gEfiMtftp4ServiceBindingProtocolGuid,
           ServiceBinding
           );

    Mtftp4CleanService (MtftpSb);

    FreePool (MtftpSb);
  } else {

    while (!IsListEmpty (&MtftpSb->Children)) {
      Instance = NET_LIST_HEAD (&MtftpSb->Children, MTFTP4_PROTOCOL, Link);
      Mtftp4ServiceBindingDestroyChild (ServiceBinding, Instance->Handle);
    }

    if (MtftpSb->ChildrenNum != 0) {
      Status = EFI_DEVICE_ERROR;
    }
  }

  gBS->RestoreTPL (OldTpl);
  return Status;
}