]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.c
BaseTools:Change the path of the file that Binary Cache
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Mtftp4Dxe / Mtftp4Support.c
index df79c85fa00a5c9888b3966b9f89c3729b5f8f8b..ad2ff7bf3a3f82a83e3ef4a5d6f9cdd8e0947c45 100644 (file)
@@ -1,14 +1,8 @@
 /** @file\r
   Support routines for Mtftp.\r
-  \r
-Copyright (c) 2006 - 2010, 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
 \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -48,16 +42,16 @@ Mtftp4AllocateRange (
 \r
 \r
 /**\r
-  Initialize the block range for either RRQ or WRQ. \r
-  \r
-  RRQ and WRQ have different requirements for Start and End. \r
-  For example, during start up, WRQ initializes its whole valid block range \r
-  to [0, 0xffff]. This is bacause the server will send us a ACK0 to inform us \r
-  to start the upload. When the client received ACK0, it will remove 0 from the \r
+  Initialize the block range for either RRQ or WRQ.\r
+\r
+  RRQ and WRQ have different requirements for Start and End.\r
+  For example, during start up, WRQ initializes its whole valid block range\r
+  to [0, 0xffff]. This is bacause the server will send us a ACK0 to inform us\r
+  to start the upload. When the client received ACK0, it will remove 0 from the\r
   range, get the next block number, which is 1, then upload the BLOCK1. For RRQ\r
-  without option negotiation, the server will directly send us the BLOCK1 in \r
-  response to the client's RRQ. When received BLOCK1, the client will remove \r
-  it from the block range and send an ACK. It also works if there is option \r
+  without option negotiation, the server will directly send us the BLOCK1 in\r
+  response to the client's RRQ. When received BLOCK1, the client will remove\r
+  it from the block range and send an ACK. It also works if there is option\r
   negotiation.\r
 \r
   @param  Head                  The block range head to initialize\r
@@ -93,7 +87,7 @@ Mtftp4InitBlockRange (
 \r
   @param  Head                  The block range head\r
 \r
-  @return The first valid block number, -1 if the block range is empty. \r
+  @return The first valid block number, -1 if the block range is empty.\r
 \r
 **/\r
 INTN\r
