mtftp4support.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 667 行 · 第 1/2 页
C
667 行
Packet->OpCode = HTONS (Instance->Operation);
Cur = Packet->Rrq.Filename;
Cur = EfiAsciiStrCpy (Cur, Token->Filename);
Cur = EfiAsciiStrCpy (Cur, Mode);
for (Index = 0; Index < Token->OptionCount; ++Index) {
Cur = EfiAsciiStrCpy (Cur, Options[Index].OptionStr);
Cur = EfiAsciiStrCpy (Cur, Options[Index].ValueStr);
}
return Mtftp4SendPacket (Instance, Nbuf);
}
EFI_STATUS
Mtftp4SendError (
IN MTFTP4_PROTOCOL *Instance,
IN UINT16 ErrCode,
IN UINT8* ErrInfo
)
/*++
Routine Description:
Build then send an error message
Arguments:
Instance - The MTFTP session
ErrInfo - The error code and message
Returns:
EFI_OUT_OF_RESOURCES - Failed to allocate memory for the error packet
EFI_SUCCESS - The error packet is transmitted.
Others - Failed to transmit the packet.
--*/
{
NET_BUF *Packet;
EFI_MTFTP4_PACKET *TftpError;
UINT32 Len;
Len = (UINT32) (EfiAsciiStrLen (ErrInfo) + sizeof (EFI_MTFTP4_ERROR_HEADER));
Packet = NetbufAlloc (Len);
if (Packet == NULL) {
return EFI_OUT_OF_RESOURCES;
}
TftpError = (EFI_MTFTP4_PACKET *) NetbufAllocSpace (Packet, Len, FALSE);
TftpError->OpCode = HTONS (EFI_MTFTP4_OPCODE_ERROR);
TftpError->Error.ErrorCode = HTONS (ErrCode);
EfiAsciiStrCpy (TftpError->Error.ErrorMessage, ErrInfo);
return Mtftp4SendPacket (Instance, Packet);
}
STATIC
VOID
Mtftp4OnPacketSent (
NET_BUF *Packet,
UDP_POINTS *Points,
EFI_STATUS IoStatus,
VOID *Context
)
/*++
Routine Description:
The callback function called when the packet is transmitted.
It simply frees the packet.
Arguments:
Packet - The transmitted (or failed to) packet
Points - The local and remote UDP access point
IoStatus - The result of the transmission
Context - Opaque parameter to the callback
Returns:
None
--*/
{
NetbufFree (Packet);
}
VOID
Mtftp4SetTimeout (
IN MTFTP4_PROTOCOL *Instance
)
/*++
Routine Description:
Set the timeout for the instance. User a longer time for
passive instances.
Arguments:
Instance - The Mtftp session to set time out
Returns:
None
--*/
{
if (Instance->Master) {
Instance->PacketToLive = Instance->Timeout;
} else {
Instance->PacketToLive = Instance->Timeout * 2;
}
}
EFI_STATUS
Mtftp4SendPacket (
IN MTFTP4_PROTOCOL *Instance,
IN NET_BUF *Packet
)
/*++
Routine Description:
Send the packet for the instance. It will first save a reference to
the packet for later retransmission. then determine the destination
port, listen port for requests, and connected port for others. At last,
send the packet out.
Arguments:
Instance - The Mtftp instance
Packet - The packet to send
Returns:
EFI_SUCCESS - The packet is sent out
Others - Failed to transmit the packet.
--*/
{
UDP_POINTS UdpPoint;
EFI_STATUS Status;
UINT16 OpCode;
//
// Save the packet for retransmission
//
if (Instance->LastPacket != NULL) {
NetbufFree (Instance->LastPacket);
}
Instance->LastPacket = Packet;
Instance->CurRetry = 0;
Mtftp4SetTimeout (Instance);
UdpPoint.LocalAddr = 0;
UdpPoint.LocalPort = 0;
UdpPoint.RemoteAddr = Instance->ServerIp;
//
// Send the requests to the listening port, other packets
// to the connected port
//
OpCode = NTOHS (*((UINT16 *) NetbufGetByte (Packet, 0, NULL)));
if ((OpCode == EFI_MTFTP4_OPCODE_RRQ) || (OpCode == EFI_MTFTP4_OPCODE_DIR) ||
(OpCode == EFI_MTFTP4_OPCODE_WRQ)) {
UdpPoint.RemotePort = Instance->ListeningPort;
} else {
UdpPoint.RemotePort = Instance->ConnectedPort;
}
NET_GET_REF (Packet);
Status = UdpIoSendDatagram (
Instance->UnicastPort,
Packet,
&UdpPoint,
Instance->Gateway,
Mtftp4OnPacketSent,
Instance
);
if (EFI_ERROR (Status)) {
NET_PUT_REF (Packet);
}
return Status;
}
EFI_STATUS
Mtftp4Retransmit (
IN MTFTP4_PROTOCOL *Instance
)
/*++
Routine Description:
Retransmit the last packet for the instance
Arguments:
Instance - The Mtftp instance
Returns:
EFI_SUCCESS - The last packet is retransmitted.
Others - Failed to retransmit.
--*/
{
UDP_POINTS UdpPoint;
EFI_STATUS Status;
UINT16 OpCode;
ASSERT (Instance->LastPacket != NULL);
UdpPoint.LocalAddr = 0;
UdpPoint.LocalPort = 0;
UdpPoint.RemoteAddr = Instance->ServerIp;
//
// Set the requests to the listening port, other packets to the connected port
//
OpCode = NTOHS (*(UINT16 *) NetbufGetByte (Instance->LastPacket, 0, NULL));
if ((OpCode == EFI_MTFTP4_OPCODE_RRQ) || (OpCode == EFI_MTFTP4_OPCODE_DIR) ||
(OpCode == EFI_MTFTP4_OPCODE_WRQ)) {
UdpPoint.RemotePort = Instance->ListeningPort;
} else {
UdpPoint.RemotePort = Instance->ConnectedPort;
}
NET_GET_REF (Instance->LastPacket);
Status = UdpIoSendDatagram (
Instance->UnicastPort,
Instance->LastPacket,
&UdpPoint,
Instance->Gateway,
Mtftp4OnPacketSent,
Instance
);
if (EFI_ERROR (Status)) {
NET_PUT_REF (Instance->LastPacket);
}
return Status;
}
VOID
EFIAPI
Mtftp4OnTimerTick (
IN EFI_EVENT Event,
IN VOID *Context
)
/*++
Routine Description:
The timer ticking function for the Mtftp service instance.
Arguments:
Event - The ticking event
Context - The Mtftp service instance
Returns:
None
--*/
{
MTFTP4_SERVICE *MtftpSb;
NET_LIST_ENTRY *Entry;
NET_LIST_ENTRY *Next;
MTFTP4_PROTOCOL *Instance;
EFI_MTFTP4_TOKEN *Token;
EFI_TPL OldTpl;
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
MtftpSb = (MTFTP4_SERVICE *) Context;
//
// Iterate through all the children of the Mtftp service instance. Time
// out the packet. If maximum retries reached, clean the session up.
//
NET_LIST_FOR_EACH_SAFE (Entry, Next, &MtftpSb->Children) {
Instance = NET_LIST_USER_STRUCT (Entry, MTFTP4_PROTOCOL, Link);
if ((Instance->PacketToLive == 0) || (--Instance->PacketToLive > 0)) {
continue;
}
//
// Call the user's time out handler
//
Token = Instance->Token;
if ((Token->TimeoutCallback != NULL) &&
EFI_ERROR (Token->TimeoutCallback (&Instance->Mtftp4, Token))) {
Mtftp4SendError (
Instance,
EFI_MTFTP4_ERRORCODE_REQUEST_DENIED,
"User aborted the transfer in time out"
);
Mtftp4CleanOperation (Instance, EFI_ABORTED);
continue;
}
//
// Retransmit the packet if haven't reach the maxmium retry count,
// otherwise exit the transfer.
//
if (++Instance->CurRetry < Instance->MaxRetry) {
Mtftp4Retransmit (Instance);
Mtftp4SetTimeout (Instance);
} else {
Mtftp4CleanOperation (Instance, EFI_TIMEOUT);
continue;
}
}
NET_RESTORE_TPL (OldTpl);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?