/** @file
  Driver Binding functions and Service Binding functions
  implementation for Mtftp6 Driver.

  Copyright (c) 2009 - 2012, 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
};


/**
  Destroy 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 destroyed.
  //
  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->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->InDestroy = FALSE;
  Mtftp6Ins->Service   = Service;

  CopyMem (
    &Mtftp6Ins->Mtftp6,
    &gMtftp6ProtocolTemplate,
    sizeof (EFI_MTFTP6_PROTOCOL)
    );

  InitializeListHead (&Mtftp6Ins->Link);
  InitializeListHead (&Mtftp6Ins->BlkList);

  *Instance = Mtftp6Ins;

  return EFI_SUCCESS;
}


/**
  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
Mtftp6DestroyChildEntryInHandleBuffer (
  IN LIST_ENTRY         *Entry,
  IN VOID               *Context
  )
{
  MTFTP6_INSTANCE               *Instance;
  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;
  UINTN                         NumberOfChildren;
  EFI_HANDLE                    *ChildHandleBuffer;

  if (Entry == NULL || Context == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = NET_LIST_USER_STRUCT_S (Entry, MTFTP6_INSTANCE, Link, MTFTP6_INSTANCE_SIGNATURE);
  ServiceBinding    = ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
  NumberOfChildren  = ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
  ChildHandleBuffer = ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;

  if (!NetIsInHandleBuffer (Instance->Handle, NumberOfChildren, ChildHandleBuffer)) {
    return EFI_SUCCESS;
  }

  return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
}


/**
  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 Controller. 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]  Controller          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 Controller. 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]  Controller           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 Controller.
  @retval EFI_ALREADY_STARTED  This driver is already running on Controller.
  @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 Controller. This service is called by the
  EFI boot service DisconnectController(). In order to
  make drivers as small as possible, there are 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]  Controller        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 Controller.
  @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;
  EFI_HANDLE                                 NicHandle;
  EFI_STATUS                                 Status;
  LIST_ENTRY                                 *List;
  MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
  
  //
  // Locate the Nic handle to retrieve the Mtftp6 private data.
  //
  NicHandle = NetLibGetNicHandle (Controller, &gEfiUdp6ProtocolGuid);

  if (NicHandle == NULL) {
    return EFI_SUCCESS;
  }

  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 (!IsListEmpty (&Service->Children)) {
    //
    // Destroy the Mtftp6 child instance in ChildHandleBuffer.
    //
    List = &Service->Children;
    Context.ServiceBinding    = ServiceBinding;
    Context.NumberOfChildren  = NumberOfChildren;
    Context.ChildHandleBuffer = ChildHandleBuffer;
    Status = NetDestroyLinkList (
               List,
               Mtftp6DestroyChildEntryInHandleBuffer,
               &Context,
               NULL
               );
  }

  if (NumberOfChildren == 0 && IsListEmpty (&Service->Children)) {
    //
    // Destroy the Mtftp6 service if there is no Mtftp6 child instance left.
    //
    gBS->UninstallProtocolInterface (
           NicHandle,
           &gEfiMtftp6ServiceBindingProtocolGuid,
           ServiceBinding
           );

    Mtftp6DestroyService (Service);
    Status = EFI_SUCCESS;
  }

  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 NULL.
  @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 Destroy state.
  //
  if (Instance->InDestroy) {
    return EFI_SUCCESS;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Instance->InDestroy = TRUE;

  gBS->CloseProtocol (
         Service->DummyUdpIo->UdpHandle,
         &gEfiUdp6ProtocolGuid,
         gMtftp6DriverBinding.DriverBindingHandle,
         ChildHandle
         );

  if (Instance->UdpIo != NULL) {
    gBS->CloseProtocol (
         Instance->UdpIo->UdpHandle,
         &gEfiUdp6ProtocolGuid,
         gMtftp6DriverBinding.DriverBindingHandle,
         Instance->Handle
         );
  }

  if (Instance->McastUdpIo != NULL) {
    gBS->CloseProtocol (
           Instance->McastUdpIo->UdpHandle,
           &gEfiUdp6ProtocolGuid,
           gMtftp6DriverBinding.DriverBindingHandle,
           Instance->Handle
           );
  }

  //
  // Uninstall the MTFTP6 protocol first to enable a top down destruction.
  //
  gBS->RestoreTPL (OldTpl);
  Status = gBS->UninstallProtocolInterface (
                  ChildHandle,
                  &gEfiMtftp6ProtocolGuid,
                  Mtftp6
                  );
  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
  if (EFI_ERROR (Status)) {
    Instance->InDestroy = FALSE;
    gBS->RestoreTPL (OldTpl);
    return Status;
  }

  //
  // Remove the Mtftp6 instance from the children list of Mtftp6 service.
  //
  RemoveEntryList (&Instance->Link);
  Service->ChildrenNum --;

  gBS->RestoreTPL (OldTpl);

  Mtftp6DestroyInstance (Instance);

  return EFI_SUCCESS;
}
