/** @file
  RedfishSmbiosHostInterface.c

  Discover Redfish SMBIOS Host Interface.

  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "RedfishDiscoverInternal.h"

SMBIOS_TABLE_TYPE42  *mType42Record;

/**
  The function gets information reported in Redfish Host Interface.

  It simply frees the packet.

  @param[in]  Smbios           SMBIOS protocol.
  @param[out] DeviceDescriptor Pointer to REDFISH_INTERFACE_DATA.
  @param[out] ProtocolData     Pointer to REDFISH_OVER_IP_PROTOCOL_DATA.

  @retval EFI_SUCCESS    Get host interface succesfully.
  @retval Otherwise      Fail to tet host interface.

**/
EFI_STATUS
RedfishGetHostInterfaceProtocolData (
  IN EFI_SMBIOS_PROTOCOL             *Smbios,
  OUT REDFISH_INTERFACE_DATA         **DeviceDescriptor,
  OUT REDFISH_OVER_IP_PROTOCOL_DATA  **ProtocolData
  )
{
  EFI_STATUS               Status;
  EFI_SMBIOS_HANDLE        SmbiosHandle;
  EFI_SMBIOS_TABLE_HEADER  *Record;
  UINT16                   Offset;
  UINT8                    *RecordTmp;
  UINT8                    ProtocolLength;
  UINT8                    SpecificDataLen;

  if ((Smbios == NULL) || (ProtocolData == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
  Status       = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);
  while (!EFI_ERROR (Status) && SmbiosHandle != SMBIOS_HANDLE_PI_RESERVED) {
    if (Record->Type == SMBIOS_TYPE_MANAGEMENT_CONTROLLER_HOST_INTERFACE) {
      //
      // Check Interface Type, should be Network Host Interface = 40h
      //
      mType42Record = (SMBIOS_TABLE_TYPE42 *)Record;
      if (mType42Record->InterfaceType == MCHostInterfaceTypeNetworkHostInterface) {
        ASSERT (Record->Length >= 9);
        Offset    = 5;
        RecordTmp = (UINT8 *)Record + Offset;
        //
        // Get interface specific data length.
        //
        SpecificDataLen = *RecordTmp;
        Offset         += 1;
        RecordTmp       = (UINT8 *)Record + Offset;

        //
        // Check Device Type, PCI/PCIe and USB Network Interface v2 is supported.
        //
        if ((*RecordTmp == REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2) || (*RecordTmp == REDFISH_HOST_INTERFACE_DEVICE_TYPE_USB_V2)) {
          if (*RecordTmp == REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2) {
            ASSERT (SpecificDataLen == sizeof (PCI_OR_PCIE_INTERFACE_DEVICE_DESCRIPTOR_V2) + 1);
          } else {
            ASSERT (SpecificDataLen > sizeof (REDFISH_HOST_INTERFACE_DEVICE_TYPE_USB_V2) + 1);
          }

          *DeviceDescriptor = (REDFISH_INTERFACE_DATA *)RecordTmp;
          Offset            = Offset + SpecificDataLen;
          RecordTmp         = (UINT8 *)Record + Offset;
          //
          // Check Protocol count. if > 1, only use the first protocol.
          //
          ASSERT (*RecordTmp == 1);
          Offset   += 1;
          RecordTmp = (UINT8 *)Record + Offset;
          //
          // Check protocol identifier.
          //
          if (*RecordTmp == MCHostInterfaceProtocolTypeRedfishOverIP) {
            Offset        += 1;
            RecordTmp      = (UINT8 *)Record + Offset;
            ProtocolLength = *RecordTmp;

            Offset   += 1;
            RecordTmp = (UINT8 *)Record + Offset;

            //
            // This SMBIOS record is invalid, if the length of protocol specific data for
            // Redfish Over IP protocol is wrong.
            //
            if ((*(RecordTmp + 90) + sizeof (REDFISH_OVER_IP_PROTOCOL_DATA) - 1) != ProtocolLength) {
              return EFI_SECURITY_VIOLATION;
            }

            Offset += ProtocolLength;
            //
            // This SMBIOS record is invalid, if the length is smaller than the offset.
            //
            if (Offset > mType42Record->Hdr.Length) {
              return EFI_SECURITY_VIOLATION;
            }

            *ProtocolData = (REDFISH_OVER_IP_PROTOCOL_DATA *)RecordTmp;
            return EFI_SUCCESS;
          }
        }
      }
    }

    Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);
  }

  *ProtocolData = NULL;
  return EFI_NOT_FOUND;
}
