udp4io.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 814 行 · 第 1/2 页
C
814 行
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. 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.
Module Name:
Udp4Io.c
Abstract:
Help functions to access UDP service, it is used by both the DHCP and MTFTP.
--*/
#include "Udp4Io.h"
STATIC
VOID
EFIAPI
UdpIoOnDgramSent (
IN EFI_EVENT Event,
IN VOID *Context
);
STATIC
VOID
EFIAPI
UdpIoOnDgramRcvd (
IN EFI_EVENT Event,
IN VOID *Context
);
STATIC
UDP_TX_TOKEN *
UdpIoWrapTx (
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:
Wrap a transmit request into a UDP_TX_TOKEN.
Arguments:
UdpIo - The UdpIo port to send packet to
Packet - The user's packet
EndPoint - The local and remote access point
Gateway - The overrided next hop
CallBack - The function to call when transmission completed.
Context - The opaque parameter to the call back
Returns:
The wrapped transmission request or NULL if failed to allocate resources.
--*/
{
UDP_TX_TOKEN *Token;
EFI_UDP4_COMPLETION_TOKEN *UdpToken;
EFI_UDP4_TRANSMIT_DATA *UdpTxData;
EFI_STATUS Status;
UINT32 Count;
Token = NetAllocatePool (sizeof (UDP_TX_TOKEN) +
sizeof (EFI_UDP4_FRAGMENT_DATA) * (Packet->BlockOpNum - 1));
if (Token == NULL) {
return NULL;
}
Token->Signature = UDP_IO_TX_SIGNATURE;
NetListInit (&Token->Link);
Token->UdpIo = UdpIo;
Token->CallBack = CallBack;
Token->Packet = Packet;
Token->Context = Context;
UdpToken = &(Token->UdpToken);
UdpToken->Status = EFI_NOT_READY;
Status = gBS->CreateEvent (
EFI_EVENT_NOTIFY_SIGNAL,
EFI_TPL_CALLBACK,
UdpIoOnDgramSent,
Token,
&UdpToken->Event
);
if (EFI_ERROR (Status)) {
NetFreePool (Token);
return NULL;
}
UdpTxData = &Token->UdpTxData;
UdpToken->Packet.TxData = UdpTxData;
UdpTxData->UdpSessionData = NULL;
UdpTxData->GatewayAddress = NULL;
if (EndPoint != NULL) {
EFI_IP4 (Token->UdpSession.SourceAddress) = HTONL (EndPoint->LocalAddr);
EFI_IP4 (Token->UdpSession.DestinationAddress) = HTONL (EndPoint->RemoteAddr);
Token->UdpSession.SourcePort = EndPoint->LocalPort;
Token->UdpSession.DestinationPort = EndPoint->RemotePort;
UdpTxData->UdpSessionData = &Token->UdpSession;
}
if (Gateway != 0) {
EFI_IP4 (Token->Gateway) = HTONL (Gateway);
UdpTxData->GatewayAddress = &Token->Gateway;
}
UdpTxData->DataLength = Packet->TotalSize;
Count = Packet->BlockOpNum;
NetbufBuildExt (Packet, (NET_FRAGMENT *) UdpTxData->FragmentTable, &Count);
UdpTxData->FragmentCount = Count;
return Token;
}
VOID
UdpIoFreeTxToken (
IN UDP_TX_TOKEN *Token
)
/*++
Routine Description:
Free a UDP_TX_TOKEN. The event is closed and memory released.
Arguments:
Token - The UDP_TX_TOKEN to release.
Returns:
None
--*/
{
gBS->CloseEvent (Token->UdpToken.Event);
NetFreePool (Token);
}
UDP_RX_TOKEN *
UdpIoCreateRxToken (
IN UDP_IO_PORT *UdpIo,
IN UDP_IO_CALLBACK CallBack,
IN VOID *Context,
IN UINT32 HeadLen
)
/*++
Routine Description:
Create a UDP_RX_TOKEN to wrap the request.
Arguments:
UdpIo - The UdpIo to receive packets from
CallBack - The function to call when receive finished.
Context - The opaque parameter to the CallBack
HeadLen - The head length to reserver for the packet.
Returns:
The Wrapped request or NULL if failed to allocate resources.
--*/
{
UDP_RX_TOKEN *Token;
EFI_STATUS Status;
Token = NetAllocatePool (sizeof (UDP_RX_TOKEN));
if (Token == NULL) {
return NULL;
}
Token->Signature = UDP_IO_RX_SIGNATURE;
Token->UdpIo = UdpIo;
Token->CallBack = CallBack;
Token->Context = Context;
Token->HeadLen = HeadLen;
Token->UdpToken.Status = EFI_NOT_READY;
Token->UdpToken.Packet.RxData = NULL;
Status = gBS->CreateEvent (
EFI_EVENT_NOTIFY_SIGNAL,
EFI_TPL_CALLBACK,
UdpIoOnDgramRcvd,
Token,
&Token->UdpToken.Event
);
if (EFI_ERROR (Status)) {
NetFreePool (Token);
return NULL;
}
return Token;
}
VOID
UdpIoFreeRxToken (
IN UDP_RX_TOKEN *Token
)
/*++
Routine Description:
Free a receive request wrap.
Arguments:
Token - The receive request to release.
Returns:
None
--*/
{
gBS->CloseEvent (Token->UdpToken.Event);
NetFreePool (Token);
}
UDP_IO_PORT *
UdpIoCreatePort (
IN EFI_HANDLE Controller,
IN EFI_HANDLE Image,
IN UDP_IO_CONFIG Configure,
IN VOID *Context
)
/*++
Routine Description:
Create a UDP IO port to access the UDP service. It will
create and configure a UDP child.
Arguments:
Controller - The controller that has the UDP service binding protocol installed.
Image - The image handle for the driver.
Configure - The function to configure the created UDP child
Context - The opaque parameter for the Configure funtion.
Returns:
A point to just created UDP IO port or NULL if failed.
--*/
{
UDP_IO_PORT *UdpIo;
EFI_STATUS Status;
ASSERT (Configure != NULL);
UdpIo = NetAllocatePool (sizeof (UDP_IO_PORT));
if (UdpIo == NULL) {
return NULL;
}
UdpIo->Signature = UDP_IO_SIGNATURE;
NetListInit (&UdpIo->Link);
UdpIo->RefCnt = 1;
UdpIo->Controller = Controller;
UdpIo->Image = Image;
NetListInit (&UdpIo->SentDatagram);
UdpIo->RecvRequest = NULL;
UdpIo->UdpHandle = NULL;
//
// Create a UDP child then open and configure it
//
Status = NetLibCreateServiceChild (
Controller,
Image,
&gEfiUdp4ServiceBindingProtocolGuid,
&UdpIo->UdpHandle
);
if (EFI_ERROR (Status)) {
goto FREE_MEM;
}
Status = gBS->OpenProtocol (
UdpIo->UdpHandle,
&gEfiUdp4ProtocolGuid,
&UdpIo->Udp,
Image,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
goto FREE_CHILD;
}
if (EFI_ERROR (Configure (UdpIo, Context))) {
goto CLOSE_PROTOCOL;
}
Status = UdpIo->Udp->GetModeData (UdpIo->Udp, NULL, NULL, NULL, &UdpIo->SnpMode);
if (EFI_ERROR (Status)) {
goto CLOSE_PROTOCOL;
}
return UdpIo;
CLOSE_PROTOCOL:
gBS->CloseProtocol (UdpIo->UdpHandle, &gEfiUdp4ProtocolGuid, Image, Controller);
FREE_CHILD:
NetLibDestroyServiceChild (
Controller,
Image,
&gEfiUdp4ServiceBindingProtocolGuid,
UdpIo->UdpHandle
);
FREE_MEM:
NetFreePool (UdpIo);
return NULL;
}
STATIC
VOID
UdpIoCancelDgrams (
IN UDP_IO_PORT *UdpIo,
IN EFI_STATUS IoStatus,
IN UDP_IO_TO_CANCEL ToCancel, OPTIONAL
IN VOID *Context
)
/*++
Routine Description:
Cancel all the sent datagram that pass the selection of ToCancel.
If ToCancel is NULL, all the datagrams are cancelled.
Arguments:
UdpIo - The UDP IO port to cancel packet
IoStatus - The IoStatus to return to the packet owners.
ToCancel - The select funtion to test whether to cancel this packet or not.
Context - The opaque parameter to the ToCancel.
Returns:
None
--*/
{
NET_LIST_ENTRY *Entry;
NET_LIST_ENTRY *Next;
UDP_TX_TOKEN *Token;
NET_LIST_FOR_EACH_SAFE (Entry, Next, &UdpIo->SentDatagram) {
Token = NET_LIST_USER_STRUCT (Entry, UDP_TX_TOKEN, Link);
if ((ToCancel == NULL) || (ToCancel (Token, Context))) {
NetListRemoveEntry (Entry);
UdpIo->Udp->Cancel (UdpIo->Udp, &Token->UdpToken);
Token->CallBack (Token->Packet, NULL, IoStatus, Token->Context);
UdpIoFreeTxToken (Token);
}
}
}
EFI_STATUS
UdpIoFreePort (
IN UDP_IO_PORT *UdpIo
)
/*++
Routine Description:
Free the UDP IO port and all its related resources including
all the transmitted packet.
Arguments:
UdpIo - The UDP IO port to free.
Returns:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?