## @file
# Module that encodes and decodes a EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER with
# a payload.
#
# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#

'''
FmpCapsuleHeader
'''

import struct
import uuid

class FmpCapsuleImageHeaderClass (object):
    # typedef struct {
    #   UINT32   Version;
    #
    #   ///
    #   /// Used to identify device firmware targeted by this update. This guid is matched by
    #   /// system firmware against ImageTypeId field within a EFI_FIRMWARE_IMAGE_DESCRIPTOR
    #   ///
    #   EFI_GUID UpdateImageTypeId;
    #
    #   ///
    #   /// Passed as ImageIndex in call to EFI_FIRMWARE_MANAGEMENT_PROTOCOL.SetImage ()
    #   ///
    #   UINT8    UpdateImageIndex;
    #   UINT8    reserved_bytes[3];
    #
    #   ///
    #   /// Size of the binary update image which immediately follows this structure
    #   ///
    #   UINT32   UpdateImageSize;
    #
    #   ///
    #   /// Size of the VendorCode bytes which optionally immediately follow binary update image in the capsule
    #   ///
    #   UINT32   UpdateVendorCodeSize;
    #
    #   ///
    #   /// The HardwareInstance to target with this update. If value is zero it means match all
    #   /// HardwareInstances. This field allows update software to target only a single device in
    #   /// cases where there are more than one device with the same ImageTypeId GUID.
    #   /// This header is outside the signed data of the Authentication Info structure and
    #   /// therefore can be modified without changing the Auth data.
    #   ///
    #   UINT64   UpdateHardwareInstance;
    #
    #   ///
    #   /// Bits which indicate authentication and depex information for the image that follows this structure
    #   ///
    #   UINT64   ImageCapsuleSupport
    # } EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER;
    #
    #  #define EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION 0x00000003

    _StructFormat = '<I16sB3BIIQQ'
    _StructSize   = struct.calcsize (_StructFormat)

    EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION = 0x00000003

    def __init__ (self):
        self._Valid                 = False
        self.Version                = self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION
        self.UpdateImageTypeId      = uuid.UUID ('00000000-0000-0000-0000-000000000000')
        self.UpdateImageIndex       = 0
        self.UpdateImageSize        = 0
        self.UpdateVendorCodeSize   = 0
        self.UpdateHardwareInstance = 0x0000000000000000
        self.ImageCapsuleSupport    = 0x0000000000000000
        self.Payload                = b''
        self.VendorCodeBytes        = b''

    def Encode (self):
        self.UpdateImageSize      = len (self.Payload)
        self.UpdateVendorCodeSize = len (self.VendorCodeBytes)
        FmpCapsuleImageHeader = struct.pack (
                                         self._StructFormat,
                                         self.Version,
                                         self.UpdateImageTypeId.bytes_le,
                                         self.UpdateImageIndex,
                                         0,0,0,
                                         self.UpdateImageSize,
                                         self.UpdateVendorCodeSize,
                                         self.UpdateHardwareInstance,
                                         self.ImageCapsuleSupport
                                         )
        self._Valid = True
        return FmpCapsuleImageHeader + self.Payload + self.VendorCodeBytes

    def Decode (self, Buffer):
        if len (Buffer) < self._StructSize:
            raise ValueError ('Buffer is too small for decoding')
        (Version, UpdateImageTypeId, UpdateImageIndex, r0, r1, r2, UpdateImageSize, UpdateVendorCodeSize, UpdateHardwareInstance, ImageCapsuleSupport) = \
            struct.unpack (
                     self._StructFormat,
                     Buffer[0:self._StructSize]
                     )

        if Version < self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION:
            raise ValueError ('Incorrect capsule image header version')
        if UpdateImageIndex < 1:
            raise ValueError ('Update image index is less than 1')
        if UpdateImageSize + UpdateVendorCodeSize != len (Buffer[self._StructSize:]):
            raise ValueError ('Non-vendor and vendor parts do not add up')

        self.Version                = Version
        self.UpdateImageTypeId      = uuid.UUID (bytes_le = UpdateImageTypeId)
        self.UpdateImageIndex       = UpdateImageIndex
        self.UpdateImageSize        = UpdateImageSize
        self.UpdateVendorCodeSize   = UpdateVendorCodeSize
        self.UpdateHardwareInstance = UpdateHardwareInstance
        self.ImageCapsuleSupport    = ImageCapsuleSupport
        self.Payload                = Buffer[self._StructSize:self._StructSize + UpdateImageSize]
        self.VendorCodeBytes        = Buffer[self._StructSize + UpdateImageSize:]
        self._Valid                 = True
        return Buffer[self._StructSize:]

    def DumpInfo (self):
        if not self._Valid:
            raise ValueError ('Can not dump an invalid header')
        print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.Version                = {Version:08X}'.format (Version = self.Version))
        print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageTypeId      = {UpdateImageTypeId}'.format (UpdateImageTypeId = str(self.UpdateImageTypeId).upper()))
        print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageIndex       = {UpdateImageIndex:08X}'.format (UpdateImageIndex = self.UpdateImageIndex))
        print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageSize        = {UpdateImageSize:08X}'.format (UpdateImageSize = self.UpdateImageSize))
        print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateVendorCodeSize   = {UpdateVendorCodeSize:08X}'.format (UpdateVendorCodeSize = self.UpdateVendorCodeSize))
        print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateHardwareInstance = {UpdateHardwareInstance:016X}'.format (UpdateHardwareInstance = self.UpdateHardwareInstance))
        print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.ImageCapsuleSupport    = {ImageCapsuleSupport:016X}'.format (ImageCapsuleSupport = self.ImageCapsuleSupport))
        print ('sizeof (Payload)                                                    = {Size:08X}'.format (Size = len (self.Payload)))
        print ('sizeof (VendorCodeBytes)                                            = {Size:08X}'.format (Size = len (self.VendorCodeBytes)))

