/** @file
  Translate the DataHub records via EFI_DATA_HUB_PROTOCOL to Smbios recorders 
  via EFI_SMBIOS_PROTOCOL.
  
Copyright (c) 2009 - 2015, 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 "Thunk.h"

EFI_SMBIOS_PROTOCOL  *mSmbiosProtocol = NULL;

/**
  Release the structure Node. 
  
  @param StructureNode  Point to SMBIOS_STRUCTURE_NODE which will be removed.
**/
VOID
ReleaseStructureNode (
  SMBIOS_STRUCTURE_NODE  *StructureNode
  )
{
  EFI_SMBIOS_PROTOCOL *Smbios;
  
  RemoveEntryList (&(StructureNode->Link));
  Smbios = GetSmbiosProtocol();
  ASSERT (Smbios != NULL);
  Smbios->Remove (Smbios, StructureNode->SmbiosHandle);
  gBS->FreePool (StructureNode);
}

/**
  Process a datahub's record and find corresponding translation way to translate
  to SMBIOS record.
  
  @param Record  Point to datahub record.
**/
VOID
SmbiosProcessDataRecord (
  IN EFI_DATA_RECORD_HEADER  *Record
  )
{
  EFI_DATA_RECORD_HEADER        *RecordHeader;
  EFI_SUBCLASS_TYPE1_HEADER     *DataHeader;
  UINTN                         Index;
  SMBIOS_CONVERSION_TABLE_ENTRY *Conversion;
  UINT8                         *SrcData;
  UINTN                         SrcDataSize;
  LIST_ENTRY                    *Link;
  SMBIOS_STRUCTURE_NODE         *StructureNode;
  BOOLEAN                       StructureCreated;
  EFI_STATUS                    Status;
  
  Conversion        = NULL;
  StructureNode     = NULL;
  StructureCreated  = FALSE;
  RecordHeader      = Record;
  DataHeader        = (EFI_SUBCLASS_TYPE1_HEADER *) (Record + 1);
  SrcData           = (UINT8 *) (DataHeader + 1);
  SrcDataSize       = RecordHeader->RecordSize - RecordHeader->HeaderSize - sizeof (EFI_SUBCLASS_TYPE1_HEADER);

  if (DataHeader->HeaderSize != sizeof (EFI_SUBCLASS_TYPE1_HEADER) ||
      DataHeader->Instance == EFI_SUBCLASS_INSTANCE_RESERVED ||
      DataHeader->SubInstance == EFI_SUBCLASS_INSTANCE_RESERVED
      ) {
    //
    // Invalid Data Record
    //
    goto Done;
  }

  Index = 0;
  while(TRUE) {
    //
    // Find a matching entry in the conversion table for this
    // (SubClass, RecordNumber) pair
    //
    for (; !CompareGuid (&(mConversionTable[Index].SubClass), &gZeroGuid); Index++) {
      if (CompareGuid (
            &(mConversionTable[Index].SubClass),
            &(RecordHeader->DataRecordGuid)
            )) {
        if (mConversionTable[Index].RecordType == DataHeader->RecordType) {
          break;
        }
      }
    }

    if (CompareGuid (&(mConversionTable[Index].SubClass), &gZeroGuid)) {
      //
      // We cannot find a matching entry in conversion table,
      // this means this data record cannot be used for SMBIOS.
      // Just skip it.
      //
      goto Done;
    }

    Conversion = &mConversionTable[Index++];

    //
    // Find corresponding structure in the Structure List
    //
    for (Link = mStructureList.ForwardLink; Link != &mStructureList; Link = Link->ForwardLink) {

      StructureNode = CR (
                        Link,
                        SMBIOS_STRUCTURE_NODE,
                        Link,
                        SMBIOS_STRUCTURE_NODE_SIGNATURE
                        );

      if (Conversion->StructureLocatingMethod == BySubclassInstanceSubinstanceProducer) {
        //
        // Look at SubClass, Instance, SubInstance and ProducerName for a matching
        // node
        //
        if (CompareGuid (&(StructureNode->SubClass), &(RecordHeader->DataRecordGuid)) &&
            StructureNode->Instance == DataHeader->Instance &&
            StructureNode->SubInstance == DataHeader->SubInstance &&
            CompareGuid (&(StructureNode->ProducerName), &(RecordHeader->ProducerName))
              ) {
          if (Conversion->SmbiosType >= 0x80) {
            if (StructureNode->SmbiosType == ((SMBIOS_STRUCTURE_HDR *) SrcData)->Type) {
              break;
            }
          } else if (StructureNode->SmbiosType == Conversion->SmbiosType) {
            break;
          }
        }

      } else if (Conversion->StructureLocatingMethod == BySubClassInstanceProducer) {
        //
        // Look at SubClass, Instance and ProducerName for a matching node
        //
        if (CompareGuid (&(StructureNode->SubClass), &(RecordHeader->DataRecordGuid)) &&
            StructureNode->Instance == DataHeader->Instance &&
            CompareGuid (&(StructureNode->ProducerName), &(RecordHeader->ProducerName))
              ) {
          if (Conversion->SmbiosType >= 0x80) {
            if (StructureNode->SmbiosType == ((SMBIOS_STRUCTURE_HDR *) SrcData)->Type) {
              break;
            }
          } else if (StructureNode->SmbiosType == Conversion->SmbiosType) {
            break;
          }
        }

      } else {
        //
        // Invalid conversion table entry
        //
        goto Done;
      }
    }

    if (Link == &mStructureList || StructureNode == NULL) {

      //
      // Not found, create a new structure
      //
      StructureNode = AllocateZeroPool (sizeof (SMBIOS_STRUCTURE_NODE));

      if (StructureNode == NULL) {
        goto Done;
      }

      if (Conversion->StructureLocatingMethod == BySubclassInstanceSubinstanceProducer) {
        //
        // Fill in SubClass, Instance, SubInstance and ProducerName
        //
        CopyMem (&(StructureNode->SubClass), &(RecordHeader->DataRecordGuid), sizeof (EFI_GUID));
        StructureNode->Instance     = DataHeader->Instance;
        StructureNode->SubInstance  = DataHeader->SubInstance;
        CopyMem (&(StructureNode->ProducerName), &(RecordHeader->ProducerName), sizeof (EFI_GUID));

      } else if (Conversion->StructureLocatingMethod == BySubClassInstanceProducer) {
        //
        // Fill in at SubClass, Instance and ProducerName, mark SubInstance as Non
        // Applicable
        //
        CopyMem (&(StructureNode->SubClass), &(RecordHeader->DataRecordGuid), sizeof (EFI_GUID));
        StructureNode->Instance     = DataHeader->Instance;
        StructureNode->SubInstance  = EFI_SUBCLASS_INSTANCE_NON_APPLICABLE;
        CopyMem (&(StructureNode->ProducerName), &(RecordHeader->ProducerName), sizeof (EFI_GUID));

      }
      //
      // Allocate the structure instance
      //
      StructureNode->StructureSize = SmbiosGetTypeMinimalLength (Conversion->SmbiosType);
      
      //
      // StructureSize include the TWO trailing zero byte.
      //
      if (StructureNode->StructureSize < (sizeof(SMBIOS_STRUCTURE) + 2)) {
        //
        // Invalid Type
        //
        gBS->FreePool (StructureNode);
        goto Done;
      }

      //
      // Assign correct SmbiosType when OEM type and Non-OEM type
      //
      if (Conversion->SmbiosType >= 0x80) {
        StructureNode->SmbiosType = ((SMBIOS_STRUCTURE_HDR *) SrcData)->Type;
      } else {
        StructureNode->SmbiosType = Conversion->SmbiosType;
      }
      
      StructureNode->SmbiosHandle        = SMBIOS_HANDLE_PI_RESERVED;
      Status = SmbiosProtocolCreateRecord (
                 NULL, 
                 StructureNode
                 );
      if (EFI_ERROR (Status)) {
        goto Done;
      }
      //
      // Temporary cache the structrue pointer to Smbios database.
      //
      StructureNode->Structure = GetSmbiosBufferFromHandle (StructureNode->SmbiosHandle, StructureNode->SmbiosType, NULL);
      
      InitializeListHead (&StructureNode->LinkDataFixup);

      //
      // Insert the Structure Node into the Strucutre List
      //
      StructureNode->Signature = SMBIOS_STRUCTURE_NODE_SIGNATURE;
      InsertTailList (&mStructureList, &(StructureNode->Link));

      StructureCreated = TRUE;

    }
    
    
    //
    // Re-calculate the structure pointer to Smbios database.
    //
    StructureNode->Structure = GetSmbiosBufferFromHandle (StructureNode->SmbiosHandle, StructureNode->SmbiosType, NULL);
    
    //
    // Fill the Structure's field corresponding to this data record
    //
    if (Conversion->FieldFillingMethod == RecordDataUnchangedOffsetSpecified) {
      //
      // Field data is just the record data without transforming and
      // offset is specified directly in the conversion table entry
      //
      if (Conversion->FieldOffset + SrcDataSize > StructureNode->Structure->Length) {
        //
        // Invalid Conversion Table Entry
        //
        if (StructureCreated) {
          ReleaseStructureNode (StructureNode);
        }

        goto Done;
      }
      
      CopyMem ((UINT8 *) (StructureNode->Structure) + Conversion->FieldOffset, SrcData, SrcDataSize);

    } else if (Conversion->FieldFillingMethod == ByFunctionWithOffsetSpecified) {
      //
      // Field offfset is specified in the conversion table entry, but
      // record data needs to be transformed to be filled into the field,
      // so let the FieldFillingFunction do it.
      //
      if (Conversion->FieldFillingFunction == NULL) {
        //
        // Invalid Conversion Table Entry
        //
        if (StructureCreated) {
          ReleaseStructureNode (StructureNode);
        }

        goto Done;
      }

      Status = Conversion->FieldFillingFunction (
                            StructureNode,
                            Conversion->FieldOffset,
                            SrcData,
                            (UINT32) SrcDataSize
                            );
      if (EFI_ERROR (Status)) {
        if (StructureCreated) {
          ReleaseStructureNode (StructureNode);
        }

        goto Done;
      }
    } else if (Conversion->FieldFillingMethod == ByFunction) {
      //
      // Both field offset and field content are determined by
      // FieldFillingFunction
      //
      if (Conversion->FieldFillingFunction == NULL) {
        //
        // Invalid Conversion Table Entry
        //
        if (StructureCreated) {
          ReleaseStructureNode (StructureNode);
        }

        goto Done;
      }

      Status = Conversion->FieldFillingFunction (
                            StructureNode,
                            0,
                            SrcData,
                            (UINT32) SrcDataSize
                            );
      if (EFI_ERROR (Status)) {
        if (StructureCreated) {
          ReleaseStructureNode (StructureNode);
        }

        goto Done;
      }
    } else if (Conversion->FieldFillingMethod == ByFunctionWithWholeDataRecord) {
      //
      // Both field offset and field content are determined by
      // FieldFillingFunction and the function accepts the whole data record
      // including the data header
      //
      if (Conversion->FieldFillingFunction == NULL) {
        //
        // Invalid Conversion Table Entry
        //
        if (StructureCreated) {
          ReleaseStructureNode (StructureNode);
        }

        goto Done;
      }

      Status = Conversion->FieldFillingFunction (
                            StructureNode,
                            0,
                            DataHeader,
                            RecordHeader->RecordSize - RecordHeader->HeaderSize
                            );
      if (EFI_ERROR (Status)) {
        if (StructureCreated) {
          ReleaseStructureNode (StructureNode);
        }

        goto Done;
      }
    } else {
      //
      // Invalid Conversion Table Entry
      //
      if (StructureCreated) {
        ReleaseStructureNode (StructureNode);
      }

      goto Done;
    }
    
    //
    // SmbiosEnlargeStructureBuffer is called to remove and add again
    // this SMBIOS entry to reflash SMBIOS table in configuration table.
    //
    SmbiosEnlargeStructureBuffer (
      StructureNode,
      StructureNode->Structure->Length,
      StructureNode->StructureSize,
      StructureNode->StructureSize
      );
  }
Done:
  return ;
}

