udp4io.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 814 行 · 第 1/2 页
C
814 行
EFI_SUCCESS - The UDP IO port is freed.
--*/
{
UDP_RX_TOKEN *RxToken;
//
// Cancel all the sent datagram and receive requests. The
// callbacks of transmit requests are executed to allow the
// caller to release the resource. The callback of receive
// request are NOT executed. This is because it is most
// likely that the current user of the UDP IO port is closing
// itself.
//
UdpIoCancelDgrams (UdpIo, EFI_ABORTED, NULL, NULL);
if ((RxToken = UdpIo->RecvRequest) != NULL) {
UdpIo->RecvRequest = NULL;
UdpIo->Udp->Cancel (UdpIo->Udp, &RxToken->UdpToken);
UdpIoFreeRxToken (RxToken);
}
//
// Close then destory the UDP child
//
gBS->CloseProtocol (
UdpIo->UdpHandle,
&gEfiUdp4ProtocolGuid,
UdpIo->Image,
UdpIo->Controller
);
NetLibDestroyServiceChild (
UdpIo->Controller,
UdpIo->Image,
&gEfiUdp4ServiceBindingProtocolGuid,
UdpIo->UdpHandle
);
NetListRemoveEntry (&UdpIo->Link);
NetFreePool (UdpIo);
return EFI_SUCCESS;
}
VOID
UdpIoCleanPort (
IN UDP_IO_PORT *UdpIo
)
/*++
Routine Description:
Clean up the UDP IO port. It will release all the transmitted
datagrams and receive request. It will also configure NULL the
UDP child.
Arguments:
UdpIo - UDP IO port to clean up.
Returns:
None
--*/
{
UDP_RX_TOKEN *RxToken;
//
// Cancel all the sent datagram and receive requests.
//
UdpIoCancelDgrams (UdpIo, EFI_ABORTED, NULL, NULL);
if ((RxToken = UdpIo->RecvRequest) != NULL) {
UdpIo->RecvRequest = NULL;
UdpIo->Udp->Cancel (UdpIo->Udp, &RxToken->UdpToken);
UdpIoFreeRxToken (RxToken);
}
UdpIo->Udp->Configure (UdpIo->Udp, NULL);
}
STATIC
VOID
EFIAPI
UdpIoOnDgramSent (
IN EFI_EVENT Event,
IN VOID *Context
)
/*++
Routine Description:
The callback function when the packet is sent by UDP.
It will remove the packet from the local list then call
the packet owner's callback function.
Arguments:
Event - The event signalled.
Context - The UDP TX Token.
Returns:
None
--*/
{
UDP_TX_TOKEN *Token;
EFI_TPL OldTpl;
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
Token = (UDP_TX_TOKEN *) Context;
ASSERT (Token->Signature == UDP_IO_TX_SIGNATURE);
NetListRemoveEntry (&Token->Link);
Token->CallBack (Token->Packet, NULL, Token->UdpToken.Status, Token->Context);
UdpIoFreeTxToken (Token);
NET_RESTORE_TPL (OldTpl);
}
EFI_STATUS
UdpIoSendDatagram (
IN UDP_IO_PORT *UdpIo,
IN NET_BUF *Packet,
IN UDP_POINTS *EndPoint, OPTIONAL
IN IP4_ADDR Gateway,
IN UDP_IO_CALLBACK CallBack,
IN VOID *Context
)
/*++
Routine Description:
Send a packet through the UDP IO port.
Arguments:
UdpIo - The UDP IO Port to send the packet through
Packet - The packet to send
EndPoint - The local and remote access point
Gateway - The gateway to use
CallBack - The call back function to call when packet is
transmitted or failed.
Context - The opque parameter to the CallBack
Returns:
EFI_OUT_OF_RESOURCES - Failed to allocate resource for the packet
EFI_SUCCESS - The packet is successfully delivered to UDP
for transmission.
--*/
{
UDP_TX_TOKEN *Token;
EFI_STATUS Status;
Token = UdpIoWrapTx (UdpIo, Packet, EndPoint, Gateway, CallBack, Context);
if (Token == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Status = UdpIo->Udp->Transmit (UdpIo->Udp, &Token->UdpToken);
if (EFI_ERROR (Status)) {
UdpIoFreeTxToken (Token);
return Status;
}
NetListInsertHead (&UdpIo->SentDatagram, &Token->Link);
return EFI_SUCCESS;
}
STATIC
BOOLEAN
UdpIoCancelSingleDgram (
IN UDP_TX_TOKEN *Token,
IN VOID *Context
)
/*++
Routine Description:
The selection function to cancel a single sent datagram.
Arguments:
Token - The UDP TX token to test againist.
Context - The context
Returns:
TRUE if the packet is to be cancelled, otherwise FALSE.
--*/
{
NET_BUF *Packet;
Packet = (NET_BUF *) Context;
if (Token->Packet == Packet) {
return TRUE;
}
return FALSE;
}
VOID
UdpIoCancelSentDatagram (
IN UDP_IO_PORT *UdpIo,
IN NET_BUF *Packet
)
/*++
Routine Description:
Cancel a single sent datagram.
Arguments:
UdpIo - The UDP IO port to cancel the packet from
Packet - The packet to cancel
Returns:
None
--*/
{
UdpIoCancelDgrams (UdpIo, EFI_ABORTED, UdpIoCancelSingleDgram, Packet);
}
STATIC
VOID
UdpIoRecycleDgram (
IN VOID *Context
)
/*++
Routine Description:
Recycle the received UDP data.
Arguments:
Context - The UDP_RX_TOKEN
Returns:
None
--*/
{
UDP_RX_TOKEN *Token;
Token = (UDP_RX_TOKEN *) Context;
gBS->SignalEvent (Token->UdpToken.Packet.RxData->RecycleSignal);
UdpIoFreeRxToken (Token);
}
STATIC
VOID
EFIAPI
UdpIoOnDgramRcvd (
IN EFI_EVENT Event,
IN VOID *Context
)
/*++
Routine Description:
The event handle for UDP receive request. It will build
a NET_BUF from the recieved UDP data, then deliver it
to the receiver.
Arguments:
Event - The UDP receive request event
Context - The UDP RX token.
Returns:
None
--*/
{
EFI_UDP4_COMPLETION_TOKEN *UdpToken;
EFI_UDP4_RECEIVE_DATA *UdpRxData;
EFI_UDP4_SESSION_DATA *UdpSession;
UDP_RX_TOKEN *Token;
UDP_POINTS Points;
EFI_TPL OldTpl;
NET_BUF *Netbuf;
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
Token = (UDP_RX_TOKEN *) Context;
ASSERT ((Token->Signature == UDP_IO_RX_SIGNATURE) &&
(Token == Token->UdpIo->RecvRequest));
//
// Clear the receive request first in case that the caller
// wants to restart the receive in the callback.
//
Token->UdpIo->RecvRequest = NULL;
UdpToken = &Token->UdpToken;
UdpRxData = UdpToken->Packet.RxData;
if (EFI_ERROR (UdpToken->Status) || (UdpRxData == NULL)) {
Token->CallBack (NULL, NULL, UdpToken->Status, Token->Context);
UdpIoFreeRxToken (Token);
goto ON_EXIT;
}
//
// Build a NET_BUF from the UDP receive data, then deliver it up.
//
Netbuf = NetbufFromExt (
(NET_FRAGMENT *) UdpRxData->FragmentTable,
UdpRxData->FragmentCount,
0,
(UINT32) Token->HeadLen,
UdpIoRecycleDgram,
Token
);
if (Netbuf == NULL) {
gBS->SignalEvent (UdpRxData->RecycleSignal);
Token->CallBack (NULL, NULL, EFI_OUT_OF_RESOURCES, Token->Context);
UdpIoFreeRxToken (Token);
goto ON_EXIT;
}
UdpSession = &UdpRxData->UdpSession;
Points.LocalAddr = EFI_NTOHL (UdpSession->DestinationAddress);
Points.LocalPort = UdpSession->DestinationPort;
Points.RemoteAddr = EFI_NTOHL (UdpSession->SourceAddress);
Points.RemotePort = UdpSession->SourcePort;
Token->CallBack (Netbuf, &Points, EFI_SUCCESS, Token->Context);
ON_EXIT:
NET_RESTORE_TPL (OldTpl);
return;
}
EFI_STATUS
UdpIoRecvDatagram (
IN UDP_IO_PORT *UdpIo,
IN UDP_IO_CALLBACK CallBack,
IN VOID *Context,
IN UINT32 HeadLen
)
/*++
Routine Description:
Issue a receive request to the UDP IO port.
Arguments:
UdpIo - The UDP IO port to recieve the packet from.
CallBack - The call back function to execute when receive finished.
Context - The opque context to the call back
HeadLen - The lenght of the application's header
Returns:
EFI_ALREADY_STARTED - There is already a pending receive request. Only
one receive request is supported.
EFI_OUT_OF_RESOURCES - Failed to allocate some resource.
EFI_SUCCESS - The receive request is issued successfully.
--*/
{
UDP_RX_TOKEN *Token;
EFI_STATUS Status;
if (UdpIo->RecvRequest != NULL) {
return EFI_ALREADY_STARTED;
}
Token = UdpIoCreateRxToken (UdpIo, CallBack, Context, HeadLen);
if (Token == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Status = UdpIo->Udp->Receive (UdpIo->Udp, &Token->UdpToken);
if (EFI_ERROR (Status)) {
UdpIoFreeRxToken (Token);
return Status;
}
UdpIo->RecvRequest = Token;
return EFI_SUCCESS;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?