@@ -113,10 +107,10 @@ Mtftp4GetNextBlockNum (
 \r
 \r
 /**\r
-  Set the last block number of the block range list. \r
-  \r
+  Set the last block number of the block range list.\r
+\r
   It will remove all the blocks after the Last. MTFTP initialize the block range\r
-  to the maximum possible range, such as [0, 0xffff] for WRQ. When it gets the \r
+  to the maximum possible range, such as [0, 0xffff] for WRQ. When it gets the\r
   last block number, it will call this function to set the last block number.\r
 \r
   @param  Head                  The block range list\r
@@ -158,8 +152,8 @@ Mtftp4SetLastBlockNum (
 \r
   @param  Head                  The block range list to remove from\r
   @param  Num                   The block number to remove\r
-  @param  Completed             Whether Num is the last block number\r
-  @param  TotalBlock            The continuous block number in all \r
+  @param  Completed             Whether Num is the last block number.\r
+  @param  BlockCounter          The continuous block counter instead of the value after roll-over.\r
 \r
   @retval EFI_NOT_FOUND         The block number isn't in the block range list\r
   @retval EFI_SUCCESS           The block number has been removed from the list\r
@@ -171,7 +165,7 @@ Mtftp4RemoveBlockNum (
   IN LIST_ENTRY             *Head,\r
   IN UINT16                 Num,\r
   IN BOOLEAN                Completed,\r
-  OUT UINT64                *TotalBlock\r
+  OUT UINT64                *BlockCounter\r
   )\r
 {\r
   MTFTP4_BLOCK_RANGE        *Range;\r
@@ -213,22 +207,22 @@ Mtftp4RemoveBlockNum (
       Range->Start++;\r
 \r
       //\r
-      // Note that: RFC 1350 does not mention block counter roll-over, \r
-      // but several TFTP hosts implement the roll-over be able to accept \r
-      // transfers of unlimited size. There is no consensus, however, whether \r
-      // the counter should wrap around to zero or to one. Many implementations \r
-      // wrap to zero, because this is the simplest to implement. Here we choose \r
+      // Note that: RFC 1350 does not mention block counter roll-over,\r
+      // but several TFTP hosts implement the roll-over be able to accept\r
+      // transfers of unlimited size. There is no consensus, however, whether\r
+      // the counter should wrap around to zero or to one. Many implementations\r
+      // wrap to zero, because this is the simplest to implement. Here we choose\r
       // this solution.\r
       //\r
-         *TotalBlock  = Num;\r
-         \r
+      *BlockCounter  = Num;\r
+\r
       if (Range->Round > 0) {\r
-           *TotalBlock += Range->Bound +  MultU64x32 ((UINTN) (Range->Round -1), (UINT32) (Range->Bound + 1)) + 1;\r
-         }\r
+        *BlockCounter += Range->Bound +  MultU64x32 ((UINTN) (Range->Round -1), (UINT32) (Range->Bound + 1)) + 1;\r
+      }\r
 \r
       if (Range->Start > Range->Bound) {\r
-                 Range->Start = 0;\r
-                 Range->Round ++;\r
+        Range->Start = 0;\r
+        Range->Round ++;\r
       }\r
 \r
       if ((Range->Start > Range->End) || Completed) {\r
@@ -278,13 +272,16 @@ Mtftp4SendRequest (
   EFI_MTFTP4_PACKET         *Packet;\r
   EFI_MTFTP4_OPTION         *Options;\r
   EFI_MTFTP4_TOKEN          *Token;\r
+  RETURN_STATUS             Status;\r
   NET_BUF                   *Nbuf;\r
   UINT8                     *Mode;\r
   UINT8                     *Cur;\r
-  UINT32                    Len;\r
   UINTN                     Index;\r
-  UINT32                    Len1;\r
-  UINT32                    Len2;\r
+  UINT32                    BufferLength;\r
+  UINTN                     FileNameLength;\r
+  UINTN                     ModeLength;\r
+  UINTN                     OptionStrLength;\r
+  UINTN                     ValueStrLength;\r
 \r
   Token   = Instance->Token;\r
   Options = Token->OptionList;\r
@@ -297,39 +294,52 @@ Mtftp4SendRequest (
   //\r
   // Compute the packet length\r
   //\r
-  Len1 = (UINT32) AsciiStrLen ((CHAR8 *) Token->Filename);\r
-  Len2 = (UINT32) AsciiStrLen ((CHAR8 *) Mode);\r
-  Len  = (Len1 + Len2 + 4);\r
+  FileNameLength = AsciiStrLen ((CHAR8 *) Token->Filename);\r
+  ModeLength     = AsciiStrLen ((CHAR8 *) Mode);\r
+  BufferLength   = (UINT32) FileNameLength + (UINT32) ModeLength + 4;\r
 \r
   for (Index = 0; Index < Token->OptionCount; Index++) {\r
-    Len1 = (UINT32) AsciiStrLen ((CHAR8 *) Options[Index].OptionStr);\r
-    Len2 = (UINT32) AsciiStrLen ((CHAR8 *) Options[Index].ValueStr);\r
-    Len += Len1 + Len2 + 2;\r
+    OptionStrLength = AsciiStrLen ((CHAR8 *) Options[Index].OptionStr);\r
+    ValueStrLength  = AsciiStrLen ((CHAR8 *) Options[Index].ValueStr);\r
+    BufferLength   += (UINT32) OptionStrLength + (UINT32) ValueStrLength + 2;\r
   }\r
-\r
   //\r
   // Allocate a packet then copy the data over\r
   //\r
-  if ((Nbuf = NetbufAlloc (Len)) == NULL) {\r
+  if ((Nbuf = NetbufAlloc (BufferLength)) == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  Packet         = (EFI_MTFTP4_PACKET *) NetbufAllocSpace (Nbuf, Len, FALSE);\r
+  Packet         = (EFI_MTFTP4_PACKET *) NetbufAllocSpace (Nbuf, BufferLength, FALSE);\r
   ASSERT (Packet != NULL);\r
 \r
   Packet->OpCode = HTONS (Instance->Operation);\r
+  BufferLength  -= sizeof (Packet->OpCode);\r
+\r
   Cur            = Packet->Rrq.Filename;\r
-  Cur            = (UINT8 *) AsciiStrCpy ((CHAR8 *) Cur, (CHAR8 *) Token->Filename);\r
-  Cur           += AsciiStrLen ((CHAR8 *) Token->Filename) + 1;\r
-  Cur            = (UINT8 *) AsciiStrCpy ((CHAR8 *) Cur, (CHAR8 *) Mode);\r
-  Cur           += AsciiStrLen ((CHAR8 *) Mode) + 1;\r
+  Status         = AsciiStrCpyS ((CHAR8 *) Cur, BufferLength, (CHAR8 *) Token->Filename);\r
+  ASSERT_EFI_ERROR (Status);\r
+  BufferLength  -= (UINT32) (FileNameLength + 1);\r
+  Cur           += FileNameLength + 1;\r
+  Status         = AsciiStrCpyS ((CHAR8 *) Cur, BufferLength, (CHAR8 *) Mode);\r
+  ASSERT_EFI_ERROR (Status);\r
+  BufferLength  -= (UINT32) (ModeLength + 1);\r
+  Cur           += ModeLength + 1;\r
 \r
   for (Index = 0; Index < Token->OptionCount; ++Index) {\r
-    Cur  = (UINT8 *) AsciiStrCpy ((CHAR8 *) Cur, (CHAR8 *) Options[Index].OptionStr);\r
-    Cur += AsciiStrLen ((CHAR8 *) Options[Index].OptionStr) + 1;\r
+    OptionStrLength = AsciiStrLen ((CHAR8 *) Options[Index].OptionStr);\r
+    ValueStrLength  = AsciiStrLen ((CHAR8 *) Options[Index].ValueStr);\r
+\r
+    Status          = AsciiStrCpyS ((CHAR8 *) Cur, BufferLength, (CHAR8 *) Options[Index].OptionStr);\r
+    ASSERT_EFI_ERROR (Status);\r
+    BufferLength   -= (UINT32) (OptionStrLength + 1);\r
+    Cur            += OptionStrLength + 1;\r
+\r
+    Status          = AsciiStrCpyS ((CHAR8 *) Cur, BufferLength, (CHAR8 *) Options[Index].ValueStr);\r
+    ASSERT_EFI_ERROR (Status);\r
+    BufferLength   -= (UINT32) (ValueStrLength + 1);\r
+    Cur            += ValueStrLength + 1;\r
 \r
-    Cur  = (UINT8 *) AsciiStrCpy ((CHAR8 *) Cur, (CHAR8 *) Options[Index].ValueStr);\r
-    Cur += AsciiStrLen ((CHAR8 *) (CHAR8 *) Options[Index].ValueStr) + 1;\r
   }\r
 \r
   return Mtftp4SendPacket (Instance, Nbuf);\r
@@ -340,7 +350,7 @@ Mtftp4SendRequest (
   Build then send an error message.\r
 \r
   @param  Instance              The MTFTP session\r
-  @param  ErrCode               The error code  \r
+  @param  ErrCode               The error code\r
   @param  ErrInfo               The error message\r
 \r
   @retval EFI_OUT_OF_RESOURCES  Failed to allocate memory for the error packet\r
@@ -371,7 +381,7 @@ Mtftp4SendError (
   TftpError->OpCode = HTONS (EFI_MTFTP4_OPCODE_ERROR);\r
   TftpError->Error.ErrorCode = HTONS (ErrCode);\r
 \r
-  AsciiStrCpy ((CHAR8 *) TftpError->Error.ErrorMessage, (CHAR8 *) ErrInfo);\r
+  AsciiStrCpyS ((CHAR8 *) TftpError->Error.ErrorMessage, Len, (CHAR8 *) ErrInfo);\r
 \r
   return Mtftp4SendPacket (Instance, Packet);\r
 }\r
@@ -379,7 +389,7 @@ Mtftp4SendError (
 \r
 /**\r
   The callback function called when the packet is transmitted.\r
-  \r
+\r
   It simply frees the packet.\r
 \r
   @param  Packet                The transmitted (or failed to) packet\r
@@ -421,10 +431,10 @@ Mtftp4SetTimeout (
 \r
 \r
 /**\r
-  Send the packet for the instance. \r
-  \r
-  It will first save a reference to the packet for later retransmission. \r
-  Then determine the destination port, listen port for requests, and connected \r
+  Send the packet for the instance.\r
+\r
+  It will first save a reference to the packet for later retransmission.\r
+  Then determine the destination port, listen port for requests, and connected\r
   port for others. At last, send the packet out.\r
 \r
   @param  Instance              The Mtftp instance\r
@@ -468,7 +478,7 @@ Mtftp4SendPacket (
   ASSERT (Buffer != NULL);\r
   OpCode = NTOHS (*(UINT16 *)Buffer);\r
 \r
-  if ((OpCode == EFI_MTFTP4_OPCODE_RRQ) || \r
+  if ((OpCode == EFI_MTFTP4_OPCODE_RRQ) ||\r
       (OpCode == EFI_MTFTP4_OPCODE_DIR) ||\r
       (OpCode == EFI_MTFTP4_OPCODE_WRQ)) {\r
     UdpPoint.RemotePort = Instance->ListeningPort;\r
@@ -552,6 +562,42 @@ Mtftp4Retransmit (
 }\r
 \r
 \r
+/**\r
+  The timer ticking function in TPL_NOTIFY level for the Mtftp service instance.\r
+\r
+  @param  Event                 The ticking event\r
+  @param  Context               The Mtftp service instance\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+Mtftp4OnTimerTickNotifyLevel (\r
+  IN EFI_EVENT              Event,\r
+  IN VOID                   *Context\r
+  )\r
+{\r
+  MTFTP4_SERVICE            *MtftpSb;\r
+  LIST_ENTRY                *Entry;\r
+  LIST_ENTRY                *Next;\r
+  MTFTP4_PROTOCOL           *Instance;\r
+\r
+  MtftpSb = (MTFTP4_SERVICE *) Context;\r
+\r
+  //\r
+  // Iterate through all the children of the Mtftp service instance. Time\r
+  // out the current packet transmit.\r
+  //\r
+  NET_LIST_FOR_EACH_SAFE (Entry, Next, &MtftpSb->Children) {\r
+    Instance = NET_LIST_USER_STRUCT (Entry, MTFTP4_PROTOCOL, Link);\r
+    if ((Instance->PacketToLive == 0) || (--Instance->PacketToLive > 0)) {\r
+      Instance->HasTimeout = FALSE;\r
+    } else {\r
+      Instance->HasTimeout = TRUE;\r
+    }\r
+  }\r
+}\r
+\r
+\r
 /**\r
   The timer ticking function for the Mtftp service instance.\r
 \r
@@ -575,29 +621,28 @@ Mtftp4OnTimerTick (
   MtftpSb = (MTFTP4_SERVICE *) Context;\r
 \r
   //\r
-  // Iterate through all the children of the Mtftp service instance. Time\r
-  // out the packet. If maximum retries reached, clean the session up.\r
+  // Iterate through all the children of the Mtftp service instance.\r
   //\r
   NET_LIST_FOR_EACH_SAFE (Entry, Next, &MtftpSb->Children) {\r
     Instance = NET_LIST_USER_STRUCT (Entry, MTFTP4_PROTOCOL, Link);\r
-\r
-    if ((Instance->PacketToLive == 0) || (--Instance->PacketToLive > 0)) {\r
+    if (!Instance->HasTimeout) {\r
       continue;\r
     }\r
 \r
+    Instance->HasTimeout = FALSE;\r
+\r
     //\r
     // Call the user's time out handler\r
     //\r
     Token = Instance->Token;\r
 \r
-    if ((Token->TimeoutCallback != NULL) &&\r
+    if (Token != NULL && Token->TimeoutCallback != NULL &&\r
         EFI_ERROR (Token->TimeoutCallback (&Instance->Mtftp4, Token))) {\r
-\r
       Mtftp4SendError (\r
-         Instance,\r
-         EFI_MTFTP4_ERRORCODE_REQUEST_DENIED,\r
-         (UINT8 *) "User aborted the transfer in time out"\r
-         );\r
+        Instance,\r
+        EFI_MTFTP4_ERRORCODE_REQUEST_DENIED,\r
+        (UINT8 *) "User aborted the transfer in time out"\r
+        );\r
 \r
       Mtftp4CleanOperation (Instance, EFI_ABORTED);\r
       continue;\r