The implementation for the 'tftp' Shell command.\r
\r
Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>\r
- Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved. <BR>\r
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved. <BR>\r
(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
\r
This program and the accompanying materials\r
@return TRUE The value was returned.\r
@return FALSE A parsing error occured.\r
**/\r
-STATIC \r
-BOOLEAN \r
+STATIC\r
+BOOLEAN\r
StringToUint16 (\r
IN CONST CHAR16 *ValueStr,\r
OUT UINT16 *Value\r
@param[in] NicNumber The network physical device number.\r
@param[out] NicName Address where to store the NIC name.\r
The memory area has to be at least\r
- IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH \r
+ IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH\r
double byte wide.\r
\r
@return EFI_SUCCESS The name of the NIC was returned.\r
Managed Network Protocol could not be\r
read.\r
**/\r
-STATIC \r
-EFI_STATUS \r
+STATIC\r
+EFI_STATUS\r
GetNicName (\r
IN EFI_HANDLE ControllerHandle,\r
IN UINTN NicNumber,\r
@return Others Either the creation of the child or the opening\r
of the protocol failed.\r
**/\r
-STATIC \r
-EFI_STATUS \r
+STATIC\r
+EFI_STATUS\r
CreateServiceChildAndOpenProtocol (\r
IN EFI_HANDLE ControllerHandle,\r
IN EFI_GUID *ServiceBindingProtocolGuid,\r
@param[in] ChildHandle Handle of the child to be destroyed.\r
\r
**/\r
-STATIC \r
-VOID \r
+STATIC\r
+VOID\r
CloseProtocolAndDestroyServiceChild (\r
IN EFI_HANDLE ControllerHandle,\r
IN EFI_GUID *ServiceBindingProtocolGuid,\r
(see EFI_MTFTP4_PROTOCOL.GetInfo() status codes)\r
or error when parsing the response of the server.\r
**/\r
-STATIC \r
-EFI_STATUS \r
+STATIC\r
+EFI_STATUS\r
GetFileSize (\r
IN EFI_MTFTP4_PROTOCOL *Mtftp4,\r
IN CONST CHAR8 *FilePath,\r
(see EFI_MTFTP4_PROTOCOL.ReadFile() status codes).\r
\r
**/\r
-STATIC \r
-EFI_STATUS \r
+STATIC\r
+EFI_STATUS\r
DownloadFile (\r
IN EFI_MTFTP4_PROTOCOL *Mtftp4,\r
IN CONST CHAR16 *FilePath,\r
IN CONST CHAR8 *AsciiFilePath,\r
IN UINTN FileSize,\r
IN UINT16 BlockSize,\r
+ IN UINT16 WindowSize,\r
OUT VOID **Data\r
);\r
\r
@retval EFI_SUCCESS All packets are accepted.\r
\r
**/\r
-STATIC \r
-EFI_STATUS \r
+STATIC\r
+EFI_STATUS\r
EFIAPI\r
CheckPacket (\r
IN EFI_MTFTP4_PROTOCOL *This,\r
{L"-c", TypeValue},\r
{L"-t", TypeValue},\r
{L"-s", TypeValue},\r
+ {L"-w", TypeValue},\r
{NULL , TypeMax}\r
};\r
\r
///\r
#define MTFTP_MIN_BLKSIZE 8\r
#define MTFTP_MAX_BLKSIZE 65464\r
-\r
+///\r
+/// The default windowsize (1) of tftp.\r
+///\r
+#define MTFTP_DEFAULT_WINDOWSIZE 1\r
+///\r
+/// The valid range of window size option.\r
+/// Note that: RFC 7440 does not mention max window size value, but for the\r
+/// stability reason, the value is limited to 64.\r
+///\r
+#define MTFTP_MIN_WINDOWSIZE 1\r
+#define MTFTP_MAX_WINDOWSIZE 64\r
\r
/**\r
Function for 'tftp' command.\r
VOID *Data;\r
SHELL_FILE_HANDLE FileHandle;\r
UINT16 BlockSize;\r
+ UINT16 WindowSize;\r
\r
ShellStatus = SHELL_INVALID_PARAMETER;\r
ProblemParam = NULL;\r
FileSize = 0;\r
DataSize = 0;\r
BlockSize = MTFTP_DEFAULT_BLKSIZE;\r
+ WindowSize = MTFTP_DEFAULT_WINDOWSIZE;\r
\r
//\r
// Initialize the Shell library (we must be in non-auto-init...)\r
}\r
}\r
\r
+ ValueStr = ShellCommandLineGetValue (CheckPackage, L"-w");\r
+ if (ValueStr != NULL) {\r
+ if (!StringToUint16 (ValueStr, &WindowSize)) {\r
+ goto Error;\r
+ }\r
+ if (WindowSize < MTFTP_MIN_WINDOWSIZE || WindowSize > MTFTP_MAX_WINDOWSIZE) {\r
+ ShellPrintHiiEx (\r
+ -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV),\r
+ mTftpHiiHandle, L"tftp", ValueStr\r
+ );\r
+ goto Error;\r
+ }\r
+ }\r
+\r
//\r
// Locate all MTFTP4 Service Binding protocols\r
//\r
goto NextHandle;\r
}\r
\r
- Status = DownloadFile (Mtftp4, RemoteFilePath, AsciiRemoteFilePath, FileSize, BlockSize, &Data);\r
+ Status = DownloadFile (Mtftp4, RemoteFilePath, AsciiRemoteFilePath, FileSize, BlockSize, WindowSize, &Data);\r
if (EFI_ERROR (Status)) {\r
ShellPrintHiiEx (\r
-1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_DOWNLOAD),\r
goto NextHandle;\r
}\r
\r
+ DataSize = FileSize;\r
+\r
if (!EFI_ERROR (ShellFileExists (LocalFilePath))) {\r
ShellDeleteFileByName (LocalFilePath);\r
}\r
goto NextHandle;\r
}\r
\r
- DataSize = FileSize;\r
Status = ShellWriteFile (FileHandle, &FileSize, Data);\r
if (!EFI_ERROR (Status)) {\r
ShellStatus = SHELL_SUCCESS;\r
@param[in] NicNumber The network physical device number.\r
@param[out] NicName Address where to store the NIC name.\r
The memory area has to be at least\r
- IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH \r
+ IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH\r
double byte wide.\r
\r
@return EFI_SUCCESS The name of the NIC was returned.\r
IN CONST CHAR8 *AsciiFilePath,\r
IN UINTN FileSize,\r
IN UINT16 BlockSize,\r
+ IN UINT16 WindowSize,\r
OUT VOID **Data\r
)\r
{\r
VOID *Buffer;\r
DOWNLOAD_CONTEXT *TftpContext;\r
EFI_MTFTP4_TOKEN Mtftp4Token;\r
- EFI_MTFTP4_OPTION ReqOpt;\r
- UINT8 OptBuf[10];\r
+ UINT8 BlksizeBuf[10];\r
+ UINT8 WindowsizeBuf[10];\r
+\r
+ ZeroMem (&Mtftp4Token, sizeof (EFI_MTFTP4_TOKEN));\r
\r
// Downloaded file can be large. BS.AllocatePages() is more faster\r
// than AllocatePool() and avoid fragmentation.\r
TftpContext->DownloadedNbOfBytes = 0;\r
TftpContext->LastReportedNbOfBytes = 0;\r
\r
- ZeroMem (&Mtftp4Token, sizeof (EFI_MTFTP4_TOKEN));\r
Mtftp4Token.Filename = (UINT8*)AsciiFilePath;\r
Mtftp4Token.BufferSize = FileSize;\r
Mtftp4Token.Buffer = Buffer;\r
Mtftp4Token.CheckPacket = CheckPacket;\r
Mtftp4Token.Context = (VOID*)TftpContext;\r
+ Mtftp4Token.OptionCount = 0;\r
+ Mtftp4Token.OptionList = AllocatePool (sizeof (EFI_MTFTP4_OPTION) * 2);\r
+ if (Mtftp4Token.OptionList == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Error;\r
+ }\r
+\r
if (BlockSize != MTFTP_DEFAULT_BLKSIZE) {\r
- ReqOpt.OptionStr = (UINT8 *) "blksize";\r
- AsciiSPrint ((CHAR8 *)OptBuf, sizeof (OptBuf), "%d", BlockSize);\r
- ReqOpt.ValueStr = OptBuf;\r
+ Mtftp4Token.OptionList[Mtftp4Token.OptionCount].OptionStr = (UINT8 *) "blksize";\r
+ AsciiSPrint ((CHAR8 *) BlksizeBuf, sizeof (BlksizeBuf), "%d", BlockSize);\r
+ Mtftp4Token.OptionList[Mtftp4Token.OptionCount].ValueStr = BlksizeBuf;\r
+ Mtftp4Token.OptionCount ++;\r
+ }\r
\r
- Mtftp4Token.OptionCount = 1;\r
- Mtftp4Token.OptionList = &ReqOpt;\r
+ if (WindowSize != MTFTP_DEFAULT_WINDOWSIZE) {\r
+ Mtftp4Token.OptionList[Mtftp4Token.OptionCount].OptionStr = (UINT8 *) "windowsize";\r
+ AsciiSPrint ((CHAR8 *) WindowsizeBuf, sizeof (WindowsizeBuf), "%d", WindowSize);\r
+ Mtftp4Token.OptionList[Mtftp4Token.OptionCount].ValueStr = WindowsizeBuf;\r
+ Mtftp4Token.OptionCount ++;\r
}\r
\r
ShellPrintHiiEx (\r
\r
Error :\r
\r
- if (TftpContext == NULL) {\r
+ if (TftpContext != NULL) {\r
FreePool (TftpContext);\r
}\r
\r
+ if (Mtftp4Token.OptionList != NULL) {\r
+ FreePool (Mtftp4Token.OptionList);\r
+ }\r
+\r
if (EFI_ERROR (Status)) {\r
gBS->FreePages (PagesAddress, EFI_SIZE_TO_PAGES (FileSize));\r
return Status;\r