/** @file\r
Routines to process Rrq (download).\r
\r
-Copyright (c) 2006 - 2009, Intel Corporation<BR>\r
-All rights reserved. This program and the accompanying materials\r
+(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>\r
+Copyright (c) 2006 - 2014, 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
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
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->Protocol.Udp4->Configure (McastIo->Protocol.Udp4, &UdpConfig);\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->Protocol.Udp4->Groups (McastIo->Protocol.Udp4, TRUE, &Group);\r
}\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 = 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
+ 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
} else {\r
Packet = (EFI_MTFTP4_PACKET *) NetbufGetByte (UdpPacket, 0, NULL);\r
+ ASSERT (Packet != NULL);\r
}\r
\r
Opcode = NTOHS (Packet->OpCode);\r