class FmpCapsuleHeaderClass (object):
    # typedef struct {
    #   UINT32 Version;
    #
    #   ///
    #   /// The number of drivers included in the capsule and the number of corresponding
    #   /// offsets stored in ItemOffsetList array.
    #   ///
    #   UINT16 EmbeddedDriverCount;
    #
    #   ///
    #   /// The number of payload items included in the capsule and the number of
    #   /// corresponding offsets stored in the ItemOffsetList array.
    #   ///
    #   UINT16 PayloadItemCount;
    #
    #   ///
    #   /// Variable length array of dimension [EmbeddedDriverCount + PayloadItemCount]
    #   /// containing offsets of each of the drivers and payload items contained within the capsule
    #   ///
    #   // UINT64 ItemOffsetList[];
    # } EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER;
    #
    #  #define EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION       0x00000001
    _StructFormat = '<IHH'
    _StructSize   = struct.calcsize (_StructFormat)

    _ItemOffsetFormat = '<Q'
    _ItemOffsetSize   = struct.calcsize (_ItemOffsetFormat)

    EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION = 0x00000001
    CAPSULE_SUPPORT_AUTHENTICATION = 0x0000000000000001
    CAPSULE_SUPPORT_DEPENDENCY     = 0x0000000000000002

    def __init__ (self):
        self._Valid                     = False
        self.Version                    = self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION
        self.EmbeddedDriverCount        = 0
        self.PayloadItemCount           = 0
        self._ItemOffsetList            = []
        self._EmbeddedDriverList        = []
        self._PayloadList               = []
        self._FmpCapsuleImageHeaderList = []

    def AddEmbeddedDriver (self, EmbeddedDriver):
        self._EmbeddedDriverList.append (EmbeddedDriver)

    def GetEmbeddedDriver (self, Index):
        if Index > len (self._EmbeddedDriverList):
            raise ValueError ('Invalid embedded driver index')
        return self._EmbeddedDriverList[Index]

    def AddPayload (self, UpdateImageTypeId, Payload = b'', VendorCodeBytes = b'', HardwareInstance = 0, UpdateImageIndex = 1, CapsuleSupport = 0):
        self._PayloadList.append ((UpdateImageTypeId, Payload, VendorCodeBytes, HardwareInstance, UpdateImageIndex, CapsuleSupport))

    def GetFmpCapsuleImageHeader (self, Index):
        if Index >= len (self._FmpCapsuleImageHeaderList):
            raise ValueError ('Invalid capsule image index')
        return self._FmpCapsuleImageHeaderList[Index]

    def Encode (self):
        self.EmbeddedDriverCount = len (self._EmbeddedDriverList)
        self.PayloadItemCount    = len (self._PayloadList)

        FmpCapsuleHeader = struct.pack (
                                    self._StructFormat,
                                    self.Version,
                                    self.EmbeddedDriverCount,
                                    self.PayloadItemCount
                                    )

        FmpCapsuleData = b''
        Offset = self._StructSize + (self.EmbeddedDriverCount + self.PayloadItemCount) * self._ItemOffsetSize
        for EmbeddedDriver in self._EmbeddedDriverList:
            FmpCapsuleData = FmpCapsuleData + EmbeddedDriver
            self._ItemOffsetList.append (Offset)
            Offset = Offset + len (EmbeddedDriver)
        Index = 1
        for (UpdateImageTypeId, Payload, VendorCodeBytes, HardwareInstance, UpdateImageIndex, CapsuleSupport) in self._PayloadList:
            FmpCapsuleImageHeader = FmpCapsuleImageHeaderClass ()
            FmpCapsuleImageHeader.UpdateImageTypeId      = UpdateImageTypeId
            FmpCapsuleImageHeader.UpdateImageIndex       = UpdateImageIndex
            FmpCapsuleImageHeader.Payload                = Payload
            FmpCapsuleImageHeader.VendorCodeBytes        = VendorCodeBytes
            FmpCapsuleImageHeader.UpdateHardwareInstance = HardwareInstance
            FmpCapsuleImageHeader.ImageCapsuleSupport    = CapsuleSupport
            FmpCapsuleImage = FmpCapsuleImageHeader.Encode ()
            FmpCapsuleData = FmpCapsuleData + FmpCapsuleImage

            self._ItemOffsetList.append (Offset)
            self._FmpCapsuleImageHeaderList.append (FmpCapsuleImageHeader)

            Offset = Offset + len (FmpCapsuleImage)
            Index = Index + 1

        for Offset in self._ItemOffsetList:
          FmpCapsuleHeader = FmpCapsuleHeader + struct.pack (self._ItemOffsetFormat, Offset)

        self._Valid = True
        return FmpCapsuleHeader + FmpCapsuleData

    def Decode (self, Buffer):
        if len (Buffer) < self._StructSize:
            raise ValueError ('Buffer is too small for decoding')
        (Version, EmbeddedDriverCount, PayloadItemCount) = \
            struct.unpack (
                     self._StructFormat,
                     Buffer[0:self._StructSize]
                     )
        if Version < self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION:
            raise ValueError ('Incorrect capsule header version')

        self.Version                    = Version
        self.EmbeddedDriverCount        = EmbeddedDriverCount
        self.PayloadItemCount           = PayloadItemCount
        self._ItemOffsetList            = []
        self._EmbeddedDriverList        = []
        self._PayloadList               = []
        self._FmpCapsuleImageHeaderList = []

        #
        # Parse the ItemOffsetList values
        #
        Offset = self._StructSize
        for Index in range (0, EmbeddedDriverCount + PayloadItemCount):
            ItemOffset = struct.unpack (self._ItemOffsetFormat, Buffer[Offset:Offset + self._ItemOffsetSize])[0]
            if ItemOffset >= len (Buffer):
                raise ValueError ('Item offset is outside of buffer')
            self._ItemOffsetList.append (ItemOffset)
            Offset = Offset + self._ItemOffsetSize
        Result = Buffer[Offset:]

        #
        # Parse the EmbeddedDrivers
        #
        for Index in range (0, EmbeddedDriverCount):
            Offset = self._ItemOffsetList[Index]
            if Index < (len (self._ItemOffsetList) - 1):
                Length = self._ItemOffsetList[Index + 1] - Offset
            else:
                Length = len (Buffer) - Offset
            self.AddEmbeddedDriver (Buffer[Offset:Offset + Length])

        #
        # Parse the Payloads that are FMP Capsule Images
        #
        for Index in range (EmbeddedDriverCount, EmbeddedDriverCount + PayloadItemCount):
            Offset = self._ItemOffsetList[Index]
            if Index < (len (self._ItemOffsetList) - 1):
                Length = self._ItemOffsetList[Index + 1] - Offset
            else:
                Length = len (Buffer) - Offset
            FmpCapsuleImageHeader = FmpCapsuleImageHeaderClass ()
            FmpCapsuleImageHeader.Decode (Buffer[Offset:Offset + Length])
            self.AddPayload (
                   FmpCapsuleImageHeader.UpdateImageTypeId,
                   FmpCapsuleImageHeader.Payload,
                   FmpCapsuleImageHeader.VendorCodeBytes
                   )
            self._FmpCapsuleImageHeaderList.append (FmpCapsuleImageHeader)

        self._Valid = True
        return Result

    def DumpInfo (self):
        if not self._Valid:
            raise ValueError ('Can not dump an invalid header')
        print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.Version             = {Version:08X}'.format (Version = self.Version))
        print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.EmbeddedDriverCount = {EmbeddedDriverCount:08X}'.format (EmbeddedDriverCount = self.EmbeddedDriverCount))
        for EmbeddedDriver in self._EmbeddedDriverList:
            print ('  sizeof (EmbeddedDriver)                                  = {Size:08X}'.format (Size = len (EmbeddedDriver)))
        print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.PayloadItemCount    = {PayloadItemCount:08X}'.format (PayloadItemCount = self.PayloadItemCount))
        print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.ItemOffsetList      = ')
        for Offset in self._ItemOffsetList:
            print ('  {Offset:016X}'.format (Offset = Offset))
        for FmpCapsuleImageHeader in self._FmpCapsuleImageHeaderList:
            FmpCapsuleImageHeader.DumpInfo ()
