1## @file
2# Module that encodes and decodes a FMP_PAYLOAD_HEADER with a payload.
3# The FMP_PAYLOAD_HEADER is processed by the FmpPayloadHeaderLib in the
4# FmpDevicePkg.
5#
6# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
7# SPDX-License-Identifier: BSD-2-Clause-Patent
8#
9
10'''
11FmpPayloadHeader
12'''
13
14import struct
15
16def _SIGNATURE_32 (A, B, C, D):
17    return struct.unpack ('=I',bytearray (A + B + C + D, 'ascii'))[0]
18
19def _SIGNATURE_32_TO_STRING (Signature):
20    return struct.pack ("<I", Signature).decode ()
21
22class FmpPayloadHeaderClass (object):
23    #
24    # typedef struct {
25    #   UINT32  Signature;
26    #   UINT32  HeaderSize;
27    #   UINT32  FwVersion;
28    #   UINT32  LowestSupportedVersion;
29    # } FMP_PAYLOAD_HEADER;
30    #
31    # #define FMP_PAYLOAD_HEADER_SIGNATURE SIGNATURE_32 ('M', 'S', 'S', '1')
32    #
33    _StructFormat = '<IIII'
34    _StructSize   = struct.calcsize (_StructFormat)
35
36    _FMP_PAYLOAD_HEADER_SIGNATURE = _SIGNATURE_32 ('M', 'S', 'S', '1')
37
38    def __init__ (self):
39        self._Valid                 = False
40        self.Signature              = self._FMP_PAYLOAD_HEADER_SIGNATURE
41        self.HeaderSize             = self._StructSize
42        self.FwVersion              = 0x00000000
43        self.LowestSupportedVersion = 0x00000000
44        self.Payload                = b''
45
46    def Encode (self):
47        FmpPayloadHeader = struct.pack (
48                                     self._StructFormat,
49                                     self.Signature,
50                                     self.HeaderSize,
51                                     self.FwVersion,
52                                     self.LowestSupportedVersion
53                                     )
54        self._Valid = True
55        return FmpPayloadHeader + self.Payload
56
57    def Decode (self, Buffer):
58        if len (Buffer) < self._StructSize:
59            raise ValueError
60        (Signature, HeaderSize, FwVersion, LowestSupportedVersion) = \
61            struct.unpack (
62                     self._StructFormat,
63                     Buffer[0:self._StructSize]
64                     )
65        if Signature != self._FMP_PAYLOAD_HEADER_SIGNATURE:
66            raise ValueError
67        if HeaderSize < self._StructSize:
68            raise ValueError
69        self.Signature              = Signature
70        self.HeaderSize             = HeaderSize
71        self.FwVersion              = FwVersion
72        self.LowestSupportedVersion = LowestSupportedVersion
73        self.Payload                = Buffer[self.HeaderSize:]
74
75        self._Valid                 = True
76        return self.Payload
77
78    def DumpInfo (self):
79        if not self._Valid:
80            raise ValueError
81        print ('FMP_PAYLOAD_HEADER.Signature              = {Signature:08X} ({SignatureString})'.format (Signature = self.Signature, SignatureString = _SIGNATURE_32_TO_STRING (self.Signature)))
82        print ('FMP_PAYLOAD_HEADER.HeaderSize             = {HeaderSize:08X}'.format (HeaderSize = self.HeaderSize))
83        print ('FMP_PAYLOAD_HEADER.FwVersion              = {FwVersion:08X}'.format (FwVersion = self.FwVersion))
84        print ('FMP_PAYLOAD_HEADER.LowestSupportedVersion = {LowestSupportedVersion:08X}'.format (LowestSupportedVersion = self.LowestSupportedVersion))
85        print ('sizeof (Payload)                          = {Size:08X}'.format (Size = len (self.Payload)))
86