/** @file
  Driver Binding functions and Service Binding functions
  implementation for Mtftp6 Driver.

  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 "Mtftp6Impl.h"


EFI_DRIVER_BINDING_PROTOCOL   gMtftp6DriverBinding = {
  Mtftp6DriverBindingSupported,
  Mtftp6DriverBindingStart,
  Mtftp6DriverBindingStop,
  0xa,
  NULL,
  NULL
};

EFI_SERVICE_BINDING_PROTOCOL  gMtftp6ServiceBindingTemplate = {
  Mtftp6ServiceBindingCreateChild,
  Mtftp6ServiceBindingDestroyChild
};


/**
  Destory the MTFTP6 service. The MTFTP6 service may be partly initialized,
  or partly destroyed. If a resource is destroyed, it is marked as such in
  case the destroy failed and is called again later.

  @param[in]  Service            The MTFTP6 service to be destroyed.

**/
VOID
Mtftp6DestroyService (
  IN MTFTP6_SERVICE     *Service
  )
{
  //
  // Make sure all children instances have been already destoryed.
  //
  ASSERT (Service->ChildrenNum == 0);

  if (Service->DummyUdpIo != NULL) {
    UdpIoFreeIo (Service->DummyUdpIo);
  }

  if (Service->Timer != NULL) {
    gBS->CloseEvent (Service->Timer);
  }

  FreePool (Service);
}


/**
  Create then initialize a MTFTP6 service binding instance.

  @param[in]  Controller             The controller to install the MTFTP6 service
                                     binding on.
  @param[in]  Image                  The driver binding image of the MTFTP6 driver.
  @param[out] Service                The variable to receive the created service
                                     binding instance.

  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources to create the instance
  @retval EFI_DEVICE_ERROR       Failed to create a NULL UDP port to keep connection with UDP.
  @retval EFI_SUCCESS            The service instance is created for the controller.

**/
EFI_STATUS
Mtftp6CreateService (
  IN  EFI_HANDLE            Controller,
  IN  EFI_HANDLE            Image,
  OUT MTFTP6_SERVICE        **Service
  )
{
  MTFTP6_SERVICE            *Mtftp6Srv;
  EFI_STATUS                Status;

  ASSERT (Service != NULL);

  *Service  = NULL;
  Mtftp6Srv = AllocateZeroPool (sizeof (MTFTP6_SERVICE));

  if (Mtftp6Srv == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Mtftp6Srv->Signature      = MTFTP6_SERVICE_SIGNATURE;
  Mtftp6Srv->Controller     = Controller;
  Mtftp6Srv->Image          = Image;
  Mtftp6Srv->InDestory      = FALSE;
  Mtftp6Srv->ChildrenNum    = 0;

  CopyMem (
    &Mtftp6Srv->ServiceBinding,
    &gMtftp6ServiceBindingTemplate,
    sizeof (EFI_SERVICE_BINDING_PROTOCOL)
    );

  InitializeListHead (&Mtftp6Srv->Children);

  //
  // Create a internal timer for all instances.
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL | EVT_TIMER,
                  TPL_CALLBACK,
                  Mtftp6OnTimerTick,
                  Mtftp6Srv,
                  &Mtftp6Srv->Timer
                  );

  if (EFI_ERROR (Status)) {
    FreePool (Mtftp6Srv);
    return Status;
  }

  //
  // Create a dummy Udp6Io to build parent-child relationship between Udp6 driver
  // and Mtftp6 driver.
  //
  Mtftp6Srv->DummyUdpIo = UdpIoCreateIo (
                            Controller,
                            Image,
                            Mtftp6ConfigDummyUdpIo,
                            UDP_IO_UDP6_VERSION,
                            NULL
                            );

  if (Mtftp6Srv->DummyUdpIo == NULL) {
    gBS->CloseEvent (Mtftp6Srv->Timer);
    FreePool (Mtftp6Srv);
    return EFI_DEVICE_ERROR;
  }

  *Service = Mtftp6Srv;
  return EFI_SUCCESS;
}


/**
  Destroy the MTFTP6 instance and recycle the resources.

  @param[in]  Instance        The pointer to the MTFTP6 instance.

**/
VOID
Mtftp6DestroyInstance (
  IN MTFTP6_INSTANCE         *Instance
  )
{
  LIST_ENTRY                 *Entry;
  LIST_ENTRY                 *Next;
  MTFTP6_BLOCK_RANGE         *Block;

  if (Instance->Config != NULL) {
    FreePool (Instance->Config);
  }

  if (Instance->Token != NULL && Instance->Token->Event != NULL) {
    gBS->SignalEvent (Instance->Token->Event);
  }

  if (Instance->LastPacket != NULL) {
    NetbufFree (Instance->LastPacket);
  }

  if (Instance->UdpIo!= NULL) {
    UdpIoFreeIo (Instance->UdpIo);
  }

  if (Instance->McastUdpIo != NULL) {
    UdpIoFreeIo (Instance->McastUdpIo);
  }

  NET_LIST_FOR_EACH_SAFE (Entry, Next, &Instance->BlkList) {
    Block = NET_LIST_USER_STRUCT (Entry, MTFTP6_BLOCK_RANGE, Link);
    RemoveEntryList (Entry);
    FreePool (Block);
  }

  FreePool (Instance);
}


