/** @file

Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Dhcp4Impl.h"
#include "Dhcp4Driver.h"

EFI_DRIVER_BINDING_PROTOCOL  gDhcp4DriverBinding = {
  Dhcp4DriverBindingSupported,
  Dhcp4DriverBindingStart,
  Dhcp4DriverBindingStop,
  0xa,
  NULL,
  NULL
};

EFI_SERVICE_BINDING_PROTOCOL  mDhcp4ServiceBindingTemplate = {
  Dhcp4ServiceBindingCreateChild,
  Dhcp4ServiceBindingDestroyChild
};

/**
  This is the declaration of an EFI image entry point. This entry point is
  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
  both device drivers and bus drivers.

  Entry point of the DHCP driver to install various protocols.

  @param[in]  ImageHandle           The firmware allocated handle for the UEFI image.
  @param[in]  SystemTable           A pointer to the EFI System Table.

  @retval EFI_SUCCESS           The operation completed successfully.
  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.

**/
EFI_STATUS
EFIAPI
Dhcp4DriverEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  return EfiLibInstallDriverBindingComponentName2 (
           ImageHandle,
           SystemTable,
           &gDhcp4DriverBinding,
           ImageHandle,
           &gDhcp4ComponentName,
           &gDhcp4ComponentName2
           );
}

/**
  Test to see if this driver supports ControllerHandle. This service
  is called by the EFI boot service ConnectController(). In
  order to make drivers as small as possible, there are a few calling
  restrictions for this service. ConnectController() must
  follow these calling restrictions. If any other agent wishes to call
  Supported() it must also follow these calling restrictions.

  @param[in]  This                Protocol instance pointer.
  @param[in]  ControllerHandle    Handle of device to test
  @param[in]  RemainingDevicePath Optional parameter use to pick a specific child
                                  device to start.

  @retval EFI_SUCCESS         This driver supports this device
  @retval EFI_ALREADY_STARTED This driver is already running on this device
  @retval other               This driver does not support this device

**/
EFI_STATUS
EFIAPI
Dhcp4DriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  EFI_STATUS  Status;

  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiUdp4ServiceBindingProtocolGuid,
                  NULL,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );

  return Status;
}

/**
  Configure the default UDP child to receive all the DHCP traffics
  on this network interface.

  @param[in]  UdpIo                  The UDP IO to configure
  @param[in]  Context                The context to the function

  @retval EFI_SUCCESS            The UDP IO is successfully configured.
  @retval Others                 Failed to configure the UDP child.

**/
EFI_STATUS
EFIAPI
DhcpConfigUdpIo (
  IN UDP_IO  *UdpIo,
  IN VOID    *Context
  )
{
  EFI_UDP4_CONFIG_DATA  UdpConfigData;

  UdpConfigData.AcceptBroadcast    = TRUE;
  UdpConfigData.AcceptPromiscuous  = FALSE;
  UdpConfigData.AcceptAnyPort      = FALSE;
  UdpConfigData.AllowDuplicatePort = TRUE;
  UdpConfigData.TypeOfService      = 0;
  UdpConfigData.TimeToLive         = 64;
  UdpConfigData.DoNotFragment      = FALSE;
  UdpConfigData.ReceiveTimeout     = 0;
  UdpConfigData.TransmitTimeout    = 0;

  UdpConfigData.UseDefaultAddress = FALSE;
  UdpConfigData.StationPort       = DHCP_CLIENT_PORT;
  UdpConfigData.RemotePort        = DHCP_SERVER_PORT;

  ZeroMem (&UdpConfigData.StationAddress, sizeof (EFI_IPv4_ADDRESS));
  ZeroMem (&UdpConfigData.SubnetMask, sizeof (EFI_IPv4_ADDRESS));
  ZeroMem (&UdpConfigData.RemoteAddress, sizeof (EFI_IPv4_ADDRESS));

  return UdpIo->Protocol.Udp4->Configure (UdpIo->Protocol.Udp4, &UdpConfigData);
}

