/** @file
  Support functions implementation for UefiPxeBc Driver.

  Copyright (c) 2007 - 2016, 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 "PxeBcImpl.h"


/**
  Flush the previous configration using the new station Ip address.

  @param[in]   Private        The pointer to the PxeBc private data.
  @param[in]   StationIp      The pointer to the station Ip address.
  @param[in]   SubnetMask     The pointer to the subnet mask address for v4.

  @retval EFI_SUCCESS         Successfully flushed the previous configuration.
  @retval Others              Failed to flush using the new station Ip.

**/
EFI_STATUS
PxeBcFlushStationIp (
  PXEBC_PRIVATE_DATA       *Private,
  EFI_IP_ADDRESS           *StationIp,
  EFI_IP_ADDRESS           *SubnetMask     OPTIONAL
  )
{
  EFI_PXE_BASE_CODE_MODE   *Mode;
  EFI_STATUS               Status;

  ASSERT (StationIp != NULL);

  Mode   = Private->PxeBc.Mode;
  Status = EFI_SUCCESS;

  if (Mode->UsingIpv6) {

    CopyMem (&Private->Udp6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));
    CopyMem (&Private->Ip6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));

    //
    // Reconfigure the Ip6 instance to capture background ICMP6 packets with new station Ip address.
    //
    Private->Ip6->Cancel (Private->Ip6, &Private->Icmp6Token);
    Private->Ip6->Configure (Private->Ip6, NULL);

    Status = Private->Ip6->Configure (Private->Ip6, &Private->Ip6CfgData);
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }

    Status = Private->Ip6->Receive (Private->Ip6, &Private->Icmp6Token);
  } else {
    ASSERT (SubnetMask != NULL);
    CopyMem (&Private->Udp4CfgData.StationAddress, StationIp, sizeof (EFI_IPv4_ADDRESS));
    CopyMem (&Private->Udp4CfgData.SubnetMask, SubnetMask, sizeof (EFI_IPv4_ADDRESS));
    CopyMem (&Private->Ip4CfgData.StationAddress, StationIp, sizeof (EFI_IPv4_ADDRESS));
    CopyMem (&Private->Ip4CfgData.SubnetMask, SubnetMask, sizeof (EFI_IPv4_ADDRESS));

    //
    // Reconfigure the Ip4 instance to capture background ICMP packets with new station Ip address.
    //
    Private->Ip4->Cancel (Private->Ip4, &Private->IcmpToken);
    Private->Ip4->Configure (Private->Ip4, NULL);

    Status = Private->Ip4->Configure (Private->Ip4, &Private->Ip4CfgData);
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }

    Status = Private->Ip4->Receive (Private->Ip4, &Private->IcmpToken);
  }

ON_EXIT:
  return Status;
}


/**
  Notify the callback function when an event is triggered.

  @param[in]  Event           The triggered event.
  @param[in]  Context         The opaque parameter to the function.

**/
VOID
EFIAPI
PxeBcCommonNotify (
  IN EFI_EVENT           Event,
  IN VOID                *Context
  )
{
  *((BOOLEAN *) Context) = TRUE;
}


/**
  Do arp resolution from arp cache in PxeBcMode.

  @param  Mode           The pointer to EFI_PXE_BASE_CODE_MODE.
  @param  Ip4Addr        The Ip4 address for resolution.
  @param  MacAddress     The resoluted MAC address if the resolution is successful.
                         The value is undefined if the resolution fails.

  @retval TRUE           Found an matched entry.
  @retval FALSE          Did not find a matched entry.

**/
BOOLEAN
PxeBcCheckArpCache (
  IN  EFI_PXE_BASE_CODE_MODE    *Mode,
  IN  EFI_IPv4_ADDRESS          *Ip4Addr,
  OUT EFI_MAC_ADDRESS           *MacAddress
  )
{
  UINT32       Index;

  ASSERT (!Mode->UsingIpv6);

  //
  // Check whether the current Arp cache in mode data contains this information or not.
  //
  for (Index = 0; Index < Mode->ArpCacheEntries; Index++) {
    if (EFI_IP4_EQUAL (&Mode->ArpCache[Index].IpAddr.v4, Ip4Addr)) {
      CopyMem (
        MacAddress,
        &Mode->ArpCache[Index].MacAddr,
        sizeof (EFI_MAC_ADDRESS)
        );
      return TRUE;
    }
  }

  return FALSE;
}


/**
  Update the arp cache periodically.

  @param  Event              The pointer to EFI_PXE_BC_PROTOCOL.
  @param  Context            Context of the timer event.

**/
VOID
EFIAPI
PxeBcArpCacheUpdate (
  IN EFI_EVENT            Event,
  IN VOID                 *Context
  )
{
  PXEBC_PRIVATE_DATA      *Private;
  EFI_PXE_BASE_CODE_MODE  *Mode;
  EFI_ARP_FIND_DATA       *ArpEntry;
  UINT32                  EntryLength;
  UINT32                  EntryCount;
  UINT32                  Index;
  EFI_STATUS              Status;

  Private = (PXEBC_PRIVATE_DATA *) Context;
  Mode    = Private->PxeBc.Mode;

  ASSERT (!Mode->UsingIpv6);

  //
  // Get the current Arp cache from Arp driver.
  //
  Status = Private->Arp->Find (
                           Private->Arp,
                           TRUE,
                           NULL,
                           &EntryLength,
                           &EntryCount,
                           &ArpEntry,
                           TRUE
                           );
  if (EFI_ERROR (Status)) {
    return;
  }

  //
  // Update the Arp cache in mode data.
  //
  Mode->ArpCacheEntries = MIN (EntryCount, EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES);

  for (Index = 0; Index < Mode->ArpCacheEntries; Index++) {
    CopyMem (
      &Mode->ArpCache[Index].IpAddr,
      ArpEntry + 1,
      ArpEntry->SwAddressLength
      );
    CopyMem (
      &Mode->ArpCache[Index].MacAddr,
      (UINT8 *) (ArpEntry + 1) + ArpEntry->SwAddressLength,
      ArpEntry->HwAddressLength
      );
    ArpEntry = (EFI_ARP_FIND_DATA *) ((UINT8 *) ArpEntry + EntryLength);
  }
}