/**
  Create the MTFTP6 instance and initialize it.

  @param[in]  Service              The pointer to the MTFTP6 service.
  @param[out] Instance             The pointer to the MTFTP6 instance.

  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
  @retval EFI_SUCCESS            The MTFTP6 instance is created.

**/
EFI_STATUS
Mtftp6CreateInstance (
  IN  MTFTP6_SERVICE         *Service,
  OUT MTFTP6_INSTANCE        **Instance
  )
{
  MTFTP6_INSTANCE            *Mtftp6Ins;

  *Instance = NULL;
  Mtftp6Ins = AllocateZeroPool (sizeof (MTFTP6_INSTANCE));

  if (Mtftp6Ins == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Mtftp6Ins->Signature = MTFTP6_INSTANCE_SIGNATURE;
  Mtftp6Ins->InDestory = FALSE;
  Mtftp6Ins->Service   = Service;

  CopyMem (
    &Mtftp6Ins->Mtftp6,
    &gMtftp6ProtocolTemplate,
    sizeof (EFI_MTFTP6_PROTOCOL)
    );

  InitializeListHead (&Mtftp6Ins->Link);
  InitializeListHead (&Mtftp6Ins->BlkList);

  *Instance = Mtftp6Ins;

  return EFI_SUCCESS;
}


/**
  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 MTFTP6 driver to install various protocols.

  @param[in]  ImageHandle           The firmware allocated handle for the UEFI image.
  @param[in]  SystemTable           The 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
Mtftp6DriverEntryPoint (
  IN EFI_HANDLE             ImageHandle,
  IN EFI_SYSTEM_TABLE       *SystemTable
  )
{
  return EfiLibInstallDriverBindingComponentName2 (
           ImageHandle,
           SystemTable,
           &gMtftp6DriverBinding,
           ImageHandle,
           &gMtftp6ComponentName,
           &gMtftp6ComponentName2
           );
}


/**
  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 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 Others              This driver does not support this device.

**/
EFI_STATUS
EFIAPI
Mtftp6DriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )
{
  return gBS->OpenProtocol (
                Controller,
                &gEfiUdp6ServiceBindingProtocolGuid,
                NULL,
                This->DriverBindingHandle,
                Controller,
                EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                );
}


/**
  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 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 Others               This driver does not support this device.

**/
EFI_STATUS
EFIAPI
Mtftp6DriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  MTFTP6_SERVICE            *Service;
  EFI_STATUS                Status;

  //
  // Directly return if driver is already running on this Nic handle.
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiMtftp6ServiceBindingProtocolGuid,
                  NULL,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );

  if (!EFI_ERROR (Status)) {
    return EFI_ALREADY_STARTED;
  }

  //
  // Create Mtftp6 service for this Nic handle
  //
  Status = Mtftp6CreateService (
             Controller,
             This->DriverBindingHandle,
             &Service
             );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  ASSERT (Service != NULL);

  //
  // Start the internal timer to track the packet retransmission.
  //
  Status = gBS->SetTimer (
                  Service->Timer,
                  TimerPeriodic,
                  TICKS_PER_SECOND
                  );

  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Install the Mtftp6 service on the Nic handle.
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Controller,
                  &gEfiMtftp6ServiceBindingProtocolGuid,
                  &Service->ServiceBinding,
                  NULL
                  );

  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  return EFI_SUCCESS;

ON_ERROR:

  Mtftp6DestroyService (Service);
  return Status;
}


