Add EFI REST EX helper library to create child instance of REST EX service. Signed-off-by: Abner Chang <abner.chang@hpe.com> Cc: Jiaxin Wu <jiaxin.wu@intel.com> Cc: Siyuan Fu <siyuan.fu@intel.com> Cc: Fan Wang <fan.wang@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Nickle Wang <nickle.wang@hpe.com> Cc: Peter O'Hanley <peter.ohanley@hpe.com> Reviewed-by: Nickle Wang <nickle.wang@hpe.com>
		
			
				
	
	
		
			167 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			167 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  This library provides help functions for REST EX Protocol.
 | 
						|
 | 
						|
  (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
 | 
						|
 | 
						|
  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include <Uefi.h>
 | 
						|
#include <Library/BaseMemoryLib.h>
 | 
						|
#include <Library/MemoryAllocationLib.h>
 | 
						|
#include <Library/NetLib.h>
 | 
						|
#include <Library/UefiBootServicesTableLib.h>
 | 
						|
#include <Protocol/Http.h>
 | 
						|
#include <Protocol/RestEx.h>
 | 
						|
 | 
						|
#define REST_EX_CONFIG_DATA_LEN_UNKNOWN 0xff
 | 
						|
 | 
						|
/**
 | 
						|
  This function allows the caller to create child handle for specific
 | 
						|
  REST server.
 | 
						|
 | 
						|
  @param[in]  Image                The image handle used to open service.
 | 
						|
  @param[in]  AccessMode           Access mode of REST server.
 | 
						|
  @param[in]  ConfigType           Underlying configuration to communicate with REST server.
 | 
						|
  @param[in]  ServiceType          REST service type.
 | 
						|
  @param[out] ChildInstanceHandle  The handle to receive the create child.
 | 
						|
 | 
						|
  @retval  EFI_SUCCESS            Can't create the corresponding REST EX child instance.
 | 
						|
  @retval  EFI_INVALID_PARAMETERS Any of input parameters is improper.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
RestExLibCreateChild (
 | 
						|
  IN EFI_HANDLE Image,
 | 
						|
  IN EFI_REST_EX_SERVICE_ACCESS_MODE  AccessMode,
 | 
						|
  IN EFI_REST_EX_CONFIG_TYPE ConfigType,
 | 
						|
  IN EFI_REST_EX_SERVICE_TYPE ServiceType,
 | 
						|
  OUT EFI_HANDLE *ChildInstanceHandle
 | 
						|
)
 | 
						|
{
 | 
						|
  EFI_STATUS Status;
 | 
						|
  UINTN NoBuffer;
 | 
						|
  EFI_HANDLE *Handle;
 | 
						|
  EFI_HANDLE ChildHandle;
 | 
						|
  EFI_REST_EX_PROTOCOL *RestEx;
 | 
						|
  EFI_REST_EX_SERVICE_INFO *RestExServiceInfo;
 | 
						|
  UINT8 LenOfConfig;
 | 
						|
 | 
						|
  if (Image == NULL ||
 | 
						|
      AccessMode >= EfiRestExServiceModeMax ||
 | 
						|
      ConfigType >= EfiRestExConfigTypeMax ||
 | 
						|
      ServiceType >= EfiRestExServiceTypeMax ||
 | 
						|
      ChildInstanceHandle == NULL
 | 
						|
      ) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  *ChildInstanceHandle = NULL;
 | 
						|
  //
 | 
						|
  // Locate all REST EX binding service.
 | 
						|
  //
 | 
						|
  Handle = NULL;
 | 
						|
  NoBuffer = 0;
 | 
						|
  Status = gBS->LocateHandleBuffer (
 | 
						|
              ByProtocol,
 | 
						|
              &gEfiRestExServiceBindingProtocolGuid,
 | 
						|
              NULL,
 | 
						|
              &NoBuffer,
 | 
						|
              &Handle
 | 
						|
            );
 | 
						|
  if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
  Handle = (EFI_HANDLE *)AllocateZeroPool (sizeof(EFI_HANDLE) * NoBuffer);
 | 
						|
  if (Handle == NULL) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
  Status = gBS->LocateHandleBuffer (
 | 
						|
              ByProtocol,
 | 
						|
              &gEfiRestExServiceBindingProtocolGuid,
 | 
						|
              NULL,
 | 
						|
              &NoBuffer,
 | 
						|
              &Handle
 | 
						|
            );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    FreePool (Handle);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Search for the proper REST EX instance.
 | 
						|
  //
 | 
						|
  while (NoBuffer != 0) {
 | 
						|
    ChildHandle = NULL;
 | 
						|
    Status = NetLibCreateServiceChild (
 | 
						|
                *(Handle + (NoBuffer - 1)),
 | 
						|
                Image,
 | 
						|
                &gEfiRestExServiceBindingProtocolGuid,
 | 
						|
                &ChildHandle
 | 
						|
                );
 | 
						|
    if (!EFI_ERROR (Status)) {
 | 
						|
      Status = gBS->OpenProtocol (
 | 
						|
                  ChildHandle,
 | 
						|
                  &gEfiRestExProtocolGuid,
 | 
						|
                  (VOID **)&RestEx,
 | 
						|
                  Image,
 | 
						|
                  NULL,
 | 
						|
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
 | 
						|
                  );
 | 
						|
      if (EFI_ERROR (Status)) {
 | 
						|
        goto ON_ERROR;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      // Get the information of REST service provided by this EFI REST EX driver
 | 
						|
      //
 | 
						|
      Status = RestEx->GetService (
 | 
						|
                            RestEx,
 | 
						|
                            &RestExServiceInfo
 | 
						|
                            );
 | 
						|
      if (EFI_ERROR (Status)) {
 | 
						|
        goto ON_ERROR;
 | 
						|
      }
 | 
						|
      //
 | 
						|
      // Check REST EX property.
 | 
						|
      //
 | 
						|
      switch (ConfigType) {
 | 
						|
        case EfiRestExConfigHttp:
 | 
						|
          LenOfConfig = sizeof (EFI_REST_EX_HTTP_CONFIG_DATA);
 | 
						|
          break;
 | 
						|
 | 
						|
        case EfiRestExConfigUnspecific:
 | 
						|
          LenOfConfig = REST_EX_CONFIG_DATA_LEN_UNKNOWN;
 | 
						|
          break;
 | 
						|
 | 
						|
        default:
 | 
						|
          goto ON_ERROR;
 | 
						|
      }
 | 
						|
      if (RestExServiceInfo->EfiRestExServiceInfoV10.RestServiceAccessMode != AccessMode ||
 | 
						|
          RestExServiceInfo->EfiRestExServiceInfoV10.RestServiceType != ServiceType ||
 | 
						|
          RestExServiceInfo->EfiRestExServiceInfoV10.RestExConfigType != ConfigType ||
 | 
						|
          ((LenOfConfig != REST_EX_CONFIG_DATA_LEN_UNKNOWN) && (RestExServiceInfo->EfiRestExServiceInfoV10.RestExConfigDataLength != LenOfConfig))) {
 | 
						|
        goto ON_ERROR;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // This is proper REST EX instance.
 | 
						|
    //
 | 
						|
    *ChildInstanceHandle = ChildHandle;
 | 
						|
    FreePool (Handle);
 | 
						|
    return EFI_SUCCESS;
 | 
						|
 | 
						|
ON_ERROR:;
 | 
						|
    NetLibDestroyServiceChild (
 | 
						|
      *(Handle + (NoBuffer - 1)),
 | 
						|
      Image,
 | 
						|
      &gEfiRestExServiceBindingProtocolGuid,
 | 
						|
      ChildHandle
 | 
						|
      );
 | 
						|
    NoBuffer --;
 | 
						|
  };
 | 
						|
  FreePool (Handle);
 | 
						|
  return EFI_NOT_FOUND;
 | 
						|
}
 |