/**
  Notify function to handle the received ICMP message in DPC.

  @param  Context               The PXEBC private data.

**/
VOID
EFIAPI
PxeBcIcmpErrorDpcHandle (
  IN VOID                      *Context
  )
{
  EFI_STATUS                   Status;
  EFI_IP4_RECEIVE_DATA         *RxData;
  EFI_IP4_PROTOCOL             *Ip4;
  PXEBC_PRIVATE_DATA           *Private;
  EFI_PXE_BASE_CODE_MODE       *Mode;
  UINT8                        Type;
  UINTN                        Index;
  UINT32                       CopiedLen;
  UINT8                        *IcmpError;

  Private = (PXEBC_PRIVATE_DATA *) Context;
  Mode    = &Private->Mode;
  Status  = Private->IcmpToken.Status;
  RxData  = Private->IcmpToken.Packet.RxData;
  Ip4     = Private->Ip4;

  ASSERT (!Mode->UsingIpv6);

  if (Status == EFI_ABORTED) {
    //
    // It's triggered by user cancellation.
    //
    return;
  }

  if (RxData == NULL) {
    goto ON_EXIT;
  }

  if (Status != EFI_ICMP_ERROR) {
    //
    // The return status should be recognized as EFI_ICMP_ERROR.
    //
    gBS->SignalEvent (RxData->RecycleSignal);
    goto ON_EXIT;
  }

  if (EFI_IP4 (RxData->Header->SourceAddress) != 0 &&
      (NTOHL (Mode->SubnetMask.Addr[0]) != 0) &&
      IP4_NET_EQUAL (NTOHL(Mode->StationIp.Addr[0]), EFI_NTOHL (RxData->Header->SourceAddress), NTOHL (Mode->SubnetMask.Addr[0])) &&
      !NetIp4IsUnicast (EFI_NTOHL (RxData->Header->SourceAddress), NTOHL (Mode->SubnetMask.Addr[0]))) {
    //
    // The source address of the received packet should be a valid unicast address.
    //
    gBS->SignalEvent (RxData->RecycleSignal);
    goto ON_EXIT;
  }

  if (!EFI_IP4_EQUAL (&RxData->Header->DestinationAddress, &Mode->StationIp.v4)) {
    //
    // The destination address of the received packet should be equal to the host address.
    //
    gBS->SignalEvent (RxData->RecycleSignal);
    goto ON_EXIT;
  }

  if (RxData->Header->Protocol != EFI_IP_PROTO_ICMP) {
    //
    // The protocol value in the header of the receveid packet should be EFI_IP_PROTO_ICMP.
    //
    gBS->SignalEvent (RxData->RecycleSignal);
    goto ON_EXIT;
  }

  Type = *((UINT8 *) RxData->FragmentTable[0].FragmentBuffer);

  if (Type != ICMP_DEST_UNREACHABLE &&
      Type != ICMP_SOURCE_QUENCH &&
      Type != ICMP_REDIRECT &&
      Type != ICMP_TIME_EXCEEDED &&
      Type != ICMP_PARAMETER_PROBLEM) {
    //
    // The type of the receveid ICMP message should be ICMP_ERROR_MESSAGE.
    //
    gBS->SignalEvent (RxData->RecycleSignal);
    goto ON_EXIT;
  }

  //
  // Copy the right ICMP error message into mode data.
  //
  CopiedLen = 0;
  IcmpError = (UINT8 *) &Mode->IcmpError;

  for (Index = 0; Index < RxData->FragmentCount; Index++) {
    CopiedLen += RxData->FragmentTable[Index].FragmentLength;
    if (CopiedLen <= sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR)) {
      CopyMem (
        IcmpError,
        RxData->FragmentTable[Index].FragmentBuffer,
        RxData->FragmentTable[Index].FragmentLength
        );
    } else {
      CopyMem (
        IcmpError,
        RxData->FragmentTable[Index].FragmentBuffer,
        CopiedLen - sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR)
        );
    }
    IcmpError += CopiedLen;
  }

ON_EXIT:
  Private->IcmpToken.Status = EFI_NOT_READY;
  Ip4->Receive (Ip4, &Private->IcmpToken);
}


/**
  Callback function to update the latest ICMP6 error message.

  @param  Event                 The event signalled.
  @param  Context               The context passed in using the event notifier.

**/
VOID
EFIAPI
PxeBcIcmpErrorUpdate (
  IN EFI_EVENT            Event,
  IN VOID                 *Context
  )
{
  QueueDpc (TPL_CALLBACK, PxeBcIcmpErrorDpcHandle, Context);
}


