/** @file
  Contains all EFI_UDP6_PROTOCOL interfaces.

  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>

  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php.

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "Udp6Impl.h"

EFI_UDP6_PROTOCOL  mUdp6Protocol = {
  Udp6GetModeData,
  Udp6Configure,
  Udp6Groups,
  Udp6Transmit,
  Udp6Receive,
  Udp6Cancel,
  Udp6Poll
};


/**
  This function copies the current operational settings of this EFI UDPv6 Protocol
  instance into user-supplied buffers. This function is used optionally to retrieve
  the operational mode data of underlying networks or drivers.

  @param[in]  This               Pointer to the EFI_UDP6_PROTOCOL instance.
  @param[out] Udp6ConfigData     The buffer in which the current UDP configuration
                                 data is returned. This parameter is optional and
                                 may be NULL.
  @param[out] Ip6ModeData        The buffer in which the current EFI IPv6 Protocol
                                 mode data is returned. This parameter is optional
                                 and may be NULL.
  @param[out] MnpConfigData      The buffer in which the current managed network
                                 configuration data is returned. This parameter is
                                 optional and may be NULL.
  @param[out] SnpModeData        The buffer in which the simple network mode data
                                 is returned. This parameter is optional and may be NULL.

  @retval EFI_SUCCESS            The mode data was read.
  @retval EFI_NOT_STARTED        When Udp6ConfigData is queried, no configuration
                                 data is  available because this instance has not
                                 been started.
  @retval EFI_INVALID_PARAMETER  This is NULL.

**/
EFI_STATUS
EFIAPI
Udp6GetModeData (
  IN  EFI_UDP6_PROTOCOL                *This,
  OUT EFI_UDP6_CONFIG_DATA             *Udp6ConfigData OPTIONAL,
  OUT EFI_IP6_MODE_DATA                *Ip6ModeData    OPTIONAL,
  OUT EFI_MANAGED_NETWORK_CONFIG_DATA  *MnpConfigData  OPTIONAL,
  OUT EFI_SIMPLE_NETWORK_MODE          *SnpModeData    OPTIONAL
  )
{
  UDP6_INSTANCE_DATA  *Instance;
  EFI_IP6_PROTOCOL    *Ip;
  EFI_TPL             OldTpl;
  EFI_STATUS          Status;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = UDP6_INSTANCE_DATA_FROM_THIS (This);

  if (!Instance->Configured && (Udp6ConfigData != NULL)) {
    return EFI_NOT_STARTED;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  if (Udp6ConfigData != NULL) {
    //
    // Set the Udp6ConfigData.
    //
    CopyMem (Udp6ConfigData, &Instance->ConfigData, sizeof (EFI_UDP6_CONFIG_DATA));
  }

  Ip = Instance->IpInfo->Ip.Ip6;

  //
  // Get the underlying Ip6ModeData, MnpConfigData and SnpModeData.
  //
  Status = Ip->GetModeData (Ip, Ip6ModeData, MnpConfigData, SnpModeData);

  gBS->RestoreTPL (OldTpl);

  return Status;
}


/**
  This function is used to do the following:
  Initialize and start this instance of the EFI UDPv6 Protocol.
  Change the filtering rules and operational parameters.
  Reset this instance of the EFI UDPv6 Protocol.

  @param[in]  This               Pointer to the EFI_UDP6_PROTOCOL instance.
  @param[in]  UdpConfigData      Pointer to the buffer to set the configuration
                                 data. This parameter is optional and may be NULL.

  @retval EFI_SUCCESS            The configuration settings were set, changed, or
                                 reset successfully.
  @retval EFI_NO_MAPPING         When the UdpConifgData.UseAnyStationAddress is set
                                 to true and there is no address available for the IP6
                                 driver to bind a source address to this instance.
  @retval EFI_INVALID_PARAMETER  One or more following conditions are TRUE:
                                 This is NULL.
                                 UdpConfigData.StationAddress is not a valid
                                 unicast IPv6 address.
                                 UdpConfigData.RemoteAddress is not a valid unicast
                                 IPv6  address if it is not zero.
  @retval EFI_ALREADY_STARTED    The EFI UDPv6 Protocol instance is already
                                 started/configured and must be stopped/reset
                                 before it can be reconfigured. Only TrafficClass,
                                 HopLimit, ReceiveTimeout, and  TransmitTimeout can
                                 be reconfigured without stopping the  current
                                 instance of the EFI UDPv6 Protocol.
  @retval EFI_ACCESS_DENIED      UdpConfigData.AllowDuplicatePort is FALSE and
                                 UdpConfigData.StationPort is already used by another
                                 instance.
  @retval EFI_OUT_OF_RESOURCES   The EFI UDPv6 Protocol driver cannot allocate
                                 memory for this EFI UDPv6 Protocol instance.
  @retval EFI_DEVICE_ERROR       An unexpected network or system error occurred, and
                                 this instance was not opened.

**/
EFI_STATUS
EFIAPI
Udp6Configure (
  IN EFI_UDP6_PROTOCOL     *This,
  IN EFI_UDP6_CONFIG_DATA  *UdpConfigData OPTIONAL
  )
{
  EFI_STATUS           Status;
  UDP6_INSTANCE_DATA   *Instance;
  UDP6_SERVICE_DATA    *Udp6Service;
  EFI_TPL              OldTpl;
  EFI_IPv6_ADDRESS     StationAddress;
  EFI_IPv6_ADDRESS     RemoteAddress;
  EFI_IP6_CONFIG_DATA  Ip6ConfigData;
  EFI_IPv6_ADDRESS     LocalAddr;
  EFI_IPv6_ADDRESS     RemoteAddr;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = UDP6_INSTANCE_DATA_FROM_THIS (This);

  if (!Instance->Configured && (UdpConfigData == NULL)) {
    return EFI_SUCCESS;
  }

  Udp6Service = Instance->Udp6Service;
  Status      = EFI_SUCCESS;
  ASSERT (Udp6Service != NULL);

  OldTpl      = gBS->RaiseTPL (TPL_CALLBACK);

  if (UdpConfigData != NULL) {

    IP6_COPY_ADDRESS (&StationAddress, &UdpConfigData->StationAddress);
    IP6_COPY_ADDRESS (&RemoteAddress, &UdpConfigData->RemoteAddress);

    if ((!NetIp6IsUnspecifiedAddr (&StationAddress) && !NetIp6IsValidUnicast (&StationAddress)) ||
        (!NetIp6IsUnspecifiedAddr (&RemoteAddress) && !NetIp6IsValidUnicast (&RemoteAddress))
        ){
      //
      // If not use default address, and StationAddress is not a valid unicast
      // if it is not IPv6 address or RemoteAddress is not a valid unicast IPv6
      // address if it is not 0.
      //
      Status = EFI_INVALID_PARAMETER;
      goto ON_EXIT;
    }

    if (Instance->Configured) {
      //
      // The instance is already configured, try to do the re-configuration.
      //
      if (!Udp6IsReconfigurable (&Instance->ConfigData, UdpConfigData)) {
        //
        // If the new configuration data wants to change some unreconfigurable
        // settings, return EFI_ALREADY_STARTED.
        //
        Status = EFI_ALREADY_STARTED;
        goto ON_EXIT;
      }

      //
      // Save the reconfigurable parameters.
      //
      Instance->ConfigData.TrafficClass    = UdpConfigData->TrafficClass;
      Instance->ConfigData.HopLimit        = UdpConfigData->HopLimit;
      Instance->ConfigData.ReceiveTimeout  = UdpConfigData->ReceiveTimeout;
      Instance->ConfigData.TransmitTimeout = UdpConfigData->TransmitTimeout;
    } else {
      //
      // Construct the Ip configuration data from the UdpConfigData.
      //
      Udp6BuildIp6ConfigData (UdpConfigData, &Ip6ConfigData);

      //
      // Configure the Ip instance wrapped in the IpInfo.
      //
      Status = IpIoConfigIp (Instance->IpInfo, &Ip6ConfigData);
      if (EFI_ERROR (Status)) {
        if (Status == EFI_NO_MAPPING) {
          Instance->IsNoMapping = TRUE;
        }

        goto ON_EXIT;
      }

      Instance->IsNoMapping = FALSE;

      //
      // Save the configuration data.
      //
      CopyMem (
        &Instance->ConfigData,
        UdpConfigData,
        sizeof (EFI_UDP6_CONFIG_DATA)
        );
      IP6_COPY_ADDRESS (&Instance->ConfigData.StationAddress, &Ip6ConfigData.StationAddress);
      //
      // Try to allocate the required port resource.
      //
      Status = Udp6Bind (&Udp6Service->ChildrenList, &Instance->ConfigData);
      if (EFI_ERROR (Status)) {
        //
        // Reset the ip instance if bind fails.
        //
        IpIoConfigIp (Instance->IpInfo, NULL);
        goto ON_EXIT;
      }

      //
      // Pre calculate the checksum for the pseudo head, ignore the UDP length first.
      //
      IP6_COPY_ADDRESS (&LocalAddr, &Instance->ConfigData.StationAddress);
      IP6_COPY_ADDRESS (&RemoteAddr, &Instance->ConfigData.RemoteAddress);

      Instance->HeadSum = NetIp6PseudoHeadChecksum (
                            &LocalAddr,
                            &RemoteAddr,
                            EFI_IP_PROTO_UDP,
                            0
                            );

      Instance->Configured = TRUE;
    }
  } else {
    //
    // UdpConfigData is NULL, reset the instance.
    //
    Instance->Configured  = FALSE;
    Instance->IsNoMapping = FALSE;

    //
    // Reset the Ip instance wrapped in the IpInfo.
    //
    IpIoConfigIp (Instance->IpInfo, NULL);

    //
    // Cancel all the user tokens.
    //
    Status = Instance->Udp6Proto.Cancel (&Instance->Udp6Proto, NULL);

    //
    // Remove the buffered RxData for this instance.
    //
    Udp6FlushRcvdDgram (Instance);

    ASSERT (IsListEmpty (&Instance->DeliveredDgramQue));
  }

  Status = Udp6SetVariableData (Instance->Udp6Service);

ON_EXIT:

  gBS->RestoreTPL (OldTpl);

  return Status;
}


/**
  This function is used to enable and disable the multicast group filtering.

  @param[in]  This               Pointer to the EFI_UDP6_PROTOCOL instance.
  @param[in]  JoinFlag           Set to TRUE to join a multicast group. Set to
                                 FALSE to leave one or all multicast groups.
  @param[in]  MulticastAddress   Pointer to multicast group address to join or
                                 leave. This parameter is optional and may be NULL.

  @retval EFI_SUCCESS            The operation completed successfully.
  @retval EFI_NOT_STARTED        The EFI UDPv6 Protocol instance has not been
                                 started.
  @retval EFI_OUT_OF_RESOURCES   Could not allocate resources to join the group.
  @retval EFI_INVALID_PARAMETER  One or more of the following conditions is TRUE:
                                 This is NULL.
                                 JoinFlag is TRUE and MulticastAddress is NULL.
                                 JoinFlag is TRUE and *MulticastAddress is not a
                                 valid  multicast address.
  @retval EFI_ALREADY_STARTED    The group address is already in the group table
                                 (when JoinFlag is TRUE).
  @retval EFI_NOT_FOUND          The group address is not in the group table (when
                                 JoinFlag is FALSE).
  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.

**/
EFI_STATUS
EFIAPI
Udp6Groups (
  IN EFI_UDP6_PROTOCOL  *This,
  IN BOOLEAN            JoinFlag,
  IN EFI_IPv6_ADDRESS   *MulticastAddress OPTIONAL
  )
{
  EFI_STATUS          Status;
  UDP6_INSTANCE_DATA  *Instance;
  EFI_IP6_PROTOCOL    *Ip;
  EFI_TPL             OldTpl;
  EFI_IPv6_ADDRESS    *McastIp;

  if ((This == NULL) || (JoinFlag && (MulticastAddress == NULL))) {
    return EFI_INVALID_PARAMETER;
  }

  McastIp = NULL;

  if (JoinFlag) {
    if (!IP6_IS_MULTICAST (MulticastAddress)) {
      return EFI_INVALID_PARAMETER;
    }

    McastIp = AllocateCopyPool (sizeof (EFI_IPv6_ADDRESS), MulticastAddress);
    if (McastIp == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
  }

  Instance = UDP6_INSTANCE_DATA_FROM_THIS (This);
  if (!Instance->Configured) {
    return EFI_NOT_STARTED;
  }

  Ip      = Instance->IpInfo->Ip.Ip6;

  OldTpl  = gBS->RaiseTPL (TPL_CALLBACK);

  //
  // Invoke the Ip instance the Udp6 instance consumes to do the group operation.
  //
  Status = Ip->Groups (Ip, JoinFlag, MulticastAddress);

  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Keep a local copy of the configured multicast IPs because IpIo receives
  // datagrams from the 0 station address IP instance and then UDP delivers to
  // the matched instance. This copy of multicast IPs is used to avoid receive
  // the mutlicast datagrams destinated to multicast IPs the other instances configured.
  //
  if (JoinFlag) {

    Status = NetMapInsertTail (&Instance->McastIps, (VOID *) McastIp, NULL);
  } else {

    NetMapIterate (&Instance->McastIps, Udp6LeaveGroup, MulticastAddress);
  }

ON_EXIT:

  gBS->RestoreTPL (OldTpl);

  if (EFI_ERROR (Status)) {
    if (McastIp != NULL) {
      FreePool (McastIp);
    }
  }

  return Status;
}



/**
  This function places a sending request to this instance of the EFI UDPv6 Protocol,
  alongside the transmit data that was filled by the user.

  @param[in]  This               Pointer to the EFI_UDP6_PROTOCOL instance.
  @param[in]  Token              Pointer to the completion token that will be
                                 placed into the transmit queue.

  @retval EFI_SUCCESS            The data was queued for transmission.
  @retval EFI_NOT_STARTED        This EFI UDPv6 Protocol instance has not been
                                 started.
  @retval EFI_NO_MAPPING         The under-layer IPv6 driver was responsible for
                                 choosing a source address for this instance, but
                                 no  source address was available for use.
  @retval EFI_INVALID_PARAMETER  One or more of the following are TRUE:
                                 This is NULL.
                                 Token is NULL. Token.Event is NULL.
                                 Token.Packet.TxData is NULL.
                                 Token.Packet.TxData.FragmentCount is zero.
                                 Token.Packet.TxData.DataLength is not equal to the
                                 sum of fragment lengths.
                                 One or more of the
                                 Token.Packet.TxData.FragmentTable[].FragmentLength
                                 fields is zero.
                                 One or more of the
                                 Token.Packet.TxData.FragmentTable[].FragmentBuffer
                                 fields is NULL. One or more of the
                                 Token.Packet.TxData.UdpSessionData.DestinationAddres
                                 are not valid unicast IPv6
                                 addresses if the  UdpSessionData is not NULL.
                                 Token.Packet.TxData.UdpSessionData.
                                 DestinationAddress is NULL
                                 Token.Packet.TxData.UdpSessionData.
                                 DestinatioPort
                                 is zero.
                                 Token.Packet.TxData.UdpSessionData is NULL and this
                                 instance's UdpConfigData.RemoteAddress  is unspecified.
  @retval EFI_ACCESS_DENIED      The transmit completion token with the same
                                 Token.Event is already in the transmit queue.
  @retval EFI_NOT_READY          The completion token could not be queued because
                                 the transmit queue is full.
  @retval EFI_OUT_OF_RESOURCES   Could not queue the transmit data.
  @retval EFI_NOT_FOUND          There is no route to the destination network or
                                 address.
  @retval EFI_BAD_BUFFER_SIZE    The data length is greater than the maximum UDP
                                 packet size. Or, the length of the IP header + UDP
                                 header + data length is greater than MTU if
                                 DoNotFragment is TRUE.

**/
EFI_STATUS
EFIAPI
Udp6Transmit (
  IN EFI_UDP6_PROTOCOL          *This,
  IN EFI_UDP6_COMPLETION_TOKEN  *Token
  )
{
  EFI_STATUS              Status;
  UDP6_INSTANCE_DATA      *Instance;
  EFI_TPL                 OldTpl;
  NET_BUF                 *Packet;
  EFI_UDP_HEADER          *Udp6Header;
  EFI_UDP6_CONFIG_DATA    *ConfigData;
  EFI_IPv6_ADDRESS        Source;
  EFI_IPv6_ADDRESS        Destination;
  EFI_UDP6_TRANSMIT_DATA  *TxData;
  EFI_UDP6_SESSION_DATA   *UdpSessionData;
  UDP6_SERVICE_DATA       *Udp6Service;
  IP_IO_OVERRIDE          Override;
  UINT16                  HeadSum;
  EFI_IP_ADDRESS          IpDestAddr;

  if ((This == NULL) || (Token == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = UDP6_INSTANCE_DATA_FROM_THIS (This);

  if (!Instance->Configured) {
    return EFI_NOT_STARTED;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  //
  // Validate the Token, if the token is invalid return the error code.
  //
  Status = Udp6ValidateTxToken (Instance, Token);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  if (EFI_ERROR (NetMapIterate (&Instance->TxTokens, Udp6TokenExist, Token)) ||
      EFI_ERROR (NetMapIterate (&Instance->RxTokens, Udp6TokenExist, Token))
      ){
    //
    // Try to find a duplicate token in the two token maps, if found, return
    // EFI_ACCESS_DENIED.
    //
    Status = EFI_ACCESS_DENIED;
    goto ON_EXIT;
  }

  TxData = Token->Packet.TxData;

  //
  // Create a net buffer to hold the user buffer and the udp header.
  //
  Packet = NetbufFromExt (
             (NET_FRAGMENT *) TxData->FragmentTable,
             TxData->FragmentCount,
             UDP6_HEADER_SIZE,
             0,
             Udp6NetVectorExtFree,
             NULL
             );
  if (Packet == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  //
  // Store the IpIo in ProtoData.
  //
  Udp6Service                        = Instance->Udp6Service;
  *((UINTN *) &Packet->ProtoData[0]) = (UINTN) (Udp6Service->IpIo);

  Udp6Header = (EFI_UDP_HEADER *) NetbufAllocSpace (Packet, UDP6_HEADER_SIZE, TRUE);
  ASSERT (Udp6Header != NULL);
  ConfigData = &Instance->ConfigData;

  //
  // Fill the udp header.
  //
  Udp6Header->SrcPort      = HTONS (ConfigData->StationPort);
  Udp6Header->DstPort      = HTONS (ConfigData->RemotePort);
  Udp6Header->Length       = HTONS ((UINT16) Packet->TotalSize);
  Udp6Header->Checksum     = 0;
  //
  // Set the UDP Header in NET_BUF, this UDP header is for IP6 can fast get the
  // Udp header for pseudoHeadCheckSum.
  //
  Packet->Udp    = Udp6Header;
  UdpSessionData = TxData->UdpSessionData;

  if (UdpSessionData != NULL) {
    //
    // Set the Destination according to the specified
    // UdpSessionData.
    //

    if (UdpSessionData->DestinationPort != 0) {
      Udp6Header->DstPort = HTONS (UdpSessionData->DestinationPort);
    }

    IP6_COPY_ADDRESS (&Source, &ConfigData->StationAddress);
    if (!NetIp6IsUnspecifiedAddr (&UdpSessionData->DestinationAddress)) {
      IP6_COPY_ADDRESS (&Destination, &UdpSessionData->DestinationAddress);
    } else {
      IP6_COPY_ADDRESS (&Destination, &ConfigData->RemoteAddress);
    }

    //
    //Calculate the pseudo head checksum using the overridden parameters.
    //
    if (!NetIp6IsUnspecifiedAddr (&ConfigData->StationAddress)) {
      HeadSum = NetIp6PseudoHeadChecksum (
                  &Source,
                  &Destination,
                  EFI_IP_PROTO_UDP,
                  0
                  );

      //
      // calculate the checksum.
      //
      Udp6Header->Checksum = Udp6Checksum (Packet, HeadSum);
      if (Udp6Header->Checksum == 0) {
        //
        // If the calculated checksum is 0, fill the Checksum field with all ones.
        //
        Udp6Header->Checksum = 0XFFFF;
      }
    } else {
      //
      // Set the checksum is zero if the ConfigData->StationAddress is unspcified
      // and the Ipv6 will fill the correct value of this checksum.
      //
      Udp6Header->Checksum = 0;

    }
  } else {
    //
    // UdpSessionData is NULL, use the address and port information previously configured.
    //
    IP6_COPY_ADDRESS (&Destination, &ConfigData->RemoteAddress);

    HeadSum = Instance->HeadSum;
    //
    // calculate the checksum.
    //
    Udp6Header->Checksum = Udp6Checksum (Packet, HeadSum);
    if (Udp6Header->Checksum == 0) {
      //
      // If the calculated checksum is 0, fill the Checksum field with all ones.
      //
      Udp6Header->Checksum = 0xffff;
    }
  }



  //
  // Fill the IpIo Override data.
  //
  Override.Ip6OverrideData.Protocol  = EFI_IP_PROTO_UDP;
  Override.Ip6OverrideData.HopLimit  = ConfigData->HopLimit;
  Override.Ip6OverrideData.FlowLabel = 0;

  //
  // Save the token into the TxToken map.
  //
  Status = NetMapInsertTail (&Instance->TxTokens, Token, Packet);
  if (EFI_ERROR (Status)) {
    goto FREE_PACKET;
  }

  //
  // Send out this datagram through IpIo.
  //
  if (UdpSessionData != NULL){
    IP6_COPY_ADDRESS (&(IpDestAddr.v6), &Destination);
  } else {
    ZeroMem (&IpDestAddr.v6, sizeof (EFI_IPv6_ADDRESS));
  }

  Status = IpIoSend (
             Udp6Service->IpIo,
             Packet,
             Instance->IpInfo,
             Instance,
             Token,
             &IpDestAddr,
             &Override
             );
  if (EFI_ERROR (Status)) {
    //
    // Remove this token from the TxTokens.
    //
    Udp6RemoveToken (&Instance->TxTokens, Token);
  }

FREE_PACKET:

  NetbufFree (Packet);

ON_EXIT:

  gBS->RestoreTPL (OldTpl);

  return Status;
}


/**
  This function places a completion token into the receive packet queue. This function
  is always asynchronous.

  @param[in]  This               Pointer to the EFI_UDP6_PROTOCOL instance.
  @param[in]  Token              Pointer to a token that is associated with the
                                 receive data descriptor.

  @retval EFI_SUCCESS            The receive completion token was cached.
  @retval EFI_NOT_STARTED        This EFI UDPv6 Protocol instance has not been
                                 started.
  @retval EFI_NO_MAPPING         When using a default address, configuration (DHCP,
                                 BOOTP, RARP, etc.) is not finished yet.
  @retval EFI_INVALID_PARAMETER  One or more of the following conditions is TRUE:
                                 This is NULL. Token is NULL. Token.Event is NULL.
  @retval EFI_OUT_OF_RESOURCES   The receive completion token could not be queued
                                 due to a lack of system resources (usually
                                 memory).
  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.
                                 The EFI UDPv6 Protocol instance has been reset to
                                 startup defaults.
  @retval EFI_ACCESS_DENIED      A receive completion token with the same
                                 Token.Event is already in the receive queue.
  @retval EFI_NOT_READY          The receive request could not be queued because
                                 the receive  queue is full.

**/
EFI_STATUS
EFIAPI
Udp6Receive (
  IN EFI_UDP6_PROTOCOL          *This,
  IN EFI_UDP6_COMPLETION_TOKEN  *Token
  )
{
  EFI_STATUS          Status;
  UDP6_INSTANCE_DATA  *Instance;
  EFI_TPL             OldTpl;

  if ((This == NULL) || (Token == NULL) || (Token->Event == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = UDP6_INSTANCE_DATA_FROM_THIS (This);

  if (!Instance->Configured) {
    return EFI_NOT_STARTED;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  if (EFI_ERROR (NetMapIterate (&Instance->RxTokens, Udp6TokenExist, Token)) ||
      EFI_ERROR (NetMapIterate (&Instance->TxTokens, Udp6TokenExist, Token))
      ){
    //
    // Return EFI_ACCESS_DENIED if the specified token is already in the TxTokens or
    // RxTokens map.
    //
    Status = EFI_ACCESS_DENIED;
    goto ON_EXIT;
  }

  Token->Packet.RxData = NULL;

  //
  // Save the token into the RxTokens map.
  //
  Status = NetMapInsertTail (&Instance->RxTokens, Token, NULL);
  if (EFI_ERROR (Status)) {
    Status = EFI_NOT_READY;
    goto ON_EXIT;
  }

  //
  // If there is an icmp error, report it.
  //
  Udp6ReportIcmpError (Instance);

  //
  // Try to delivered the received datagrams.
  //
  Udp6InstanceDeliverDgram (Instance);

  //
  // Dispatch the DPC queued by the NotifyFunction of Token->Event.
  //
  DispatchDpc ();

ON_EXIT:

  gBS->RestoreTPL (OldTpl);

  return Status;
}


/**
  This function is used to abort a pending transmit or receive request.

  @param[in]  This               Pointer to the EFI_UDP6_PROTOCOL instance.
  @param[in]  Token              Pointer to a token that has been issued by
                                 EFI_UDP6_PROTOCOL.Transmit() or
                                 EFI_UDP6_PROTOCOL.Receive(). This parameter is
                                 optional and may be NULL.

  @retval EFI_SUCCESS            The asynchronous I/O request was aborted, and
                                 Token.Event was  signaled. When Token is NULL, all
                                 pending requests are aborted and their events are
                                 signaled.
  @retval EFI_INVALID_PARAMETER  This is NULL.
  @retval EFI_NOT_STARTED        This instance has not been started.
  @retval EFI_NO_MAPPING         When using the default address, configuration
                                 (DHCP, BOOTP, RARP, etc.) is not finished yet.
  @retval EFI_NOT_FOUND          When Token is not NULL, the asynchronous I/O
                                 request is not found in the transmit or receive
                                 queue. It is either completed or not issued by
                                 Transmit() or Receive().

**/
EFI_STATUS
EFIAPI
Udp6Cancel (
  IN EFI_UDP6_PROTOCOL          *This,
  IN EFI_UDP6_COMPLETION_TOKEN  *Token OPTIONAL
  )
{
  EFI_STATUS          Status;
  UDP6_INSTANCE_DATA  *Instance;
  EFI_TPL             OldTpl;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = UDP6_INSTANCE_DATA_FROM_THIS (This);

  if (!Instance->Configured) {
    return EFI_NOT_STARTED;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  //
  // Cancle the tokens specified by Token for this instance.
  //
  Status = Udp6InstanceCancelToken (Instance, Token);

  //
  // Dispatch the DPC queued by the NotifyFunction of the canceled token's events.
  //
  DispatchDpc ();

  gBS->RestoreTPL (OldTpl);

  return Status;
}


/**
  This function can be used by network drivers and applications to increase the rate that
  data packets are moved between the communications device and the transmit/receive queues.

  @param[in] This                Pointer to the EFI_UDP6_PROTOCOL instance.

  @retval EFI_SUCCESS            Incoming or outgoing data was processed.
  @retval EFI_INVALID_PARAMETER  This is NULL.
  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.
  @retval EFI_TIMEOUT            Data was dropped out of the transmit and/or
                                 receive queue.

**/
EFI_STATUS
EFIAPI
Udp6Poll (
  IN EFI_UDP6_PROTOCOL  *This
  )
{
  UDP6_INSTANCE_DATA  *Instance;
  EFI_IP6_PROTOCOL    *Ip;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = UDP6_INSTANCE_DATA_FROM_THIS (This);
  Ip       = Instance->IpInfo->Ip.Ip6;

  //
  // Invode the Ip instance consumed by the udp instance to do the poll operation.
  //
  return Ip->Poll (Ip);
}
