]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/TcpDxe/SockInterface.c
NetworkPkg: Support TCP Cancel function
[mirror_edk2.git] / NetworkPkg / TcpDxe / SockInterface.c
index 1f3524bc1b6baa33e005f152510bdcd93cc6a33a..1ae0c64b108a0fe421ec28de194b8ee932c33e4b 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Interface function of the Socket.\r
 \r
-  Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
@@ -876,6 +876,96 @@ Exit:
   return Status;\r
 }\r
 \r
+/**\r
+  Abort the socket associated connection, listen, transmission or receive request.\r
+\r
+  @param[in, out]  Sock        Pointer to the socket to abort.\r
+  @param[in]       Token       Pointer to a token that has been issued by\r
+                               Connect(), Accept(), Transmit() or Receive(). If\r
+                               NULL, all pending tokens issued by the four\r
+                               functions listed above will be aborted.\r
+\r
+  @retval EFI_UNSUPPORTED      The operation is not supported in the current\r
+                               implementation.\r
+**/\r
+EFI_STATUS\r
+SockCancel (\r
+  IN OUT SOCKET  *Sock,\r
+  IN     VOID    *Token\r
+  ) \r
+{\r
+  EFI_STATUS     Status;\r
+\r
+  Status    = EFI_SUCCESS;\r
+\r
+  ASSERT (SockStream == Sock->Type);\r
+\r
+  Status = EfiAcquireLockOrFail (&(Sock->Lock));\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG (\r
+      (EFI_D_ERROR,\r
+      "SockCancel: Get the access for socket failed with %r",\r
+      Status)\r
+      );\r
+\r
+    return EFI_ACCESS_DENIED;\r
+  }\r
+\r
+  if (SOCK_IS_UNCONFIGURED (Sock)) {\r
+    Status = EFI_NOT_STARTED;\r
+    goto Exit;\r
+  }\r
+  \r
+  //\r
+  // 1. Check ConnectionToken.\r
+  //\r
+  if (Token == NULL || (SOCK_COMPLETION_TOKEN *) Token == Sock->ConnectionToken) {\r
+    if (Sock->ConnectionToken != NULL) {\r
+      SIGNAL_TOKEN (Sock->ConnectionToken, EFI_ABORTED);\r
+      Sock->ConnectionToken = NULL;\r
+    }\r
+\r
+    if (Token != NULL) {\r
+      Status = EFI_SUCCESS;\r
+      goto Exit;\r
+    }\r
+  }\r
+\r
+  //\r
+  // 2. Check ListenTokenList.\r
+  //\r
+  Status = SockCancelToken (Token, &Sock->ListenTokenList);\r
+  if (Token != NULL && !EFI_ERROR (Status)) {\r
+    goto Exit;\r
+  }\r
+\r
+  //\r
+  // 3. Check RcvTokenList.\r
+  //\r
+  Status = SockCancelToken (Token, &Sock->RcvTokenList);\r
+  if (Token != NULL && !EFI_ERROR (Status)) {\r
+    goto Exit;\r
+  }\r
+  \r
+  //\r
+  // 4. Check SndTokenList.\r
+  //\r
+  Status = SockCancelToken (Token, &Sock->SndTokenList);\r
+  if (Token != NULL && !EFI_ERROR (Status)) {\r
+    goto Exit;\r
+  }\r
+\r
+  //\r
+  // 5. Check ProcessingSndTokenList.\r
+  //\r
+  Status = SockCancelToken (Token, &Sock->ProcessingSndTokenList);\r
+  \r
+Exit:\r
+  EfiReleaseLock (&(Sock->Lock));\r
+  return Status;\r
+}\r
+\r
+\r
 /**\r
   Get the mode data of the low layer protocol.\r
 \r