/**
  Notify function to handle the received ICMP6 message in DPC.

  @param  Context               The PXEBC private data.

**/
VOID
EFIAPI
PxeBcIcmp6ErrorDpcHandle (
  IN VOID                 *Context
  )
{
  PXEBC_PRIVATE_DATA      *Private;
  EFI_IP6_RECEIVE_DATA    *RxData;
  EFI_IP6_PROTOCOL        *Ip6;
  EFI_PXE_BASE_CODE_MODE  *Mode;
  EFI_STATUS              Status;
  UINTN                   Index;
  UINT8                   Type;
  UINT32                  CopiedLen;
  UINT8                   *Icmp6Error;

  Private = (PXEBC_PRIVATE_DATA *) Context;
  Mode    = &Private->Mode;
  Status  = Private->Icmp6Token.Status;
  RxData  = Private->Icmp6Token.Packet.RxData;
  Ip6     = Private->Ip6;

  ASSERT (Mode->UsingIpv6);

  if (Status == EFI_ABORTED) {
    //
    // It's triggered by user cancellation.
    //
    return;
  }

  if (RxData == NULL) {
    goto ON_EXIT;
  }

  if (Status != EFI_ICMP_ERROR) {
    //
    // The return status should be recognized as EFI_ICMP_ERROR.
    //
    gBS->SignalEvent (RxData->RecycleSignal);
    goto ON_EXIT;
  }

  if (!NetIp6IsValidUnicast (&RxData->Header->SourceAddress)) {
    //
    // The source address of the received packet should be a valid unicast address.
    //
    gBS->SignalEvent (RxData->RecycleSignal);
    goto ON_EXIT;
  }

  if (!NetIp6IsUnspecifiedAddr (&Mode->StationIp.v6) &&
      !EFI_IP6_EQUAL (&RxData->Header->DestinationAddress, &Mode->StationIp.v6)) {
    //
    // The destination address of the received packet should be equal to the host address.
    //
    gBS->SignalEvent (RxData->RecycleSignal);
    goto ON_EXIT;
  }

  if (RxData->Header->NextHeader != IP6_ICMP) {
    //
    // The nextheader in the header of the receveid packet should be IP6_ICMP.
    //
    gBS->SignalEvent (RxData->RecycleSignal);
    goto ON_EXIT;
  }

  Type = *((UINT8 *) RxData->FragmentTable[0].FragmentBuffer);

  if (Type != ICMP_V6_DEST_UNREACHABLE &&
      Type != ICMP_V6_PACKET_TOO_BIG &&
      Type != ICMP_V6_PACKET_TOO_BIG &&
      Type != ICMP_V6_PARAMETER_PROBLEM) {
    //
    // The type of the receveid packet should be an ICMP6 error message.
    //
    gBS->SignalEvent (RxData->RecycleSignal);
    goto ON_EXIT;
  }

  //
  // Copy the right ICMP6 error message into mode data.
  //
  CopiedLen  = 0;
  Icmp6Error = (UINT8 *) &Mode->IcmpError;

  for (Index = 0; Index < RxData->FragmentCount; Index++) {
    CopiedLen += RxData->FragmentTable[Index].FragmentLength;
    if (CopiedLen <= sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR)) {
      CopyMem (
        Icmp6Error,
        RxData->FragmentTable[Index].FragmentBuffer,
        RxData->FragmentTable[Index].FragmentLength
        );
    } else {
      CopyMem (
        Icmp6Error,
        RxData->FragmentTable[Index].FragmentBuffer,
        CopiedLen - sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR)
        );
    }
    Icmp6Error += CopiedLen;
  }

ON_EXIT:
  Private->Icmp6Token.Status = EFI_NOT_READY;
  Ip6->Receive (Ip6, &Private->Icmp6Token);
}


/**
  Callback function to update the latest ICMP6 error message.

  @param  Event                 The event signalled.
  @param  Context               The context passed in using the event notifier.

**/
VOID
EFIAPI
PxeBcIcmp6ErrorUpdate (
  IN EFI_EVENT               Event,
  IN VOID                    *Context
  )
{
  QueueDpc (TPL_CALLBACK, PxeBcIcmp6ErrorDpcHandle, Context);
}


/**
  This function is to configure a UDPv4 instance for UdpWrite.

  @param[in]       Udp4                 The pointer to EFI_UDP4_PROTOCOL.
  @param[in]       StationIp            The pointer to the station address.
  @param[in]       SubnetMask           The pointer to the subnet mask.
  @param[in]       Gateway              The pointer to the gateway address.
  @param[in, out]  SrcPort              The pointer to the source port.
  @param[in]       DoNotFragment        If TRUE, fragment is not enabled.
                                        Otherwise, fragment is enabled.
  @param[in]       Ttl                  The time to live field of the IP header. 
  @param[in]       ToS                  The type of service field of the IP header.

  @retval          EFI_SUCCESS          Successfully configured this instance.
  @retval          Others               Failed to configure this instance.

**/
EFI_STATUS
PxeBcConfigUdp4Write (
  IN     EFI_UDP4_PROTOCOL  *Udp4,
  IN     EFI_IPv4_ADDRESS   *StationIp,
  IN     EFI_IPv4_ADDRESS   *SubnetMask,
  IN     EFI_IPv4_ADDRESS   *Gateway,
  IN OUT UINT16             *SrcPort,
  IN     BOOLEAN            DoNotFragment,
  IN     UINT8              Ttl,
  IN     UINT8              ToS
  )
{
  EFI_UDP4_CONFIG_DATA  Udp4CfgData;
  EFI_STATUS            Status;

  ZeroMem (&Udp4CfgData, sizeof (Udp4CfgData));

  Udp4CfgData.TransmitTimeout    = PXEBC_DEFAULT_LIFETIME;
  Udp4CfgData.ReceiveTimeout     = PXEBC_DEFAULT_LIFETIME;
  Udp4CfgData.TypeOfService      = ToS;
  Udp4CfgData.TimeToLive         = Ttl;
  Udp4CfgData.AllowDuplicatePort = TRUE;
  Udp4CfgData.DoNotFragment      = DoNotFragment;

  CopyMem (&Udp4CfgData.StationAddress, StationIp, sizeof (*StationIp));
  CopyMem (&Udp4CfgData.SubnetMask, SubnetMask, sizeof (*SubnetMask));

  Udp4CfgData.StationPort = *SrcPort;

  //
  // Reset the UDPv4 instance.
  //
  Udp4->Configure (Udp4, NULL);

  Status = Udp4->Configure (Udp4, &Udp4CfgData);
  if (!EFI_ERROR (Status) && !EFI_IP4_EQUAL (Gateway, &mZeroIp4Addr)) {
    //
    // The basic configuration is OK, need to add the default route entry
    //
    Status = Udp4->Routes (Udp4, FALSE, &mZeroIp4Addr, &mZeroIp4Addr, Gateway);
    if (EFI_ERROR (Status)) {
      Udp4->Configure (Udp4, NULL);
    }
  }

  if (!EFI_ERROR (Status) && *SrcPort == 0) {
    Udp4->GetModeData (Udp4, &Udp4CfgData, NULL, NULL, NULL);
    *SrcPort = Udp4CfgData.StationPort;
  }

  return Status;
}