/**
  Destroy the DHCP service. The Dhcp4 service may be partly initialized,
  or partly destroyed. If a resource is destroyed, it is marked as so in
  case the destroy failed and being called again later.

  @param[in]  DhcpSb                 The DHCP service instance to destroy.

  @retval EFI_SUCCESS            Always return success.

**/
EFI_STATUS
Dhcp4CloseService (
  IN DHCP_SERVICE  *DhcpSb
  )
{
  DhcpCleanLease (DhcpSb);

  if (DhcpSb->UdpIo != NULL) {
    UdpIoFreeIo (DhcpSb->UdpIo);
    DhcpSb->UdpIo = NULL;
  }

  if (DhcpSb->Timer != NULL) {
    gBS->SetTimer (DhcpSb->Timer, TimerCancel, 0);
    gBS->CloseEvent (DhcpSb->Timer);

    DhcpSb->Timer = NULL;
  }

  return EFI_SUCCESS;
}

/**
  Create a new DHCP service binding instance for the controller.

  @param[in]  Controller             The controller to install DHCP service binding
                                     protocol onto
  @param[in]  ImageHandle            The driver's image handle
  @param[out] Service                The variable to receive the created DHCP service
                                     instance.

  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resource .
  @retval EFI_SUCCESS            The DHCP service instance is created.
  @retval other                  Other error occurs.

**/
EFI_STATUS
Dhcp4CreateService (
  IN  EFI_HANDLE    Controller,
  IN  EFI_HANDLE    ImageHandle,
  OUT DHCP_SERVICE  **Service
  )
{
  DHCP_SERVICE  *DhcpSb;
  EFI_STATUS    Status;

  *Service = NULL;
  DhcpSb   = AllocateZeroPool (sizeof (DHCP_SERVICE));

  if (DhcpSb == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  DhcpSb->Signature    = DHCP_SERVICE_SIGNATURE;
  DhcpSb->ServiceState = DHCP_UNCONFIGED;
  DhcpSb->Controller   = Controller;
  DhcpSb->Image        = ImageHandle;
  InitializeListHead (&DhcpSb->Children);
  DhcpSb->DhcpState = Dhcp4Stopped;
  DhcpSb->Xid       = NET_RANDOM (NetRandomInitSeed ());
  CopyMem (
    &DhcpSb->ServiceBinding,
    &mDhcp4ServiceBindingTemplate,
    sizeof (EFI_SERVICE_BINDING_PROTOCOL)
    );
  //
  // Create various resources, UdpIo, Timer, and get Mac address
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL | EVT_TIMER,
                  TPL_CALLBACK,
                  DhcpOnTimerTick,
                  DhcpSb,
                  &DhcpSb->Timer
                  );

  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  DhcpSb->UdpIo = UdpIoCreateIo (
                    Controller,
                    ImageHandle,
                    DhcpConfigUdpIo,
                    UDP_IO_UDP4_VERSION,
                    NULL
                    );

  if (DhcpSb->UdpIo == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_ERROR;
  }

  DhcpSb->HwLen  = (UINT8)DhcpSb->UdpIo->SnpMode.HwAddressSize;
  DhcpSb->HwType = DhcpSb->UdpIo->SnpMode.IfType;
  CopyMem (&DhcpSb->Mac, &DhcpSb->UdpIo->SnpMode.CurrentAddress, sizeof (DhcpSb->Mac));

  *Service = DhcpSb;
  return EFI_SUCCESS;

ON_ERROR:
  Dhcp4CloseService (DhcpSb);
  FreePool (DhcpSb);

  return Status;
}