/**
  Calculate the minimal length for a SMBIOS type. This length maybe not equal
  to sizeof (SMBIOS_RECORD_STRUCTURE), but defined in conformance chapter in SMBIOS specification.
  
  @param Type  SMBIOS's type.
  
  @return the minimal length of a smbios record.
**/
UINT32
SmbiosGetTypeMinimalLength (
  IN UINT8  Type
  )
{
  UINTN Index;

  for (Index = 0; mTypeInfoTable[Index].MinLength != 0; Index++) {
    if (mTypeInfoTable[Index].Type == Type) {
      return mTypeInfoTable[Index].MinLength;
    }
  }

  return 0;
}

/**
  Get pointer of EFI_SMBIOS_PROTOCOL.
  
  @return pointer of EFI_SMBIOS_PROTOCOL.
**/
EFI_SMBIOS_PROTOCOL*
GetSmbiosProtocol(
  VOID
  )
{
  EFI_STATUS  Status;
  
  if (mSmbiosProtocol == NULL) {
    Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID*) &mSmbiosProtocol);
    ASSERT_EFI_ERROR (Status);
  } 
  
  ASSERT (mSmbiosProtocol != NULL);
  return mSmbiosProtocol; 
}  

/**
  Create a blank smbios record. The datahub record is only a field of smbios record.
  So before fill any field from datahub's record. A blank smbios record need to be 
  created.
  
  @param ProducerHandle   The produce handle for a datahub record
  @param StructureNode    Point to SMBIOS_STRUCTURE_NODE
  
  @retval EFI_OUT_OF_RESOURCES Fail to allocate memory for new blank SMBIOS record.
  @retval EFI_SUCCESS          Success to create blank smbios record.
**/
EFI_STATUS
SmbiosProtocolCreateRecord (
  IN      EFI_HANDLE              ProducerHandle, OPTIONAL
  IN      SMBIOS_STRUCTURE_NODE   *StructureNode
  )
{
  EFI_SMBIOS_PROTOCOL         *Smbios;
  EFI_SMBIOS_TABLE_HEADER     *BlankRecord;
  EFI_STATUS                  Status;
  SMBIOS_STRUCTURE_NODE       *RefStructureNode;
  LIST_ENTRY                  *Link;
  LIST_ENTRY                  *Link1;
  LIST_ENTRY                  *Link2;  
  SMBIOS_LINK_DATA_FIXUP_NODE *LinkDataFixupNode;
  UINT8                       *BufferPointer;
  
  Smbios = GetSmbiosProtocol();
  ASSERT (Smbios != NULL);
  
  //
  // Prepare a blank smbios record.
  //
  BlankRecord = (EFI_SMBIOS_TABLE_HEADER*) AllocateZeroPool (StructureNode->StructureSize);
  if (BlankRecord == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  BlankRecord->Type   = StructureNode->SmbiosType;
  BlankRecord->Length = (UINT8) (StructureNode->StructureSize - 2);
  
  //
  // Add blank record into SMBIOS database.
  //
  Status = Smbios->Add (Smbios, NULL, &StructureNode->SmbiosHandle, BlankRecord);
  FreePool (BlankRecord);
  
  //
  // Fix up the InterLink node for new added smbios record if some other
  // existing smbios record want to link this new record's handle.
  //
  for (Link = mStructureList.ForwardLink; Link != &mStructureList; Link = Link->ForwardLink) {
    RefStructureNode = CR (Link, SMBIOS_STRUCTURE_NODE, Link, SMBIOS_STRUCTURE_NODE_SIGNATURE);
    for (Link1 = RefStructureNode->LinkDataFixup.ForwardLink; Link1 != &RefStructureNode->LinkDataFixup;) {
      LinkDataFixupNode = CR (Link1, SMBIOS_LINK_DATA_FIXUP_NODE, Link, SMBIOS_LINK_DATA_FIXUP_NODE_SIGNATURE);
      Link2 = Link1;
      Link1 = Link1->ForwardLink;
            
      if ((StructureNode->SmbiosType != LinkDataFixupNode->TargetType) ||
          !(CompareGuid (&StructureNode->SubClass, &LinkDataFixupNode->SubClass)) ||
          (StructureNode->Instance != LinkDataFixupNode->LinkData.Instance) ||
          (StructureNode->SubInstance != LinkDataFixupNode->LinkData.SubInstance)) {
        continue;
      }
      
      //
      // Fill the field with the handle found
      //
      BufferPointer         = (UINT8 *) (RefStructureNode->Structure) + LinkDataFixupNode->Offset;
      *BufferPointer        = (UINT8) (StructureNode->SmbiosHandle & 0xFF);
      *(BufferPointer + 1)  = (UINT8) ((StructureNode->SmbiosHandle >> 8) & 0xFF);
      BufferPointer         = NULL;

      RemoveEntryList (Link2);
      FreePool (LinkDataFixupNode);
    }
  }
  
  return Status;
}  

/**
  Get pointer of a SMBIOS record's buffer according to its handle.
  
  @param Handle         The handle of SMBIOS record want to be searched.
  @param Type           The type of SMBIOS record want to be searched.
  @param ProducerHandle The producer handle of SMBIOS record.
  
  @return EFI_SMBIOS_TABLE_HEADER Point to a SMBIOS record's buffer.
**/  
EFI_SMBIOS_TABLE_HEADER*
GetSmbiosBufferFromHandle (
  IN  EFI_SMBIOS_HANDLE  Handle,
  IN  EFI_SMBIOS_TYPE    Type,
  IN  EFI_HANDLE         ProducerHandle  OPTIONAL
  )
{
  EFI_SMBIOS_PROTOCOL*    Smbios;
  EFI_SMBIOS_HANDLE       SearchingHandle;
  EFI_SMBIOS_TABLE_HEADER *RecordInSmbiosDatabase;
  EFI_STATUS              Status;
  
  SearchingHandle = SMBIOS_HANDLE_PI_RESERVED;
  Smbios          = GetSmbiosProtocol();
  ASSERT (Smbios != NULL);
  
  do {
    Status = Smbios->GetNext (Smbios, &SearchingHandle, &Type, &RecordInSmbiosDatabase, NULL);
  } while ((SearchingHandle != Handle) && (Status != EFI_NOT_FOUND));
  
  return RecordInSmbiosDatabase;
}  

/**

  Get the full size of smbios structure including optional strings that follow the formatted structure.

  @param Head                   Pointer to the beginning of smbios structure.
  @param Size                   The returned size.
  @param NumberOfStrings        The returned number of optional strings that follow the formatted structure.

  @retval EFI_SUCCESS           Size retured in Size.
  @retval EFI_INVALID_PARAMETER Input smbios structure mal-formed or Size is NULL.
  
**/
EFI_STATUS
EFIAPI
GetSmbiosStructureSize (
  IN   EFI_SMBIOS_TABLE_HEADER          *Head,
  OUT  UINT32                           *Size,
  OUT  UINT8                            *NumberOfStrings
  )
{
  UINT32 FullSize;
  UINT8  StrLen;
  INT8*  CharInStr;
  
  if (Size == NULL || NumberOfStrings == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  FullSize = Head->Length;
  CharInStr = (INT8*)Head + Head->Length;
  *Size = FullSize;
  *NumberOfStrings = 0;
  StrLen = 0;
  //
  // look for the two consecutive zeros, check the string limit by the way.
  //
  while (*CharInStr != 0 || *(CharInStr+1) != 0) { 
    if (*CharInStr == 0) {
      *Size += 1;
      CharInStr++;
    }

    for (StrLen = 0 ; StrLen < SMBIOS_STRING_MAX_LENGTH; StrLen++) {
      if (*(CharInStr+StrLen) == 0) {
        break;
      }  
    }

    if (StrLen == SMBIOS_STRING_MAX_LENGTH) {
      return EFI_INVALID_PARAMETER;
    }
    //
    // forward the pointer
    //
    CharInStr += StrLen;
    *Size += StrLen;
    *NumberOfStrings += 1;
    
  }

  //
  // count ending two zeros.
  //
  *Size += 2;
  return EFI_SUCCESS;  
}