/**
  This function is to configure a UDPv6 instance for UdpWrite.

  @param[in]       Udp6                 The pointer to EFI_UDP6_PROTOCOL.
  @param[in]       StationIp            The pointer to the station address.
  @param[in, out]  SrcPort              The pointer to the source port.

  @retval          EFI_SUCCESS          Successfully configured this instance.
  @retval          Others               Failed to configure this instance.

**/
EFI_STATUS
PxeBcConfigUdp6Write (
  IN     EFI_UDP6_PROTOCOL  *Udp6,
  IN     EFI_IPv6_ADDRESS   *StationIp,
  IN OUT UINT16             *SrcPort
  )
{
  EFI_UDP6_CONFIG_DATA  CfgData;
  EFI_STATUS            Status;

  ZeroMem (&CfgData, sizeof (EFI_UDP6_CONFIG_DATA));

  CfgData.ReceiveTimeout     = PXEBC_DEFAULT_LIFETIME;
  CfgData.TransmitTimeout    = PXEBC_DEFAULT_LIFETIME;
  CfgData.HopLimit           = PXEBC_DEFAULT_HOPLIMIT;
  CfgData.AllowDuplicatePort = TRUE;
  CfgData.StationPort        = *SrcPort;

  CopyMem (&CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));

  //
  // Reset the UDPv6 instance.
  //
  Udp6->Configure (Udp6, NULL);

  Status = Udp6->Configure (Udp6, &CfgData);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (!EFI_ERROR (Status) && *SrcPort == 0) {
    Udp6->GetModeData (Udp6, &CfgData, NULL, NULL, NULL);
    *SrcPort = CfgData.StationPort;
  }

  return Status;
}


/**
  This function is to configure a UDPv4 instance for UdpWrite.

  @param[in]       Udp4                 The pointer to EFI_UDP4_PROTOCOL.
  @param[in]       Session              The pointer to the UDP4 session data.
  @param[in]       TimeoutEvent         The event for timeout.
  @param[in]       Gateway              The pointer to the gateway address.
  @param[in]       HeaderSize           An optional field which may be set to the length of a header
                                        at HeaderPtr to be prefixed to the data at BufferPtr.
  @param[in]       HeaderPtr            If HeaderSize is not NULL, a pointer to a header to be
                                        prefixed to the data at BufferPtr.
  @param[in]       BufferSize           A pointer to the size of the data at BufferPtr.
  @param[in]       BufferPtr            A pointer to the data to be written.

  @retval          EFI_SUCCESS          Successfully send out data using Udp4Write.
  @retval          Others               Failed to send out data.

**/
EFI_STATUS
PxeBcUdp4Write (
  IN EFI_UDP4_PROTOCOL       *Udp4,
  IN EFI_UDP4_SESSION_DATA   *Session,
  IN EFI_EVENT               TimeoutEvent,
  IN EFI_IPv4_ADDRESS        *Gateway      OPTIONAL,
  IN UINTN                   *HeaderSize   OPTIONAL,
  IN VOID                    *HeaderPtr    OPTIONAL,
  IN UINTN                   *BufferSize,
  IN VOID                    *BufferPtr
  )
{
  EFI_UDP4_COMPLETION_TOKEN Token;
  EFI_UDP4_TRANSMIT_DATA    *TxData;
  UINT32                    TxLength;
  UINT32                    FragCount;
  UINT32                    DataLength;
  BOOLEAN                   IsDone;
  EFI_STATUS                Status;

  //
  // Arrange one fragment buffer for data, and another fragment buffer for header if has.
  //
  FragCount = (HeaderSize != NULL) ? 2 : 1;
  TxLength  = sizeof (EFI_UDP4_TRANSMIT_DATA) + (FragCount - 1) * sizeof (EFI_UDP4_FRAGMENT_DATA);
  TxData    = (EFI_UDP4_TRANSMIT_DATA *) AllocateZeroPool (TxLength);
  if (TxData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  TxData->FragmentCount                               = FragCount;
  TxData->FragmentTable[FragCount - 1].FragmentLength = (UINT32) *BufferSize;
  TxData->FragmentTable[FragCount - 1].FragmentBuffer = BufferPtr;
  DataLength                                          = (UINT32) *BufferSize;

  if (HeaderSize != NULL) {
    TxData->FragmentTable[0].FragmentLength = (UINT32) *HeaderSize;
    TxData->FragmentTable[0].FragmentBuffer = HeaderPtr;
    DataLength                             += (UINT32) *HeaderSize;
  }

  if (Gateway != NULL) {
    TxData->GatewayAddress  = Gateway;
  }

  TxData->UdpSessionData  = Session;
  TxData->DataLength      = DataLength;
  Token.Packet.TxData     = TxData;
  Token.Status            = EFI_NOT_READY;
  IsDone                  = FALSE;

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  PxeBcCommonNotify,
                  &IsDone,
                  &Token.Event
                  );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  Status = Udp4->Transmit (Udp4, &Token);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Poll the UDPv6 read instance if no packet received and no timeout triggered.
  //
  while (!IsDone &&
         Token.Status == EFI_NOT_READY &&
         EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {
    Udp4->Poll (Udp4);
  }

  Status = (Token.Status == EFI_NOT_READY) ? EFI_TIMEOUT : Token.Status;

ON_EXIT:
  if (Token.Event != NULL) {
    gBS->CloseEvent (Token.Event);
  }
  FreePool (TxData);

  return Status;
}


/**
  This function is to configure a UDPv4 instance for UdpWrite.

  @param[in]       Udp6                 The pointer to EFI_UDP6_PROTOCOL.
  @param[in]       Session              The pointer to the UDP6 session data.
  @param[in]       TimeoutEvent         The event for timeout.
  @param[in]       HeaderSize           An optional field which may be set to the length of a header
                                        at HeaderPtr to be prefixed to the data at BufferPtr.
  @param[in]       HeaderPtr            If HeaderSize is not NULL, a pointer to a header to be
                                        prefixed to the data at BufferPtr.
  @param[in]       BufferSize           A pointer to the size of the data at BufferPtr.
  @param[in]       BufferPtr            A pointer to the data to be written.

  @retval          EFI_SUCCESS          Successfully sent out data using Udp6Write.
  @retval          Others               Failed to send out data.

**/
EFI_STATUS
PxeBcUdp6Write (
  IN EFI_UDP6_PROTOCOL       *Udp6,
  IN EFI_UDP6_SESSION_DATA   *Session,
  IN EFI_EVENT               TimeoutEvent,
  IN UINTN                   *HeaderSize   OPTIONAL,
  IN VOID                    *HeaderPtr    OPTIONAL,
  IN UINTN                   *BufferSize,
  IN VOID                    *BufferPtr
  )
{
  EFI_UDP6_COMPLETION_TOKEN Token;
  EFI_UDP6_TRANSMIT_DATA    *TxData;
  UINT32                    TxLength;
  UINT32                    FragCount;
  UINT32                    DataLength;
  BOOLEAN                   IsDone;
  EFI_STATUS                Status;

  //
  // Arrange one fragment buffer for data, and another fragment buffer for header if has.
  //
  FragCount = (HeaderSize != NULL) ? 2 : 1;
  TxLength  = sizeof (EFI_UDP6_TRANSMIT_DATA) + (FragCount - 1) * sizeof (EFI_UDP6_FRAGMENT_DATA);
  TxData    = (EFI_UDP6_TRANSMIT_DATA *) AllocateZeroPool (TxLength);
  if (TxData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  TxData->FragmentCount                               = FragCount;
  TxData->FragmentTable[FragCount - 1].FragmentLength = (UINT32) *BufferSize;
  TxData->FragmentTable[FragCount - 1].FragmentBuffer = BufferPtr;
  DataLength                                          = (UINT32) *BufferSize;

  if (HeaderSize != NULL) {
    TxData->FragmentTable[0].FragmentLength = (UINT32) *HeaderSize;
    TxData->FragmentTable[0].FragmentBuffer = HeaderPtr;
    DataLength                             += (UINT32) *HeaderSize;
  }

  TxData->UdpSessionData  = Session;
  TxData->DataLength      = DataLength;
  Token.Packet.TxData     = TxData;
  Token.Status            = EFI_NOT_READY;
  IsDone                  = FALSE;

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  PxeBcCommonNotify,
                  &IsDone,
                  &Token.Event
                  );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  Status = Udp6->Transmit (Udp6, &Token);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Poll the UDPv6 read instance if no packet received and no timeout triggered.
  //
  while (!IsDone &&
         Token.Status == EFI_NOT_READY &&
         EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {
    Udp6->Poll (Udp6);
  }

  Status = (Token.Status == EFI_NOT_READY) ? EFI_TIMEOUT : Token.Status;

ON_EXIT:
  if (Token.Event != NULL) {
    gBS->CloseEvent (Token.Event);
  }
  FreePool (TxData);

  return Status;
}


/**
  Check the received packet using the Ip filter.

  @param[in]  Mode                The pointer to the mode data of PxeBc.
  @param[in]  Session             The pointer to the current UDPv4 session.
  @param[in]  OpFlags             Operation flag for UdpRead/UdpWrite.

  @retval     TRUE                Passed the Ip filter successfully.
  @retval     FALSE               Failed to pass the Ip filter.

**/
BOOLEAN
PxeBcCheckByIpFilter (
  IN EFI_PXE_BASE_CODE_MODE    *Mode,
  IN VOID                      *Session,
  IN UINT16                    OpFlags
  )
{
  EFI_IP_ADDRESS               DestinationIp;
  UINTN                        Index;

  if ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER) == 0) {
    return TRUE;
  }

  if ((Mode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS) != 0) {
    return TRUE;
  }

  //
  // Convert the destination address in session data to host order.
  //
  if (Mode->UsingIpv6) {
    CopyMem (
      &DestinationIp,
      &((EFI_UDP6_SESSION_DATA *) Session)->DestinationAddress,
      sizeof (EFI_IPv6_ADDRESS)
      );
    NTOHLLL (&DestinationIp.v6);
  } else {
    ZeroMem (&DestinationIp, sizeof (EFI_IP_ADDRESS));
    CopyMem (
      &DestinationIp,
      &((EFI_UDP4_SESSION_DATA *) Session)->DestinationAddress,
      sizeof (EFI_IPv4_ADDRESS)
      );
    EFI_NTOHL (DestinationIp);
  }

  if ((Mode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST) != 0 &&
      (IP4_IS_MULTICAST (DestinationIp.Addr[0]) ||
       IP6_IS_MULTICAST (&DestinationIp))) {
    return TRUE;
  }

  if ((Mode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST) != 0 &&
      IP4_IS_LOCAL_BROADCAST (DestinationIp.Addr[0])) {
    ASSERT (!Mode->UsingIpv6);
    return TRUE;
  }

  if ((Mode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP) != 0 &&
      (EFI_IP4_EQUAL (&Mode->StationIp.v4, &DestinationIp) ||
       EFI_IP6_EQUAL (&Mode->StationIp.v6, &DestinationIp))) {
    //
    // Matched if the dest address is equal to the station address.
    //
    return TRUE;
  }

  for (Index = 0; Index < Mode->IpFilter.IpCnt; Index++) {
    ASSERT (Index < EFI_PXE_BASE_CODE_MAX_IPCNT);
    if (EFI_IP4_EQUAL (&Mode->IpFilter.IpList[Index].v4, &DestinationIp) ||
        EFI_IP6_EQUAL (&Mode->IpFilter.IpList[Index].v6, &DestinationIp)) {
      //
      // Matched if the dest address is equal to any of address in the filter list.
      //
      return TRUE;
    }
  }

  return FALSE;
}