/**
  Start this driver on ControllerHandle. This service is called by the
  EFI boot service ConnectController(). In order to make
  drivers as small as possible, there are a few calling restrictions for
  this service. ConnectController() must follow these
  calling restrictions. If any other agent wishes to call Start() it
  must also follow these calling restrictions.

  @param[in]  This                 Protocol instance pointer.
  @param[in]  ControllerHandle     Handle of device to bind driver to
  @param[in]  RemainingDevicePath  Optional parameter use to pick a specific child
                                   device to start.

  @retval EFI_SUCCESS          This driver is added to ControllerHandle
  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle
  @retval other                This driver does not support this device

**/
EFI_STATUS
EFIAPI
Dhcp4DriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  DHCP_SERVICE  *DhcpSb;
  EFI_STATUS    Status;

  //
  // First: test for the DHCP4 Protocol
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiDhcp4ServiceBindingProtocolGuid,
                  NULL,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );

  if (Status == EFI_SUCCESS) {
    return EFI_ALREADY_STARTED;
  }

  Status = Dhcp4CreateService (ControllerHandle, This->DriverBindingHandle, &DhcpSb);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  ASSERT (DhcpSb != NULL);

  //
  // Start the receiving
  //
  Status = UdpIoRecvDatagram (DhcpSb->UdpIo, DhcpInput, DhcpSb, 0);

  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  Status = gBS->SetTimer (DhcpSb->Timer, TimerPeriodic, TICKS_PER_SECOND);

  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Install the Dhcp4ServiceBinding Protocol onto ControllerHandle
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &ControllerHandle,
                  &gEfiDhcp4ServiceBindingProtocolGuid,
                  &DhcpSb->ServiceBinding,
                  NULL
                  );

  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  return Status;

ON_ERROR:
  Dhcp4CloseService (DhcpSb);
  FreePool (DhcpSb);
  return Status;
}

/**
  Callback function which provided by user to remove one node in NetDestroyLinkList process.

  @param[in]    Entry           The entry to be removed.
  @param[in]    Context         Pointer to the callback context corresponds to the Context in NetDestroyLinkList.

  @retval EFI_SUCCESS           The entry has been removed successfully.
  @retval Others                Fail to remove the entry.

**/
EFI_STATUS
EFIAPI
Dhcp4DestroyChildEntry (
  IN LIST_ENTRY  *Entry,
  IN VOID        *Context
  )
{
  DHCP_PROTOCOL                 *Instance;
  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;

  if ((Entry == NULL) || (Context == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Instance       = NET_LIST_USER_STRUCT_S (Entry, DHCP_PROTOCOL, Link, DHCP_PROTOCOL_SIGNATURE);
  ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *)Context;

  return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
}

/**
  Stop this driver on ControllerHandle. This service is called by the
  EFI boot service DisconnectController(). In order to
  make drivers as small as possible, there are a few calling
  restrictions for this service. DisconnectController()
  must follow these calling restrictions. If any other agent wishes
  to call Stop() it must also follow these calling restrictions.

  @param[in]  This              Protocol instance pointer.
  @param[in]  ControllerHandle  Handle of device to stop driver on
  @param[in]  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
                                children is zero stop the entire bus driver.
  @param[in]  ChildHandleBuffer List of Child Handles to Stop.

  @retval EFI_SUCCESS       This driver is removed ControllerHandle
  @retval other             This driver was not removed from this device

**/
EFI_STATUS
EFIAPI
Dhcp4DriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   ControllerHandle,
  IN  UINTN                        NumberOfChildren,
  IN  EFI_HANDLE                   *ChildHandleBuffer
  )
{
  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;
  DHCP_SERVICE                  *DhcpSb;
  EFI_HANDLE                    NicHandle;
  EFI_STATUS                    Status;
  LIST_ENTRY                    *List;
  UINTN                         ListLength;

  //
  // DHCP driver opens UDP child, So, the ControllerHandle is the
  // UDP child handle. locate the Nic handle first.
  //
  NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp4ProtocolGuid);

  if (NicHandle == NULL) {
    return EFI_SUCCESS;
  }

  Status = gBS->OpenProtocol (
                  NicHandle,
                  &gEfiDhcp4ServiceBindingProtocolGuid,
                  (VOID **)&ServiceBinding,
                  This->DriverBindingHandle,
                  NicHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  DhcpSb = DHCP_SERVICE_FROM_THIS (ServiceBinding);
  if (!IsListEmpty (&DhcpSb->Children)) {
    //
    // Destroy all the children instances before destroy the service.
    //
    List   = &DhcpSb->Children;
    Status = NetDestroyLinkList (
               List,
               Dhcp4DestroyChildEntry,
               ServiceBinding,
               &ListLength
               );
    if (EFI_ERROR (Status) || (ListLength != 0)) {
      Status = EFI_DEVICE_ERROR;
    }
  }

  if ((NumberOfChildren == 0) && !IsListEmpty (&DhcpSb->Children)) {
    Status = EFI_DEVICE_ERROR;
  }

  if ((NumberOfChildren == 0) && IsListEmpty (&DhcpSb->Children)) {
    //
    // Destroy the service itself if no child instance left.
    //
    DhcpSb->ServiceState = DHCP_DESTROY;

    gBS->UninstallProtocolInterface (
           NicHandle,
           &gEfiDhcp4ServiceBindingProtocolGuid,
           ServiceBinding
           );

    Dhcp4CloseService (DhcpSb);

    if (gDhcpControllerNameTable != NULL) {
      FreeUnicodeStringTable (gDhcpControllerNameTable);
      gDhcpControllerNameTable = NULL;
    }

    FreePool (DhcpSb);

    Status = EFI_SUCCESS;
  }

  return Status;
}

