/** @file\r
Routines to process Rrq (download).\r
- \r
-Copyright (c) 2006 - 2007, Intel Corporation<BR>\r
-All rights reserved. This program and the accompanying materials\r
+\r
+(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
http://opensource.org/licenses/bsd-license.php<BR>\r
The packet process callback for MTFTP download.\r
\r
@param UdpPacket The packet received\r
- @param Points The local/remote access point of the packet\r
+ @param EndPoint The local/remote access point of the packet\r
@param IoStatus The status of the receiving\r
@param Context Opaque parameter, which is the MTFTP session\r
\r
**/\r
VOID\r
+EFIAPI\r
Mtftp4RrqInput (\r
IN NET_BUF *UdpPacket,\r
- IN UDP_POINTS *Points,\r
+ IN UDP_END_POINT *EndPoint,\r
IN EFI_STATUS IoStatus,\r
IN VOID *Context\r
);\r
\r
\r
/**\r
- Start the MTFTP session to download. \r
- \r
- It will first initialize some of the internal states then build and send a RRQ \r
+ Start the MTFTP session to download.\r
+\r
+ It will first initialize some of the internal states then build and send a RRQ\r
reqeuest packet, at last, it will start receive for the downloading.\r
\r
@param Instance The Mtftp session\r
NET_BUF *Packet;\r
\r
Packet = NetbufAlloc (sizeof (EFI_MTFTP4_ACK_HEADER));\r
-\r
if (Packet == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
sizeof (EFI_MTFTP4_ACK_HEADER),\r
FALSE\r
);\r
+ ASSERT (Ack != NULL);\r
\r
Ack->Ack.OpCode = HTONS (EFI_MTFTP4_OPCODE_ACK);\r
Ack->Ack.Block[0] = HTONS (BlkNo);\r
UINT16 Block;\r
UINT64 Start;\r
UINT32 DataLen;\r
+ UINT64 TotalBlock;\r
+ BOOLEAN Completed;\r
\r
- Token = Instance->Token;\r
- Block = NTOHS (Packet->Data.Block);\r
- DataLen = Len - MTFTP4_DATA_HEAD_LEN;\r
+ Completed = FALSE;\r
+ Token = Instance->Token;\r
+ Block = NTOHS (Packet->Data.Block);\r
+ DataLen = Len - MTFTP4_DATA_HEAD_LEN;\r
\r
//\r
// This is the last block, save the block no\r
//\r
if (DataLen < Instance->BlkSize) {\r
+ Completed = TRUE;\r
Instance->LastBlock = Block;\r
Mtftp4SetLastBlockNum (&Instance->Blocks, Block);\r
}\r
//\r
// Remove this block number from the file hole. If Mtftp4RemoveBlockNum\r
// returns EFI_NOT_FOUND, the block has been saved, don't save it again.\r
+ // Note that : For bigger files, allowing the block counter to roll over\r
+ // to accept transfers of unlimited size. So TotalBlock is memorised as\r
+ // continuous block counter.\r
//\r
- Status = Mtftp4RemoveBlockNum (&Instance->Blocks, Block);\r
+ Status = Mtftp4RemoveBlockNum (&Instance->Blocks, Block, Completed, &TotalBlock);\r
\r
if (Status == EFI_NOT_FOUND) {\r
return EFI_SUCCESS;\r
}\r
\r
if (Token->Buffer != NULL) {\r
- Start = MultU64x32 (Block - 1, Instance->BlkSize);\r
+ Start = MultU64x32 (TotalBlock - 1, Instance->BlkSize);\r
\r
if (Start + DataLen <= Token->BufferSize) {\r
CopyMem ((UINT8 *) Token->Buffer + Start, Packet->Data.Data, DataLen);\r
//\r
// Update the file size when received the last block\r
//\r
- if (Instance->LastBlock == Block) {\r
+ if ((Instance->LastBlock == Block) && Completed) {\r
Token->BufferSize = Start + DataLen;\r
}\r
\r
\r
\r
/**\r
- Function to process the received data packets. \r
- \r
+ Function to process the received data packets.\r
+\r
It will save the block then send back an ACK if it is active.\r
\r
@param Instance The downloading MTFTP session\r
\r
/**\r
Validate whether the options received in the server's OACK packet is valid.\r
- \r
+\r
The options are valid only if:\r
1. The server doesn't include options not requested by us\r
2. The server can only use smaller blksize than that is requested\r
/**\r
Configure a UDP IO port to receive the multicast.\r
\r
- @param McastIo The UDP IO port to configure\r
+ @param McastIo The UDP IO to configure\r
@param Context The opaque parameter to the function which is the\r
MTFTP session.\r
\r
\r
**/\r
EFI_STATUS\r
+EFIAPI\r
Mtftp4RrqConfigMcastPort (\r
- IN UDP_IO_PORT *McastIo,\r
+ IN UDP_IO *McastIo,\r
IN VOID *Context\r
)\r
{\r
UdpConfig.ReceiveTimeout = 0;\r
UdpConfig.TransmitTimeout = 0;\r
UdpConfig.UseDefaultAddress = Config->UseDefaultSetting;\r
- UdpConfig.StationAddress = Config->StationIp;\r
- UdpConfig.SubnetMask = Config->SubnetMask;\r
+ IP4_COPY_ADDRESS (&UdpConfig.StationAddress, &Config->StationIp);\r
+ IP4_COPY_ADDRESS (&UdpConfig.SubnetMask, &Config->SubnetMask);\r
UdpConfig.StationPort = Instance->McastPort;\r
UdpConfig.RemotePort = 0;\r
\r
Ip = HTONL (Instance->ServerIp);\r
- CopyMem (&UdpConfig.RemoteAddress, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
+ IP4_COPY_ADDRESS (&UdpConfig.RemoteAddress, &Ip);\r
\r
- Status = McastIo->Udp->Configure (McastIo->Udp, &UdpConfig);\r
+ Status = McastIo->Protocol.Udp4->Configure (McastIo->Protocol.Udp4, &UdpConfig);\r
\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
- if (!Config->UseDefaultSetting && \r
+ if (!Config->UseDefaultSetting &&\r
!EFI_IP4_EQUAL (&mZeroIp4Addr, &Config->GatewayIp)) {\r
//\r
// The station IP address is manually configured and the Gateway IP is not 0.\r
// Add the default route for this UDP instance.\r
//\r
- Status = McastIo->Udp->Routes (\r
- McastIo->Udp, \r
- FALSE,\r
- &mZeroIp4Addr,\r
- &mZeroIp4Addr,\r
- &Config->GatewayIp\r
- );\r
- \r
+ Status = McastIo->Protocol.Udp4->Routes (\r
+ McastIo->Protocol.Udp4,\r
+ FALSE,\r
+ &mZeroIp4Addr,\r
+ &mZeroIp4Addr,\r
+ &Config->GatewayIp\r
+ );\r
+\r
if (EFI_ERROR (Status)) {\r
- McastIo->Udp->Configure (McastIo->Udp, NULL);\r
+ McastIo->Protocol.Udp4->Configure (McastIo->Protocol.Udp4, NULL);\r
return Status;\r
}\r
}\r
// join the multicast group\r
//\r
Ip = HTONL (Instance->McastIp);\r
- CopyMem (&Group, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
+ IP4_COPY_ADDRESS (&Group, &Ip);\r
\r
- return McastIo->Udp->Groups (McastIo->Udp, TRUE, &Group);\r
+ return McastIo->Protocol.Udp4->Groups (McastIo->Protocol.Udp4, TRUE, &Group);\r
}\r
\r
\r
/**\r
- Function to process the OACK. \r
- \r
+ Function to process the OACK.\r
+\r
It will first validate the OACK packet, then update the various negotiated parameters.\r
\r
@param Instance The download MTFTP session\r
MTFTP4_OPTION Reply;\r
EFI_STATUS Status;\r
INTN Expected;\r
+ EFI_UDP4_PROTOCOL *Udp4;\r
\r
*Completed = FALSE;\r
\r
//\r
Instance->McastIp = Reply.McastIp;\r
Instance->McastPort = Reply.McastPort;\r
- Instance->McastUdpPort = UdpIoCreatePort (\r
- Instance->Service->Controller,\r
- Instance->Service->Image,\r
- Mtftp4RrqConfigMcastPort,\r
- Instance\r
- );\r
+ if (Instance->McastUdpPort == NULL) {\r
+ Instance->McastUdpPort = UdpIoCreateIo (\r
+ Instance->Service->Controller,\r
+ Instance->Service->Image,\r
+ Mtftp4RrqConfigMcastPort,\r
+ UDP_IO_UDP4_VERSION,\r
+ Instance\r
+ );\r
+ if (Instance->McastUdpPort != NULL) {\r
+ Status = gBS->OpenProtocol (\r
+ Instance->McastUdpPort->UdpHandle,\r
+ &gEfiUdp4ProtocolGuid,\r
+ (VOID **) &Udp4,\r
+ Instance->Service->Image,\r
+ Instance->Handle,\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ UdpIoFreeIo (Instance->McastUdpPort);\r
+ Instance->McastUdpPort = NULL;\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ }\r
+ }\r
+\r
\r
if (Instance->McastUdpPort == NULL) {\r
return EFI_DEVICE_ERROR;\r
\r
return Status;\r
}\r
- \r
+\r
//\r
// Update the parameters used.\r
//\r
if (Reply.BlkSize != 0) {\r
Instance->BlkSize = Reply.BlkSize;\r
}\r
- \r
+\r
if (Reply.Timeout != 0) {\r
Instance->Timeout = Reply.Timeout;\r
- } \r
- } \r
- \r
+ }\r
+ }\r
+\r
} else {\r
Instance->Master = TRUE;\r
- \r
+\r
if (Reply.BlkSize != 0) {\r
Instance->BlkSize = Reply.BlkSize;\r
}\r
Instance->Timeout = Reply.Timeout;\r
}\r
}\r
- \r
+\r
//\r
// Send an ACK to (Expected - 1) which is 0 for unicast download,\r
// or tell the server we want to receive the Expected block.\r
The packet process callback for MTFTP download.\r
\r
@param UdpPacket The packet received\r
- @param Points The local/remote access point of the packet\r
+ @param EndPoint The local/remote access point of the packet\r
@param IoStatus The status of the receiving\r
@param Context Opaque parameter, which is the MTFTP session\r
\r
**/\r
VOID\r
+EFIAPI\r
Mtftp4RrqInput (\r
IN NET_BUF *UdpPacket,\r
- IN UDP_POINTS *Points,\r
+ IN UDP_END_POINT *EndPoint,\r
IN EFI_STATUS IoStatus,\r
IN VOID *Context\r
)\r
//\r
// Find the port this packet is from to restart receive correctly.\r
//\r
- Multicast = (BOOLEAN) (Points->LocalAddr == Instance->McastIp);\r
+ Multicast = (BOOLEAN) (EndPoint->LocalAddr.Addr[0] == Instance->McastIp);\r
\r
if (UdpPacket->TotalSize < MTFTP4_OPCODE_LEN) {\r
goto ON_EXIT;\r
// is required to use the same port as RemotePort to multicast the\r
// data.\r
//\r
- if (Points->RemotePort != Instance->ConnectedPort) {\r
+ if (EndPoint->RemotePort != Instance->ConnectedPort) {\r
if (Instance->ConnectedPort != 0) {\r
goto ON_EXIT;\r
} else {\r
- Instance->ConnectedPort = Points->RemotePort;\r
+ Instance->ConnectedPort = EndPoint->RemotePort;\r
}\r
}\r
\r
\r
} else {\r
Packet = (EFI_MTFTP4_PACKET *) NetbufGetByte (UdpPacket, 0, NULL);\r
+ ASSERT (Packet != NULL);\r
}\r
\r
Opcode = NTOHS (Packet->OpCode);\r
case EFI_MTFTP4_OPCODE_ERROR:\r
Status = EFI_TFTP_ERROR;\r
break;\r
- \r
+\r
default:\r
break;\r
}\r
// receive, otherwise end the session.\r
//\r
if ((Packet != NULL) && (UdpPacket->BlockOpNum > 1)) {\r
- gBS->FreePool (Packet);\r
+ FreePool (Packet);\r
}\r
\r
if (UdpPacket != NULL) {\r