/**
  Filter the received packet using the destination Ip.

  @param[in]       Mode           The pointer to the mode data of PxeBc.
  @param[in]       Session        The pointer to the current UDPv4 session.
  @param[in, out]  DestIp         The pointer to the destination Ip address.
  @param[in]       OpFlags        Operation flag for UdpRead/UdpWrite.

  @retval     TRUE                Passed the IPv4 filter successfully.
  @retval     FALSE               Failed to pass the IPv4 filter.

**/
BOOLEAN
PxeBcCheckByDestIp (
  IN     EFI_PXE_BASE_CODE_MODE    *Mode,
  IN     VOID                      *Session,
  IN OUT EFI_IP_ADDRESS            *DestIp,
  IN     UINT16                    OpFlags
  )
{
  if ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP) != 0) {
    //
    // Copy the destination address from the received packet if accept any.
    //
    if (DestIp != NULL) {
      if (Mode->UsingIpv6) {
        CopyMem (
          DestIp,
          &((EFI_UDP6_SESSION_DATA *)Session)->DestinationAddress,
          sizeof (EFI_IPv6_ADDRESS)
          );
      } else {
        ZeroMem (DestIp, sizeof (EFI_IP_ADDRESS));
        CopyMem (
          DestIp,
          &((EFI_UDP4_SESSION_DATA *)Session)->DestinationAddress,
          sizeof (EFI_IPv4_ADDRESS)
          );
      }

    }
    return TRUE;
  } else if (DestIp != NULL &&
             (EFI_IP4_EQUAL (DestIp, &((EFI_UDP4_SESSION_DATA *)Session)->DestinationAddress) ||
              EFI_IP6_EQUAL (DestIp, &((EFI_UDP6_SESSION_DATA *)Session)->DestinationAddress))) {
    //
    // The destination address in the received packet is matched if present.
    //
    return TRUE;
  } else if (EFI_IP4_EQUAL (&Mode->StationIp, &((EFI_UDP4_SESSION_DATA *)Session)->DestinationAddress) ||
             EFI_IP6_EQUAL (&Mode->StationIp, &((EFI_UDP6_SESSION_DATA *)Session)->DestinationAddress)) {
    //
    // The destination address in the received packet is equal to the host address.
    //
    return TRUE;
  }

  return FALSE;
}