/**
  Initialize a new DHCP instance.

  @param  DhcpSb                 The dhcp service instance
  @param  Instance               The dhcp instance to initialize

**/
VOID
DhcpInitProtocol (
  IN     DHCP_SERVICE   *DhcpSb,
  IN OUT DHCP_PROTOCOL  *Instance
  )
{
  Instance->Signature = DHCP_PROTOCOL_SIGNATURE;
  CopyMem (&Instance->Dhcp4Protocol, &mDhcp4ProtocolTemplate, sizeof (Instance->Dhcp4Protocol));
  InitializeListHead (&Instance->Link);
  Instance->Handle           = NULL;
  Instance->Service          = DhcpSb;
  Instance->InDestroy        = FALSE;
  Instance->CompletionEvent  = NULL;
  Instance->RenewRebindEvent = NULL;
  Instance->Token            = NULL;
  Instance->UdpIo            = NULL;
  Instance->ElaspedTime      = 0;
  NetbufQueInit (&Instance->ResponseQueue);
}

/**
  Creates a child handle and installs a protocol.

  The CreateChild() function installs a protocol on ChildHandle.
  If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
  If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.

  @param  This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
  @param  ChildHandle Pointer to the handle of the child to create. If it is NULL,
                      then a new handle is created. If it is a pointer to an existing UEFI handle,
                      then the protocol is added to the existing UEFI handle.

  @retval EFI_SUCCESS           The protocol was added to ChildHandle.
  @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
  @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to create
                                the child
  @retval other                 The child handle was not created

**/
EFI_STATUS
EFIAPI
Dhcp4ServiceBindingCreateChild (
  IN EFI_SERVICE_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                    *ChildHandle
  )
{
  DHCP_SERVICE   *DhcpSb;
  DHCP_PROTOCOL  *Instance;
  EFI_STATUS     Status;
  EFI_TPL        OldTpl;
  VOID           *Udp4;

  if ((This == NULL) || (ChildHandle == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = AllocatePool (sizeof (*Instance));

  if (Instance == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  DhcpSb = DHCP_SERVICE_FROM_THIS (This);
  DhcpInitProtocol (DhcpSb, Instance);

  //
  // Install DHCP4 onto ChildHandle
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  ChildHandle,
                  &gEfiDhcp4ProtocolGuid,
                  &Instance->Dhcp4Protocol,
                  NULL
                  );

  if (EFI_ERROR (Status)) {
    FreePool (Instance);
    return Status;
  }

  Instance->Handle = *ChildHandle;

  //
  // Open the Udp4 protocol BY_CHILD.
  //
  Status = gBS->OpenProtocol (
                  DhcpSb->UdpIo->UdpHandle,
                  &gEfiUdp4ProtocolGuid,
                  (VOID **)&Udp4,
                  gDhcp4DriverBinding.DriverBindingHandle,
                  Instance->Handle,
                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                  );
  if (EFI_ERROR (Status)) {
    gBS->UninstallMultipleProtocolInterfaces (
           Instance->Handle,
           &gEfiDhcp4ProtocolGuid,
           &Instance->Dhcp4Protocol,
           NULL
           );

    FreePool (Instance);
    return Status;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  InsertTailList (&DhcpSb->Children, &Instance->Link);
  DhcpSb->NumChildren++;

  gBS->RestoreTPL (OldTpl);

  return EFI_SUCCESS;
}

/**
  Destroys a child handle with a protocol installed on it.

  The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
  that was installed by CreateChild() from ChildHandle. If the removed protocol is the
  last protocol on ChildHandle, then ChildHandle is destroyed.

  @param  This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
  @param  ChildHandle Handle of the child to destroy

  @retval EFI_SUCCESS           The protocol was removed from ChildHandle.
  @retval EFI_UNSUPPORTED       ChildHandle does not support the protocol that is being removed.
  @retval EFI_INVALID_PARAMETER Child handle is NULL.
  @retval EFI_ACCESS_DENIED     The protocol could not be removed from the ChildHandle
                                because its services are being used.
  @retval other                 The child handle was not destroyed

**/
EFI_STATUS
EFIAPI
Dhcp4ServiceBindingDestroyChild (
  IN EFI_SERVICE_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                    ChildHandle
  )
{
  DHCP_SERVICE        *DhcpSb;
  DHCP_PROTOCOL       *Instance;
  EFI_DHCP4_PROTOCOL  *Dhcp;
  EFI_TPL             OldTpl;
  EFI_STATUS          Status;

  if ((This == NULL) || (ChildHandle == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Retrieve the private context data structures
  //
  Status = gBS->OpenProtocol (
                  ChildHandle,
                  &gEfiDhcp4ProtocolGuid,
                  (VOID **)&Dhcp,
                  gDhcp4DriverBinding.DriverBindingHandle,
                  ChildHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  Instance = DHCP_INSTANCE_FROM_THIS (Dhcp);
  DhcpSb   = DHCP_SERVICE_FROM_THIS (This);

  if (Instance->Service != DhcpSb) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // A child can be destroyed more than once. For example,
  // Dhcp4DriverBindingStop will destroy all of its children.
  // when caller driver is being stopped, it will destroy the
  // dhcp child it opens.
  //
  if (Instance->InDestroy) {
    return EFI_SUCCESS;
  }

  OldTpl              = gBS->RaiseTPL (TPL_CALLBACK);
  Instance->InDestroy = TRUE;

  //
  // Close the Udp4 protocol.
  //
  gBS->CloseProtocol (
         DhcpSb->UdpIo->UdpHandle,
         &gEfiUdp4ProtocolGuid,
         gDhcp4DriverBinding.DriverBindingHandle,
         ChildHandle
         );

  //
  // Uninstall the DHCP4 protocol first to enable a top down destruction.
  //
  gBS->RestoreTPL (OldTpl);
  Status = gBS->UninstallProtocolInterface (
                  ChildHandle,
                  &gEfiDhcp4ProtocolGuid,
                  Dhcp
                  );
  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
  if (EFI_ERROR (Status)) {
    Instance->InDestroy = FALSE;

    gBS->RestoreTPL (OldTpl);
    return Status;
  }

  if (DhcpSb->ActiveChild == Instance) {
    DhcpYieldControl (DhcpSb);
  }

  RemoveEntryList (&Instance->Link);
  DhcpSb->NumChildren--;

  if (Instance->UdpIo != NULL) {
    UdpIoCleanIo (Instance->UdpIo);
    gBS->CloseProtocol (
           Instance->UdpIo->UdpHandle,
           &gEfiUdp4ProtocolGuid,
           Instance->Service->Image,
           Instance->Handle
           );
    UdpIoFreeIo (Instance->UdpIo);
    Instance->UdpIo = NULL;
    Instance->Token = NULL;
  }

  gBS->RestoreTPL (OldTpl);

  FreePool (Instance);
  return EFI_SUCCESS;
}