/**
  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 EFI_DEVICE_ERROR  An unexpected error.
  @retval Others            This driver was not removed from this device.

**/
EFI_STATUS
EFIAPI
Mtftp6DriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL *This,
  IN  EFI_HANDLE                  Controller,
  IN  UINTN                       NumberOfChildren,
  IN  EFI_HANDLE                  *ChildHandleBuffer
  )
{
  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;
  MTFTP6_SERVICE                *Service;
  MTFTP6_INSTANCE               *Instance;
  EFI_HANDLE                    NicHandle;
  EFI_STATUS                    Status;
  EFI_TPL                       OldTpl;

  //
  // Locate the Nic handle to retrieve the Mtftp6 private data.
  //
  NicHandle = NetLibGetNicHandle (Controller, &gEfiUdp6ProtocolGuid);

  if (NicHandle == NULL) {
    return EFI_DEVICE_ERROR;
  }

  Status = gBS->OpenProtocol (
                  NicHandle,
                  &gEfiMtftp6ServiceBindingProtocolGuid,
                  (VOID **) &ServiceBinding,
                  This->DriverBindingHandle,
                  NicHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  Service = MTFTP6_SERVICE_FROM_THIS (ServiceBinding);

  if (Service->InDestory) {
    return EFI_SUCCESS;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  if (NumberOfChildren == 0) {
    //
    // Destory the Mtftp6 service if there is no Mtftp6 child instance left.
    //
    Service->InDestory = TRUE;

    gBS->UninstallProtocolInterface (
           NicHandle,
           &gEfiMtftp6ServiceBindingProtocolGuid,
           ServiceBinding
           );

    Mtftp6DestroyService (Service);

  } else {
    //
    // Destory the Mtftp6 child instance one by one.
    //
    while (!IsListEmpty (&Service->Children)) {
      Instance = NET_LIST_HEAD (&Service->Children, MTFTP6_INSTANCE, Link);
      Mtftp6ServiceBindingDestroyChild (ServiceBinding, Instance->Handle);
    }

    if (Service->ChildrenNum != 0) {
      Status = EFI_DEVICE_ERROR;
    }
  }

  gBS->RestoreTPL (OldTpl);
  return Status;
}


/**
  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[in]      This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
  @param[in, out] 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_SUCCES            The protocol was added to ChildHandle.
  @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
  @retval Others                The child handle was not created.

**/
EFI_STATUS
EFIAPI
Mtftp6ServiceBindingCreateChild (
  IN     EFI_SERVICE_BINDING_PROTOCOL  *This,
  IN OUT EFI_HANDLE                    *ChildHandle
  )
{
  MTFTP6_SERVICE            *Service;
  MTFTP6_INSTANCE           *Instance;
  EFI_STATUS                Status;
  EFI_TPL                   OldTpl;
  VOID                      *Udp6;

  if (This == NULL || ChildHandle == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Service = MTFTP6_SERVICE_FROM_THIS (This);

  Status = Mtftp6CreateInstance (Service, &Instance);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  ASSERT (Instance != NULL);

  //
  // Install the Mtftp6 protocol on the new child handle.
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  ChildHandle,
                  &gEfiMtftp6ProtocolGuid,
                  &Instance->Mtftp6,
                  NULL
                  );

  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  Instance->Handle = *ChildHandle;

  //
  // Open the Udp6 protocol by child.
  //
  Status = gBS->OpenProtocol (
                  Service->DummyUdpIo->UdpHandle,
                  &gEfiUdp6ProtocolGuid,
                  (VOID **) &Udp6,
                  gMtftp6DriverBinding.DriverBindingHandle,
                  Instance->Handle,
                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                  );

  if (EFI_ERROR (Status)) {
    gBS->UninstallMultipleProtocolInterfaces (
           Instance->Handle,
           &gEfiMtftp6ProtocolGuid,
           &Instance->Mtftp6,
           NULL
           );

    goto ON_ERROR;
  }

  //
  // Add the new Mtftp6 instance into the children list of Mtftp6 service.
  //
  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  InsertTailList (&Service->Children, &Instance->Link);
  Service->ChildrenNum++;

  gBS->RestoreTPL (OldTpl);
  return EFI_SUCCESS;

ON_ERROR:

  Mtftp6DestroyInstance (Instance);
  return Status;
}


/**
  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[in]  This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
  @param[in]  ChildHandle Handle of the child to destroy.

  @retval EFI_SUCCES            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 not a valid UEFI Handle.
  @retval Others                The child handle was not destroyed

**/
EFI_STATUS
EFIAPI
Mtftp6ServiceBindingDestroyChild (
  IN EFI_SERVICE_BINDING_PROTOCOL *This,
  IN EFI_HANDLE                   ChildHandle
  )
{
  MTFTP6_SERVICE            *Service;
  MTFTP6_INSTANCE           *Instance;
  EFI_MTFTP6_PROTOCOL       *Mtftp6;
  EFI_STATUS                Status;
  EFI_TPL                   OldTpl;

  if (This == NULL || ChildHandle == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Locate the Nic handle to retrieve the Mtftp6 private data.
  //
  Status = gBS->OpenProtocol (
                  ChildHandle,
                  &gEfiMtftp6ProtocolGuid,
                  (VOID **) &Mtftp6,
                  gMtftp6DriverBinding.DriverBindingHandle,
                  ChildHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  Instance = MTFTP6_INSTANCE_FROM_THIS (Mtftp6);
  Service  = MTFTP6_SERVICE_FROM_THIS (This);

  if (Instance->Service != Service) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check whether the instance already in destory state.
  //
  if (Instance->InDestory) {
    return EFI_SUCCESS;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Instance->InDestory = TRUE;

  gBS->CloseProtocol (
         Service->DummyUdpIo->UdpHandle,
         &gEfiUdp6ProtocolGuid,
         gMtftp6DriverBinding.DriverBindingHandle,
         ChildHandle
         );

  //
  // Uninstall the MTFTP6 protocol first to enable a top down destruction.
  //
  Status = gBS->UninstallProtocolInterface (
                  ChildHandle,
                  &gEfiMtftp6ProtocolGuid,
                  Mtftp6
                  );

  if (EFI_ERROR (Status)) {
    Instance->InDestory = FALSE;
    gBS->RestoreTPL (OldTpl);
    return Status;
  }

  //
  // Remove the Mtftp6 instance from the children list of Mtftp6 service.
  //
  RemoveEntryList (&Instance->Link);
  Service->ChildrenNum --;

  Mtftp6DestroyInstance (Instance);

  gBS->RestoreTPL (OldTpl);

  return EFI_SUCCESS;
}