/**
  Check the received packet using the destination port.

  @param[in]       Mode           The pointer to the mode data of PxeBc.
  @param[in]       Session        The pointer to the current UDPv4 session.
  @param[in, out]  DestPort       The pointer to the destination port.
  @param[in]       OpFlags        Operation flag for UdpRead/UdpWrite.

  @retval     TRUE                Passed the IPv4 filter successfully.
  @retval     FALSE               Failed to pass the IPv4 filter.

**/
BOOLEAN
PxeBcCheckByDestPort (
  IN     EFI_PXE_BASE_CODE_MODE    *Mode,
  IN     VOID                      *Session,
  IN OUT UINT16                    *DestPort,
  IN     UINT16                    OpFlags
  )
{
  UINT16       Port;

  if (Mode->UsingIpv6) {
    Port = ((EFI_UDP6_SESSION_DATA *) Session)->DestinationPort;
  } else {
    Port = ((EFI_UDP4_SESSION_DATA *) Session)->DestinationPort;
  }

  if ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT) != 0) {
    //
    // Return the destination port in the received packet if accept any.
    //
    if (DestPort != NULL) {
      *DestPort = Port;
    }
    return TRUE;
  } else if (DestPort != NULL && *DestPort == Port) {
    //
    // The destination port in the received packet is matched if present.
    //
    return TRUE;
  }

  return FALSE;
}


/**
  Filter the received packet using the source Ip.

  @param[in]       Mode           The pointer to the mode data of PxeBc.
  @param[in]       Session        The pointer to the current UDPv4 session.
  @param[in, out]  SrcIp          The pointer to the source Ip address.
  @param[in]       OpFlags        Operation flag for UdpRead/UdpWrite.

  @retval     TRUE                Passed the IPv4 filter successfully.
  @retval     FALSE               Failed to pass the IPv4 filter.

**/
BOOLEAN
PxeBcFilterBySrcIp (
  IN     EFI_PXE_BASE_CODE_MODE    *Mode,
  IN     VOID                      *Session,
  IN OUT EFI_IP_ADDRESS            *SrcIp,
  IN     UINT16                    OpFlags
  )
{
  if ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP) != 0) {
    //
    // Copy the source address from the received packet if accept any.
    //
    if (SrcIp != NULL) {
      if (Mode->UsingIpv6) {
        CopyMem (
          SrcIp,
          &((EFI_UDP6_SESSION_DATA *)Session)->SourceAddress,
          sizeof (EFI_IPv6_ADDRESS)
          );
      } else {
        ZeroMem (SrcIp, sizeof (EFI_IP_ADDRESS));
        CopyMem (
          SrcIp,
          &((EFI_UDP4_SESSION_DATA *)Session)->SourceAddress,
          sizeof (EFI_IPv4_ADDRESS)
          );
      }

    }
    return TRUE;
  } else if (SrcIp != NULL &&
             (EFI_IP4_EQUAL (SrcIp, &((EFI_UDP4_SESSION_DATA *)Session)->SourceAddress) ||
              EFI_IP6_EQUAL (SrcIp, &((EFI_UDP6_SESSION_DATA *)Session)->SourceAddress))) {
    //
    // The source address in the received packet is matched if present.
    //
    return TRUE;
  }

  return FALSE;
}


/**
  Filter the received packet using the source port.

  @param[in]       Mode           The pointer to the mode data of PxeBc.
  @param[in]       Session        The pointer to the current UDPv4 session.
  @param[in, out]  SrcPort        The pointer to the source port.
  @param[in]       OpFlags        Operation flag for UdpRead/UdpWrite.

  @retval     TRUE                Passed the IPv4 filter successfully.
  @retval     FALSE               Failed to pass the IPv4 filter.

**/
BOOLEAN
PxeBcFilterBySrcPort (
  IN     EFI_PXE_BASE_CODE_MODE    *Mode,
  IN     VOID                      *Session,
  IN OUT UINT16                    *SrcPort,
  IN     UINT16                    OpFlags
  )
{
  UINT16       Port;

  if (Mode->UsingIpv6) {
    Port = ((EFI_UDP6_SESSION_DATA *) Session)->SourcePort;
  } else {
    Port = ((EFI_UDP4_SESSION_DATA *) Session)->SourcePort;
  }

  if ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT) != 0) {
    //
    // Return the source port in the received packet if accept any.
    //
    if (SrcPort != NULL) {
      *SrcPort = Port;
    }
    return TRUE;
  } else if (SrcPort != NULL && *SrcPort == Port) {
    //
    // The source port in the received packet is matched if present.
    //
    return TRUE;
  }

  return FALSE;
}


/**
  This function is to receive packet using Udp4Read.

  @param[in]       Udp4                 The pointer to EFI_UDP4_PROTOCOL.
  @param[in]       Token                The pointer to EFI_UDP4_COMPLETION_TOKEN.
  @param[in]       Mode                 The pointer to EFI_PXE_BASE_CODE_MODE.
  @param[in]       TimeoutEvent         The event for timeout.
  @param[in]       OpFlags              The UDP operation flags.
  @param[in]       IsDone               The pointer to the IsDone flag.
  @param[out]      IsMatched            The pointer to the IsMatched flag.
  @param[in, out]  DestIp               The pointer to the destination address.
  @param[in, out]  DestPort             The pointer to the destination port.
  @param[in, out]  SrcIp                The pointer to the source address.
  @param[in, out]  SrcPort              The pointer to the source port.

  @retval          EFI_SUCCESS          Successfully read the data using Udp4.
  @retval          Others               Failed to send out data.

**/
EFI_STATUS
PxeBcUdp4Read (
  IN     EFI_UDP4_PROTOCOL            *Udp4,
  IN     EFI_UDP4_COMPLETION_TOKEN    *Token,
  IN     EFI_PXE_BASE_CODE_MODE       *Mode,
  IN     EFI_EVENT                    TimeoutEvent,
  IN     UINT16                       OpFlags,
  IN     BOOLEAN                      *IsDone,
     OUT BOOLEAN                      *IsMatched,
  IN OUT EFI_IP_ADDRESS               *DestIp      OPTIONAL,
  IN OUT EFI_PXE_BASE_CODE_UDP_PORT   *DestPort    OPTIONAL,
  IN OUT EFI_IP_ADDRESS               *SrcIp       OPTIONAL,
  IN OUT EFI_PXE_BASE_CODE_UDP_PORT   *SrcPort     OPTIONAL
  )
{
  EFI_UDP4_RECEIVE_DATA     *RxData;
  EFI_UDP4_SESSION_DATA     *Session;
  EFI_STATUS                Status;

  Token->Status = EFI_NOT_READY;
  *IsDone       = FALSE;

  Status = Udp4->Receive (Udp4, Token);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Poll the UDPv6 read instance if no packet received and no timeout triggered.
  //
  while (!(*IsDone) &&
         Token->Status == EFI_NOT_READY &&
         EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {
    //
    // Poll the token utill reply/ICMPv6 error message received or timeout.
    //
    Udp4->Poll (Udp4);
    if (Token->Status == EFI_ICMP_ERROR ||
        Token->Status == EFI_NETWORK_UNREACHABLE ||
        Token->Status == EFI_HOST_UNREACHABLE ||
        Token->Status == EFI_PROTOCOL_UNREACHABLE ||
        Token->Status == EFI_PORT_UNREACHABLE) {
      break;
    }
  }

  Status = (Token->Status == EFI_NOT_READY) ? EFI_TIMEOUT : Token->Status;

  if (!EFI_ERROR (Status)) {
    //
    // check whether this packet matches the filters
    //
    RxData    = Token->Packet.RxData;
    Session   = &RxData->UdpSession;

    *IsMatched = PxeBcCheckByIpFilter (Mode, Session, OpFlags);

    if (*IsMatched) {
      *IsMatched = PxeBcCheckByDestIp (Mode, Session, DestIp, OpFlags);
    }

    if (*IsMatched) {
      *IsMatched = PxeBcCheckByDestPort (Mode, Session, DestPort, OpFlags);
    }

    if (*IsMatched) {
      *IsMatched = PxeBcFilterBySrcIp (Mode, Session, SrcIp, OpFlags);
    }

    if (*IsMatched) {
      *IsMatched = PxeBcFilterBySrcPort (Mode, Session, SrcPort, OpFlags);
    }

    if (!(*IsMatched)) {
      //
      // Recycle the receiving buffer if not matched.
      //
      gBS->SignalEvent (RxData->RecycleSignal);
    }
  }

  return Status;
}


/**
  This function is to receive packets using Udp6Read.

  @param[in]       Udp6                 The pointer to EFI_UDP6_PROTOCOL.
  @param[in]       Token                The pointer to EFI_UDP6_COMPLETION_TOKEN.
  @param[in]       Mode                 The pointer to EFI_PXE_BASE_CODE_MODE.
  @param[in]       TimeoutEvent         The event for timeout.
  @param[in]       OpFlags              The UDP operation flags.
  @param[in]       IsDone               The pointer to the IsDone flag.
  @param[out]      IsMatched            The pointer to the IsMatched flag.
  @param[in, out]  DestIp               The pointer to the destination address.
  @param[in, out]  DestPort             The pointer to the destination port.
  @param[in, out]  SrcIp                The pointer to the source address.
  @param[in, out]  SrcPort              The pointer to the source port.

  @retval          EFI_SUCCESS          Successfully read data using Udp6.
  @retval          Others               Failed to send out data.

**/
EFI_STATUS
PxeBcUdp6Read (
  IN     EFI_UDP6_PROTOCOL            *Udp6,
  IN     EFI_UDP6_COMPLETION_TOKEN    *Token,
  IN     EFI_PXE_BASE_CODE_MODE       *Mode,
  IN     EFI_EVENT                    TimeoutEvent,
  IN     UINT16                       OpFlags,
  IN     BOOLEAN                      *IsDone,
     OUT BOOLEAN                      *IsMatched,
  IN OUT EFI_IP_ADDRESS               *DestIp      OPTIONAL,
  IN OUT EFI_PXE_BASE_CODE_UDP_PORT   *DestPort    OPTIONAL,
  IN OUT EFI_IP_ADDRESS               *SrcIp       OPTIONAL,
  IN OUT EFI_PXE_BASE_CODE_UDP_PORT   *SrcPort     OPTIONAL
  )
{
  EFI_UDP6_RECEIVE_DATA     *RxData;
  EFI_UDP6_SESSION_DATA     *Session;
  EFI_STATUS                Status;

  Token->Status = EFI_NOT_READY;
  *IsDone       = FALSE;

  Status = Udp6->Receive (Udp6, Token);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Poll the UDPv6 read instance if no packet received and no timeout triggered.
  //
  while (!(*IsDone) &&
         Token->Status == EFI_NOT_READY &&
         EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {
    //
    // Poll the token utill reply/ICMPv6 error message received or timeout.
    //
    Udp6->Poll (Udp6);
    if (Token->Status == EFI_ICMP_ERROR ||
        Token->Status == EFI_NETWORK_UNREACHABLE ||
        Token->Status == EFI_HOST_UNREACHABLE ||
        Token->Status == EFI_PROTOCOL_UNREACHABLE ||
        Token->Status == EFI_PORT_UNREACHABLE) {
      break;
    }
  }

  Status = (Token->Status == EFI_NOT_READY) ? EFI_TIMEOUT : Token->Status;

  if (!EFI_ERROR (Status)) {
    //
    // check whether this packet matches the filters
    //
    RxData    = Token->Packet.RxData;
    Session   = &RxData->UdpSession;

    *IsMatched = PxeBcCheckByIpFilter (Mode, Session, OpFlags);

    if (*IsMatched) {
      *IsMatched = PxeBcCheckByDestIp (Mode, Session, DestIp, OpFlags);
    }

    if (*IsMatched) {
      *IsMatched = PxeBcCheckByDestPort (Mode, Session, DestPort, OpFlags);
    }

    if (*IsMatched) {
      *IsMatched = PxeBcFilterBySrcIp (Mode, Session, SrcIp, OpFlags);
    }

    if (*IsMatched) {
      *IsMatched = PxeBcFilterBySrcPort (Mode, Session, SrcPort, OpFlags);
    }

    if (!(*IsMatched)) {
      //
      // Recycle the receiving buffer if not matched.
      //
      gBS->SignalEvent (RxData->RecycleSignal);
    }
  }

  return Status;
}


/**
  This function is to display the IPv4 address.

  @param[in]  Ip        The pointer to the IPv4 address.

**/
VOID
PxeBcShowIp4Addr (
  IN EFI_IPv4_ADDRESS   *Ip
  )
{
  UINTN                 Index;

  for (Index = 0; Index < 4; Index++) {
    AsciiPrint ("%d", Ip->Addr[Index]);
    if (Index < 3) {
      AsciiPrint (".");
    }
  }
}


/**
  This function is to display the IPv6 address.

  @param[in]  Ip        The pointer to the IPv6 address.

**/
VOID
PxeBcShowIp6Addr (
  IN EFI_IPv6_ADDRESS   *Ip
  )
{
  UINTN                 Index;

  for (Index = 0; Index < 16; Index++) {

    if (Ip->Addr[Index] != 0) {
      AsciiPrint ("%x", Ip->Addr[Index]);
    }
    Index++;
    if (Index > 15) {
      return;
    }
    if (((Ip->Addr[Index] & 0xf0) == 0) && (Ip->Addr[Index - 1] != 0)) {
      AsciiPrint ("0");
    }
    AsciiPrint ("%x", Ip->Addr[Index]);
    if (Index < 15) {
      AsciiPrint (":");
    }
  }
}


/**
  This function is to convert UINTN to ASCII string with the required formatting.

  @param[in]  Number         Numeric value to be converted.
  @param[in]  Buffer         The pointer to the buffer for ASCII string.
  @param[in]  Length         The length of the required format.

**/
VOID
PxeBcUintnToAscDecWithFormat (
  IN UINTN                       Number,
  IN UINT8                       *Buffer,
  IN INTN                        Length
  )
{
  UINTN                          Remainder;

  for (; Length > 0; Length--) {
    Remainder      = Number % 10;
    Number        /= 10;
    Buffer[Length - 1] = (UINT8) ('0' + Remainder);
  }
}


/**
  This function is to convert a UINTN to a ASCII string, and return the
  actual length of the buffer.

  @param[in]  Number         Numeric value to be converted.
  @param[in]  Buffer         The pointer to the buffer for ASCII string.
  @param[in]  BufferSize     The maxsize of the buffer.

  @return     Length         The actual length of the ASCII string.

**/
UINTN
PxeBcUintnToAscDec (
  IN UINTN               Number,
  IN UINT8               *Buffer,
  IN UINTN               BufferSize
  )
{
  UINTN           Index;
  UINTN           Length;
  CHAR8           TempStr[64];

  Index           = 63;
  TempStr[Index]  = 0;

  do {
    Index--;
    TempStr[Index] = (CHAR8) ('0' + (Number % 10));
    Number         = (UINTN) (Number / 10);
  } while (Number != 0);

  AsciiStrCpyS ((CHAR8 *) Buffer, BufferSize, &TempStr[Index]);

  Length = AsciiStrLen ((CHAR8 *) Buffer);

  return Length;
}


/**
  This function is to convert unicode hex number to a UINT8.

  @param[out]  Digit                   The converted UINT8 for output.
  @param[in]   Char                    The unicode hex number to be converted.

  @retval      EFI_SUCCESS             Successfully converted the unicode hex.
  @retval      EFI_INVALID_PARAMETER   Failed to convert the unicode hex.

**/
EFI_STATUS
PxeBcUniHexToUint8 (
  OUT UINT8                *Digit,
  IN  CHAR16               Char
  )
{
  if ((Char >= L'0') && (Char <= L'9')) {
    *Digit = (UINT8) (Char - L'0');
    return EFI_SUCCESS;
  }

  if ((Char >= L'A') && (Char <= L'F')) {
    *Digit = (UINT8) (Char - L'A' + 0x0A);
    return EFI_SUCCESS;
  }

  if ((Char >= L'a') && (Char <= L'f')) {
    *Digit = (UINT8) (Char - L'a' + 0x0A);
    return EFI_SUCCESS;
  }

  return EFI_INVALID_PARAMETER;
}

/**
  Calculate the elapsed time.

  @param[in]      Private      The pointer to PXE private data

**/
VOID
CalcElapsedTime (
  IN     PXEBC_PRIVATE_DATA     *Private
  )
{
  EFI_TIME          Time;
  UINT64            CurrentStamp;
  UINT64            ElapsedTimeValue;

  //
  // Generate a time stamp of the centiseconds from 1900/1/1, assume 30day/month.
  //
  ZeroMem (&Time, sizeof (EFI_TIME));
  gRT->GetTime (&Time, NULL);
  CurrentStamp = (UINT64)
    (
      ((((((Time.Year - 1900) * 360 +
       (Time.Month - 1)) * 30 +
       (Time.Day - 1)) * 24 + Time.Hour) * 60 +
       Time.Minute) * 60 + Time.Second) * 100
       + DivU64x32(Time.Nanosecond, 10000000)
    );

  //
  // Sentinel value of 0 means that this is the first DHCP packet that we are
  // sending and that we need to initialize the value.  First DHCP Solicit
  // gets 0 elapsed-time.  Otherwise, calculate based on StartTime.
  //
  if (Private->ElapsedTime == 0) {
    Private->ElapsedTime = CurrentStamp;
  } else {
    ElapsedTimeValue = CurrentStamp - Private->ElapsedTime;

    //
    // If elapsed time cannot fit in two bytes, set it to 0xffff.
    //
    if (ElapsedTimeValue > 0xffff) {
      ElapsedTimeValue = 0xffff;
    }
    //
    // Save the elapsed time
    //
    Private->ElapsedTime = ElapsedTimeValue;
  }
}

