1 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
2 #ifndef FW_UPDATE_H
3 #define FW_UPDATE_H
4
5 #ifdef __cplusplus
6 extern "C" {
7 #endif
8
9 #include "compiler.h"
10
11 #include <libpldm/api.h>
12 #include <libpldm/base.h>
13 #include <libpldm/pldm_types.h>
14 #include <libpldm/utils.h>
15
16 #include <assert.h>
17 #include <stdbool.h>
18 #include <stddef.h>
19 #include <stdint.h>
20
21 #define PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE 8
22 #define PLDM_FWUP_INVALID_COMPONENT_COMPARISON_TIMESTAMP 0xffffffff
23 #define PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES 0
24
25 /** @brief Length of QueryDownstreamDevices response defined in DSP0267_1.1.0
26 * Table 15 - QueryDownstreamDevices command format.
27 *
28 * 1 byte for completion code
29 * 1 byte for downstream device update supported
30 * 2 bytes for number of downstream devices
31 * 2 bytes for max number of downstream devices
32 * 4 bytes for capabilities
33 */
34 #define PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES 10
35
36 /** @brief Length of QueryDownstreamIdentifiers request defined in DSP0267_1.1.0
37 * Table 16 - QueryDownstreamIdentifiers command format.
38 *
39 * 4 bytes for data transfer handle
40 * 1 byte for transfer operation flag
41 */
42 #define PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES 5
43
44 /** @brief Minimum length of QueryDownstreamIdentifiers response from DSP0267_1.1.0
45 * if the complement code is success.
46 *
47 * 1 byte for completion code
48 * 4 bytes for next data transfer handle
49 * 1 byte for transfer flag
50 * 4 bytes for downstream devices length
51 * 2 bytes for number of downstream devices
52 */
53 #define PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN 12
54
55 /** @brief Minimum length of device descriptor, 2 bytes for descriptor type,
56 * 2 bytes for descriptor length and at least 1 byte of descriptor data
57 */
58 #define PLDM_FWUP_DEVICE_DESCRIPTOR_MIN_LEN 5
59
60 /** @brief Length of GetDownstreamFirmwareParameters request defined in DSP0267_1.1.0
61 *
62 * 4 bytes for Data Transfer Handle
63 * 1 byte for Transfer Operation Flag
64 */
65 #define PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES 5
66
67 /** @brief Minimum length of GetDownstreamFirmwareParameters response from
68 * DSP0267_1.1.0 if the completion code is success.
69 *
70 * 1 byte for completion code
71 * 4 bytes for next data transfer handle
72 * 1 byte for transfer flag
73 * 4 bytes for FDP capabilities during update
74 * 2 bytes for downstream device count
75 */
76 #define PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN 12
77
78 /** @brief Minimum length of DownstreamDeviceParameterTable entry from
79 * DSP0267_1.1.0 table 21 - DownstreamDeviceParameterTable
80 *
81 * 2 bytes for Downstream Device Index
82 * 4 bytes for Active Component Comparison Stamp
83 * 1 byte for Active Component Version String Type
84 * 1 byte for Active Component Version String Length
85 * 8 bytes for Active Component Release Date
86 * 4 bytes for Pending Component Comparison Stamp
87 * 1 byte for Pending Component Version String Type
88 * 1 byte for Pending Component Version String Length
89 * 8 bytes for Pending Component Release Date
90 * 2 bytes for Component Activation Methods
91 * 4 bytes for Capabilities During Update
92 */
93 #define PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN 36
94
95 #define PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES 0
96 #define PLDM_FWUP_BASELINE_TRANSFER_SIZE 32
97 #define PLDM_FWUP_MIN_OUTSTANDING_REQ 1
98 #define PLDM_GET_STATUS_REQ_BYTES 0
99 /* Maximum progress percentage value*/
100 #define PLDM_FWUP_MAX_PROGRESS_PERCENT 0x65
101 #define PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES 0
102 #define PLDM_CANCEL_UPDATE_REQ_BYTES 0
103
104 /** @brief PLDM component release data size in bytes defined in DSP0267_1.1.0
105 * Table 14 - ComponentParameterTable and Table 21 - ComponentParameterTable
106 *
107 * The size can be used in `ASCII[8] - ActiveComponentReleaseDate` and
108 * `ASCII[8] - PendingComponentReleaseDate` fields in the tables above.
109 */
110 #define PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN 8
111
112 /** @brief PLDM Firmware update commands
113 */
114 enum pldm_firmware_update_commands {
115 PLDM_QUERY_DEVICE_IDENTIFIERS = 0x01,
116 PLDM_GET_FIRMWARE_PARAMETERS = 0x02,
117 PLDM_QUERY_DOWNSTREAM_DEVICES = 0x03,
118 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS = 0x04,
119 PLDM_QUERY_DOWNSTREAM_FIRMWARE_PARAMETERS = 0x05,
120 PLDM_REQUEST_UPDATE = 0x10,
121 PLDM_PASS_COMPONENT_TABLE = 0x13,
122 PLDM_UPDATE_COMPONENT = 0x14,
123 PLDM_REQUEST_FIRMWARE_DATA = 0x15,
124 PLDM_TRANSFER_COMPLETE = 0x16,
125 PLDM_VERIFY_COMPLETE = 0x17,
126 PLDM_APPLY_COMPLETE = 0x18,
127 PLDM_GET_META_DATA = 0x19,
128 PLDM_ACTIVATE_FIRMWARE = 0x1a,
129 PLDM_GET_STATUS = 0x1b,
130 PLDM_CANCEL_UPDATE_COMPONENT = 0x1c,
131 PLDM_CANCEL_UPDATE = 0x1d,
132 PLDM_ACTIVATE_PENDING_COMPONENT_IMAGE_SET = 0x1e,
133 PLDM_ACTIVATE_PENDING_COMPONENT_IMAGE = 0x1f,
134 PLDM_REQUEST_DOWNSTREAM_DEVICE_UPDATE = 0x20,
135 PLDM_GET_COMPONENT_OPAQUE_DATA = 0x21,
136 PLDM_UPTATE_SECURITY_REVISION = 0x22
137 };
138
139 /** @brief PLDM Firmware update completion codes
140 */
141 enum pldm_firmware_update_completion_codes {
142 PLDM_FWUP_NOT_IN_UPDATE_MODE = 0x80,
143 PLDM_FWUP_ALREADY_IN_UPDATE_MODE = 0x81,
144 PLDM_FWUP_DATA_OUT_OF_RANGE = 0x82,
145 PLDM_FWUP_INVALID_TRANSFER_LENGTH = 0x83,
146 PLDM_FWUP_INVALID_STATE_FOR_COMMAND = 0x84,
147 PLDM_FWUP_INCOMPLETE_UPDATE = 0x85,
148 PLDM_FWUP_BUSY_IN_BACKGROUND = 0x86,
149 PLDM_FWUP_CANCEL_PENDING = 0x87,
150 PLDM_FWUP_COMMAND_NOT_EXPECTED = 0x88,
151 PLDM_FWUP_RETRY_REQUEST_FW_DATA = 0x89,
152 PLDM_FWUP_UNABLE_TO_INITIATE_UPDATE = 0x8a,
153 PLDM_FWUP_ACTIVATION_NOT_REQUIRED = 0x8b,
154 PLDM_FWUP_SELF_CONTAINED_ACTIVATION_NOT_PERMITTED = 0x8c,
155 PLDM_FWUP_NO_DEVICE_METADATA = 0x8d,
156 PLDM_FWUP_RETRY_REQUEST_UPDATE = 0x8e,
157 PLDM_FWUP_NO_PACKAGE_DATA = 0x8f,
158 PLDM_FWUP_INVALID_TRANSFER_HANDLE = 0x90,
159 PLDM_FWUP_INVALID_TRANSFER_OPERATION_FLAG = 0x91,
160 PLDM_FWUP_ACTIVATE_PENDING_IMAGE_NOT_PERMITTED = 0x92,
161 PLDM_FWUP_PACKAGE_DATA_ERROR = 0x93
162 };
163
164 /** @brief String type values defined in the PLDM firmware update specification
165 */
166 enum pldm_firmware_update_string_type {
167 PLDM_STR_TYPE_UNKNOWN = 0,
168 PLDM_STR_TYPE_ASCII = 1,
169 PLDM_STR_TYPE_UTF_8 = 2,
170 PLDM_STR_TYPE_UTF_16 = 3,
171 PLDM_STR_TYPE_UTF_16LE = 4,
172 PLDM_STR_TYPE_UTF_16BE = 5
173 };
174
175 /** @brief Descriptor types defined in PLDM firmware update specification
176 */
177 enum pldm_firmware_update_descriptor_types {
178 PLDM_FWUP_PCI_VENDOR_ID = 0x0000,
179 PLDM_FWUP_IANA_ENTERPRISE_ID = 0x0001,
180 PLDM_FWUP_UUID = 0x0002,
181 PLDM_FWUP_PNP_VENDOR_ID = 0x0003,
182 PLDM_FWUP_ACPI_VENDOR_ID = 0x0004,
183 PLDM_FWUP_IEEE_ASSIGNED_COMPANY_ID = 0x0005,
184 PLDM_FWUP_SCSI_VENDOR_ID = 0x0006,
185 PLDM_FWUP_PCI_DEVICE_ID = 0x0100,
186 PLDM_FWUP_PCI_SUBSYSTEM_VENDOR_ID = 0x0101,
187 PLDM_FWUP_PCI_SUBSYSTEM_ID = 0x0102,
188 PLDM_FWUP_PCI_REVISION_ID = 0x0103,
189 PLDM_FWUP_PNP_PRODUCT_IDENTIFIER = 0x0104,
190 PLDM_FWUP_ACPI_PRODUCT_IDENTIFIER = 0x0105,
191 PLDM_FWUP_ASCII_MODEL_NUMBER_LONG_STRING = 0x0106,
192 PLDM_FWUP_ASCII_MODEL_NUMBER_SHORT_STRING = 0x0107,
193 PLDM_FWUP_SCSI_PRODUCT_ID = 0x0108,
194 PLDM_FWUP_UBM_CONTROLLER_DEVICE_CODE = 0x0109,
195 PLDM_FWUP_VENDOR_DEFINED = 0xffff
196 };
197
198 /** @brief Descriptor types length defined in PLDM firmware update specification
199 */
200 enum pldm_firmware_update_descriptor_types_length {
201 PLDM_FWUP_PCI_VENDOR_ID_LENGTH = 2,
202 PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH = 4,
203 PLDM_FWUP_UUID_LENGTH = 16,
204 PLDM_FWUP_PNP_VENDOR_ID_LENGTH = 3,
205 PLDM_FWUP_ACPI_VENDOR_ID_LENGTH = 4,
206 PLDM_FWUP_IEEE_ASSIGNED_COMPANY_ID_LENGTH = 3,
207 PLDM_FWUP_SCSI_VENDOR_ID_LENGTH = 8,
208 PLDM_FWUP_PCI_DEVICE_ID_LENGTH = 2,
209 PLDM_FWUP_PCI_SUBSYSTEM_VENDOR_ID_LENGTH = 2,
210 PLDM_FWUP_PCI_SUBSYSTEM_ID_LENGTH = 2,
211 PLDM_FWUP_PCI_REVISION_ID_LENGTH = 1,
212 PLDM_FWUP_PNP_PRODUCT_IDENTIFIER_LENGTH = 4,
213 PLDM_FWUP_ACPI_PRODUCT_IDENTIFIER_LENGTH = 4,
214 PLDM_FWUP_ASCII_MODEL_NUMBER_LONG_STRING_LENGTH = 40,
215 PLDM_FWUP_ASCII_MODEL_NUMBER_SHORT_STRING_LENGTH = 10,
216 PLDM_FWUP_SCSI_PRODUCT_ID_LENGTH = 16,
217 PLDM_FWUP_UBM_CONTROLLER_DEVICE_CODE_LENGTH = 4
218 };
219
220 /** @brief ComponentClassification values defined in firmware update
221 * specification
222 */
223 enum pldm_component_classification_values {
224 PLDM_COMP_UNKNOWN = 0x0000,
225 PLDM_COMP_OTHER = 0x0001,
226 PLDM_COMP_DRIVER = 0x0002,
227 PLDM_COMP_CONFIGURATION_SOFTWARE = 0x0003,
228 PLDM_COMP_APPLICATION_SOFTWARE = 0x0004,
229 PLDM_COMP_INSTRUMENTATION = 0x0005,
230 PLDM_COMP_FIRMWARE_OR_BIOS = 0x0006,
231 PLDM_COMP_DIAGNOSTIC_SOFTWARE = 0x0007,
232 PLDM_COMP_OPERATING_SYSTEM = 0x0008,
233 PLDM_COMP_MIDDLEWARE = 0x0009,
234 PLDM_COMP_FIRMWARE = 0x000a,
235 PLDM_COMP_BIOS_OR_FCODE = 0x000b,
236 PLDM_COMP_SUPPORT_OR_SERVICEPACK = 0x000c,
237 PLDM_COMP_SOFTWARE_BUNDLE = 0x000d,
238 PLDM_COMP_DOWNSTREAM_DEVICE = 0xffff
239 };
240
241 /** @brief ComponentActivationMethods is the bit position in the bitfield that
242 * provides the capability of the FD for firmware activation. Multiple
243 * activation methods can be supported.
244 */
245 enum pldm_comp_activation_methods {
246 PLDM_ACTIVATION_AUTOMATIC = 0,
247 PLDM_ACTIVATION_SELF_CONTAINED = 1,
248 PLDM_ACTIVATION_MEDIUM_SPECIFIC_RESET = 2,
249 PLDM_ACTIVATION_SYSTEM_REBOOT = 3,
250 PLDM_ACTIVATION_DC_POWER_CYCLE = 4,
251 PLDM_ACTIVATION_AC_POWER_CYCLE = 5,
252 PLDM_SUPPORTS_ACTIVATE_PENDING_IMAGE = 6,
253 PLDM_SUPPORTS_ACTIVATE_PENDING_IMAGE_SET = 7
254 };
255
256 /** @brief ComponentResponse values in the response of PassComponentTable
257 */
258 enum pldm_component_responses {
259 PLDM_CR_COMP_CAN_BE_UPDATED = 0,
260 PLDM_CR_COMP_MAY_BE_UPDATEABLE = 1
261 };
262
263 /** @brief ComponentResponseCode values in the response of PassComponentTable
264 */
265 enum pldm_component_response_codes {
266 PLDM_CRC_COMP_CAN_BE_UPDATED = 0x00,
267 PLDM_CRC_COMP_COMPARISON_STAMP_IDENTICAL = 0x01,
268 PLDM_CRC_COMP_COMPARISON_STAMP_LOWER = 0x02,
269 PLDM_CRC_INVALID_COMP_COMPARISON_STAMP = 0x03,
270 PLDM_CRC_COMP_CONFLICT = 0x04,
271 PLDM_CRC_COMP_PREREQUISITES_NOT_MET = 0x05,
272 PLDM_CRC_COMP_NOT_SUPPORTED = 0x06,
273 PLDM_CRC_COMP_SECURITY_RESTRICTIONS = 0x07,
274 PLDM_CRC_INCOMPLETE_COMP_IMAGE_SET = 0x08,
275 PLDM_CRC_ACTIVE_IMAGE_NOT_UPDATEABLE_SUBSEQUENTLY = 0x09,
276 PLDM_CRC_COMP_VER_STR_IDENTICAL = 0x0a,
277 PLDM_CRC_COMP_VER_STR_LOWER = 0x0b,
278 PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MIN = 0xd0,
279 PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MAX = 0xef
280 };
281
282 /** @brief ComponentCompatibilityResponse values in the response of
283 * UpdateComponent
284 */
285 enum pldm_component_compatibility_responses {
286 PLDM_CCR_COMP_CAN_BE_UPDATED = 0,
287 PLDM_CCR_COMP_CANNOT_BE_UPDATED = 1
288 };
289
290 /** @brief ComponentCompatibilityResponse Code values in the response of
291 * UpdateComponent
292 */
293 enum pldm_component_compatibility_response_codes {
294 PLDM_CCRC_NO_RESPONSE_CODE = 0x00,
295 PLDM_CCRC_COMP_COMPARISON_STAMP_IDENTICAL = 0x01,
296 PLDM_CCRC_COMP_COMPARISON_STAMP_LOWER = 0x02,
297 PLDM_CCRC_INVALID_COMP_COMPARISON_STAMP = 0x03,
298 PLDM_CCRC_COMP_CONFLICT = 0x04,
299 PLDM_CCRC_COMP_PREREQUISITES_NOT_MET = 0x05,
300 PLDM_CCRC_COMP_NOT_SUPPORTED = 0x06,
301 PLDM_CCRC_COMP_SECURITY_RESTRICTIONS = 0x07,
302 PLDM_CCRC_INCOMPLETE_COMP_IMAGE_SET = 0x08,
303 PLDM_CCRC_COMP_INFO_NO_MATCH = 0x09,
304 PLDM_CCRC_COMP_VER_STR_IDENTICAL = 0x0a,
305 PLDM_CCRC_COMP_VER_STR_LOWER = 0x0b,
306 PLDM_CCRC_VENDOR_COMP_RESP_CODE_RANGE_MIN = 0xd0,
307 PLDM_CCRC_VENDOR_COMP_RESP_CODE_RANGE_MAX = 0xef
308 };
309
310 /** @brief Common error codes in TransferComplete, VerifyComplete and
311 * ApplyComplete request
312 */
313 enum pldm_firmware_update_common_error_codes {
314 PLDM_FWUP_TIME_OUT = 0x09,
315 PLDM_FWUP_GENERIC_ERROR = 0x0a
316 };
317
318 /** @brief TransferResult values in the request of TransferComplete
319 */
320 enum pldm_firmware_update_transfer_result_values {
321 PLDM_FWUP_TRANSFER_SUCCESS = 0x00,
322 PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT = 0x02,
323 PLDM_FWUP_TRANSFER_ERROR_VERSION_MISMATCH = 0x02,
324 PLDM_FWUP_FD_ABORTED_TRANSFER = 0x03,
325 PLDM_FWUP_FD_ABORTED_TRANSFER_LOW_POWER_STATE = 0x0b,
326 PLDM_FWUP_FD_ABORTED_TRANSFER_RESET_NEEDED = 0x0c,
327 PLDM_FWUP_FD_ABORTED_TRANSFER_STORAGE_ISSUE = 0x0d,
328 PLDM_FWUP_VENDOR_TRANSFER_RESULT_RANGE_MIN = 0x70,
329 PLDM_FWUP_VENDOR_TRANSFER_RESULT_RANGE_MAX = 0x8f
330 };
331
332 /**@brief VerifyResult values in the request of VerifyComplete
333 */
334 enum pldm_firmware_update_verify_result_values {
335 PLDM_FWUP_VERIFY_SUCCESS = 0x00,
336 PLDM_FWUP_VERIFY_ERROR_VERIFICATION_FAILURE = 0x01,
337 PLDM_FWUP_VERIFY_ERROR_VERSION_MISMATCH = 0x02,
338 PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS = 0x03,
339 PLDM_FWUP_VERIFY_ERROR_IMAGE_INCOMPLETE = 0x04,
340 PLDM_FWUP_VENDOR_VERIFY_RESULT_RANGE_MIN = 0x90,
341 PLDM_FWUP_VENDOR_VERIFY_RESULT_RANGE_MAX = 0xaf
342 };
343
344 /**@brief ApplyResult values in the request of ApplyComplete
345 */
346 enum pldm_firmware_update_apply_result_values {
347 PLDM_FWUP_APPLY_SUCCESS = 0x00,
348 PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD = 0x01,
349 PLDM_FWUP_APPLY_FAILURE_MEMORY_ISSUE = 0x02,
350 PLDM_FWUP_VENDOR_APPLY_RESULT_RANGE_MIN = 0xb0,
351 PLDM_FWUP_VENDOR_APPLY_RESULT_RANGE_MAX = 0xcf
352 };
353
354 /** @brief SelfContainedActivationRequest in the request of ActivateFirmware
355 */
356 enum pldm_self_contained_activation_req {
357 PLDM_NOT_ACTIVATE_SELF_CONTAINED_COMPONENTS = false,
358 PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS = true
359 };
360
361 /** @brief Current state/previous state of the FD or FDP returned in GetStatus
362 * response
363 */
364 enum pldm_firmware_device_states {
365 PLDM_FD_STATE_IDLE = 0,
366 PLDM_FD_STATE_LEARN_COMPONENTS = 1,
367 PLDM_FD_STATE_READY_XFER = 2,
368 PLDM_FD_STATE_DOWNLOAD = 3,
369 PLDM_FD_STATE_VERIFY = 4,
370 PLDM_FD_STATE_APPLY = 5,
371 PLDM_FD_STATE_ACTIVATE = 6
372 };
373
374 /** @brief Firmware device aux state in GetStatus response
375 */
376 enum pldm_get_status_aux_states {
377 PLDM_FD_OPERATION_IN_PROGRESS = 0,
378 PLDM_FD_OPERATION_SUCCESSFUL = 1,
379 PLDM_FD_OPERATION_FAILED = 2,
380 PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER = 3
381 };
382
383 /** @brief Firmware device aux state status in GetStatus response
384 */
385 enum pldm_get_status_aux_state_status_values {
386 PLDM_FD_AUX_STATE_IN_PROGRESS_OR_SUCCESS = 0x00,
387 PLDM_FD_TIMEOUT = 0x09,
388 PLDM_FD_GENERIC_ERROR = 0x0a,
389 PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START = 0x70,
390 PLDM_FD_VENDOR_DEFINED_STATUS_CODE_END = 0xef
391 };
392
393 /** @brief Firmware device reason code in GetStatus response
394 */
395 enum pldm_get_status_reason_code_values {
396 PLDM_FD_INITIALIZATION = 0,
397 PLDM_FD_ACTIVATE_FW = 1,
398 PLDM_FD_CANCEL_UPDATE = 2,
399 PLDM_FD_TIMEOUT_LEARN_COMPONENT = 3,
400 PLDM_FD_TIMEOUT_READY_XFER = 4,
401 PLDM_FD_TIMEOUT_DOWNLOAD = 5,
402 PLDM_FD_TIMEOUT_VERIFY = 6,
403 PLDM_FD_TIMEOUT_APPLY = 7,
404 PLDM_FD_STATUS_VENDOR_DEFINED_MIN = 200,
405 PLDM_FD_STATUS_VENDOR_DEFINED_MAX = 255
406 };
407
408 /** @brief Components functional indicator in CancelUpdate response
409 */
410 enum pldm_firmware_update_non_functioning_component_indication {
411 PLDM_FWUP_COMPONENTS_FUNCTIONING = 0,
412 PLDM_FWUP_COMPONENTS_NOT_FUNCTIONING = 1
413 };
414
415 /** @brief Downstream device update supported in QueryDownstreamDevices response
416 * defined in DSP0267_1.1.0
417 */
418 enum pldm_firmware_update_downstream_device_update_supported {
419 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_NOT_SUPPORTED = 0,
420 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED = 1
421 };
422
423 /* An arbitrary limit, for static storage */
424 #define PLDM_FIRMWARE_MAX_STRING 64
425
426 /** @struct pldm_firmware_string
427 *
428 * A fixed maximum length PLDM firmware string
429 */
430 struct pldm_firmware_string {
431 enum pldm_firmware_update_string_type str_type;
432 uint8_t str_len;
433 uint8_t str_data[PLDM_FIRMWARE_MAX_STRING];
434 };
435
436 /** @struct pldm_firmware_version
437 *
438 * A PLDM component version
439 */
440 struct pldm_firmware_version {
441 uint32_t comparison_stamp;
442 struct pldm_firmware_string str;
443 uint8_t date[PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN];
444 };
445
446 /** @struct pldm_package_header_information
447 *
448 * Structure representing fixed part of package header information
449 */
450 struct pldm_package_header_information {
451 uint8_t uuid[PLDM_FWUP_UUID_LENGTH];
452 uint8_t package_header_format_version;
453 uint16_t package_header_size;
454 uint8_t package_release_date_time[PLDM_TIMESTAMP104_SIZE];
455 uint16_t component_bitmap_bit_length;
456 uint8_t package_version_string_type;
457 uint8_t package_version_string_length;
458 } __attribute__((packed));
459
460 /** @struct pldm_firmware_device_id_record
461 *
462 * Structure representing firmware device ID record
463 */
464 struct pldm_firmware_device_id_record {
465 uint16_t record_length;
466 uint8_t descriptor_count;
467 bitfield32_t device_update_option_flags;
468 uint8_t comp_image_set_version_string_type;
469 uint8_t comp_image_set_version_string_length;
470 uint16_t fw_device_pkg_data_length;
471 } __attribute__((packed));
472
473 /** @struct pldm_descriptor_tlv
474 *
475 * Structure representing descriptor type, length and value
476 */
477 struct pldm_descriptor_tlv {
478 uint16_t descriptor_type;
479 uint16_t descriptor_length;
480 uint8_t descriptor_data[1];
481 } __attribute__((packed));
482
483 /** @struct pldm_vendor_defined_descriptor_title_data
484 *
485 * Structure representing vendor defined descriptor title sections
486 */
487 struct pldm_vendor_defined_descriptor_title_data {
488 uint8_t vendor_defined_descriptor_title_str_type;
489 uint8_t vendor_defined_descriptor_title_str_len;
490 uint8_t vendor_defined_descriptor_title_str[1];
491 } __attribute__((packed));
492
493 /** @struct pldm_component_image_information
494 *
495 * Structure representing fixed part of individual component information in
496 * PLDM firmware update package
497 */
498 struct pldm_component_image_information {
499 uint16_t comp_classification;
500 uint16_t comp_identifier;
501 uint32_t comp_comparison_stamp;
502 bitfield16_t comp_options;
503 bitfield16_t requested_comp_activation_method;
504 uint32_t comp_location_offset;
505 uint32_t comp_size;
506 uint8_t comp_version_string_type;
507 uint8_t comp_version_string_length;
508 } __attribute__((packed));
509
510 /** @struct pldm_query_device_identifiers_resp
511 *
512 * Structure representing query device identifiers response.
513 */
514 struct pldm_query_device_identifiers_resp {
515 uint8_t completion_code;
516 uint32_t device_identifiers_len;
517 uint8_t descriptor_count;
518 } __attribute__((packed));
519
520 /** @struct pldm_get_firmware_parameters_resp
521 *
522 * Structure representing the fixed part of GetFirmwareParameters response
523 */
524 struct pldm_get_firmware_parameters_resp {
525 uint8_t completion_code;
526 bitfield32_t capabilities_during_update;
527 uint16_t comp_count;
528 uint8_t active_comp_image_set_ver_str_type;
529 uint8_t active_comp_image_set_ver_str_len;
530 uint8_t pending_comp_image_set_ver_str_type;
531 uint8_t pending_comp_image_set_ver_str_len;
532 } __attribute__((packed));
533
534 /** @struct pldm_get_firmware_parameters_resp_full
535 *
536 * Structure representing a full GetFirmwareParameters response
537 */
538 struct pldm_get_firmware_parameters_resp_full {
539 uint8_t completion_code;
540 bitfield32_t capabilities_during_update;
541 uint16_t comp_count;
542 struct pldm_firmware_string active_comp_image_set_ver_str;
543 struct pldm_firmware_string pending_comp_image_set_ver_str;
544 };
545
546 /** @struct pldm_query_downstream_devices_resp
547 *
548 * Structure representing response of QueryDownstreamDevices.
549 * The definition can be found Table 15 - QueryDownstreamDevices command format
550 * in DSP0267_1.1.0
551 */
552 struct pldm_query_downstream_devices_resp {
553 uint8_t completion_code;
554 uint8_t downstream_device_update_supported;
555 uint16_t number_of_downstream_devices;
556 uint16_t max_number_of_downstream_devices;
557 bitfield32_t capabilities;
558 };
559
560 /** @struct pldm_component_parameter_entry
561 *
562 * Structure representing component parameter table entry, as wire format.
563 */
564 struct pldm_component_parameter_entry {
565 uint16_t comp_classification;
566 uint16_t comp_identifier;
567 uint8_t comp_classification_index;
568 uint32_t active_comp_comparison_stamp;
569 uint8_t active_comp_ver_str_type;
570 uint8_t active_comp_ver_str_len;
571 uint8_t active_comp_release_date[8];
572 uint32_t pending_comp_comparison_stamp;
573 uint8_t pending_comp_ver_str_type;
574 uint8_t pending_comp_ver_str_len;
575 uint8_t pending_comp_release_date[8];
576 bitfield16_t comp_activation_methods;
577 bitfield32_t capabilities_during_update;
578 } __attribute__((packed));
579
580 /** @struct pldm_component_parameter_entry_full
581 *
582 * Structure representing component parameter table entry.
583 * This is non-packed (contrast with struct pldm_component_parameter_entry),
584 * with version strings included.
585 */
586 struct pldm_component_parameter_entry_full {
587 uint16_t comp_classification;
588 uint16_t comp_identifier;
589 uint8_t comp_classification_index;
590
591 struct pldm_firmware_version active_ver;
592 struct pldm_firmware_version pending_ver;
593
594 bitfield16_t comp_activation_methods;
595 bitfield32_t capabilities_during_update;
596 };
597
598 /** @struct pldm_query_downstream_identifiers_req
599 *
600 * Structure for QueryDownstreamIdentifiers request defined in Table 16 -
601 * QueryDownstreamIdentifiers command format in DSP0267_1.1.0
602 */
603 struct pldm_query_downstream_identifiers_req {
604 uint32_t data_transfer_handle;
605 uint8_t transfer_operation_flag;
606 };
607
608 /** @struct pldm_query_downstream_identifiers_resp
609 *
610 * Structure representing the fixed part of QueryDownstreamIdentifiers response
611 * defined in Table 16 - QueryDownstreamIdentifiers command format, and
612 * Table 17 - QueryDownstreamIdentifiers response definition in DSP0267_1.1.0.
613 *
614 * Squash the two tables into one since the definition of
615 * Table 17 is `Portion of QueryDownstreamIdentifiers response`
616 */
617 struct pldm_query_downstream_identifiers_resp {
618 uint8_t completion_code;
619 uint32_t next_data_transfer_handle;
620 uint8_t transfer_flag;
621 uint32_t downstream_devices_length;
622 uint16_t number_of_downstream_devices;
623 };
624
625 /** @struct pldm_downstream_device
626 *
627 * Structure representing downstream device information defined in
628 * Table 18 - DownstreamDevice definition in DSP0267_1.1.0
629 */
630 struct pldm_downstream_device {
631 uint16_t downstream_device_index;
632 uint8_t downstream_descriptor_count;
633 };
634 #define PLDM_DOWNSTREAM_DEVICE_BYTES 3
635
636 struct pldm_downstream_device_iter {
637 struct variable_field field;
638 size_t devs;
639 };
640
641 LIBPLDM_ITERATOR
pldm_downstream_device_iter_end(const struct pldm_downstream_device_iter * iter)642 bool pldm_downstream_device_iter_end(
643 const struct pldm_downstream_device_iter *iter)
644 {
645 return !iter->devs;
646 }
647
648 LIBPLDM_ITERATOR
pldm_downstream_device_iter_next(struct pldm_downstream_device_iter * iter)649 bool pldm_downstream_device_iter_next(struct pldm_downstream_device_iter *iter)
650 {
651 if (!iter->devs) {
652 return false;
653 }
654
655 iter->devs--;
656 return true;
657 }
658
659 int decode_pldm_downstream_device_from_iter(
660 struct pldm_downstream_device_iter *iter,
661 struct pldm_downstream_device *dev);
662
663 /** @brief Iterate downstream devices in QueryDownstreamIdentifiers response
664 *
665 * @param devs The @ref "struct pldm_downstream_device_iter" lvalue used as the
666 * out-value from the corresponding call to @ref
667 * decode_query_downstream_identifiers_resp
668 * @param dev The @ref "struct pldm_downstream_device" lvalue into which the
669 * next device instance should be decoded.
670 * @param rc An lvalue of type int into which the return code from the decoding
671 * will be placed.
672 *
673 * Example use of the macro is as follows:
674 *
675 * @code
676 * struct pldm_query_downstream_identifiers_resp resp;
677 * struct pldm_downstream_device_iter devs;
678 * struct pldm_downstream_device dev;
679 * int rc;
680 *
681 * rc = decode_query_downstream_identifiers_resp(..., &resp, &devs);
682 * if (rc) {
683 * // Handle any error from decoding fixed-portion of response
684 * }
685 *
686 * foreach_pldm_downstream_device(devs, dev, rc) {
687 * // Do something with each decoded device placed in `dev`
688 * }
689 *
690 * if (rc) {
691 * // Handle any decoding error while iterating variable-length set of
692 * // devices
693 * }
694 * @endcode
695 */
696 #define foreach_pldm_downstream_device(devs, dev, rc) \
697 for ((rc) = 0; (!pldm_downstream_device_iter_end(&(devs)) && \
698 !((rc) = decode_pldm_downstream_device_from_iter( \
699 &(devs), &(dev)))); \
700 pldm_downstream_device_iter_next(&(devs)))
701
702 /** @struct pldm_descriptor
703 *
704 * Structure representing a type-length-value descriptor as defined in Table 7 -
705 * Descriptor Definition.
706 *
707 * Member values are always host-endian. When decoding messages, the
708 * descriptor_data member points into the message buffer.
709 */
710 struct pldm_descriptor {
711 uint16_t descriptor_type;
712 uint16_t descriptor_length;
713 const void *descriptor_data;
714 };
715
716 struct pldm_descriptor_iter {
717 struct variable_field *field;
718 size_t count;
719 };
720
721 LIBPLDM_ITERATOR
pldm_downstream_device_descriptor_iter_init(struct pldm_downstream_device_iter * devs,const struct pldm_downstream_device * dev)722 struct pldm_descriptor_iter pldm_downstream_device_descriptor_iter_init(
723 struct pldm_downstream_device_iter *devs,
724 const struct pldm_downstream_device *dev)
725 {
726 struct pldm_descriptor_iter iter = { &devs->field,
727 dev->downstream_descriptor_count };
728 return iter;
729 }
730
731 LIBPLDM_ITERATOR
pldm_descriptor_iter_end(const struct pldm_descriptor_iter * iter)732 bool pldm_descriptor_iter_end(const struct pldm_descriptor_iter *iter)
733 {
734 return !iter->count;
735 }
736
737 LIBPLDM_ITERATOR
pldm_descriptor_iter_next(struct pldm_descriptor_iter * iter)738 bool pldm_descriptor_iter_next(struct pldm_descriptor_iter *iter)
739 {
740 if (!iter->count) {
741 return false;
742 }
743
744 iter->count--;
745 return true;
746 }
747
748 int decode_pldm_descriptor_from_iter(struct pldm_descriptor_iter *iter,
749 struct pldm_descriptor *desc);
750
751 /** @brief Iterate a downstream device's descriptors in a
752 * QueryDownstreamIdentifiers response
753 *
754 * @param devs The @ref "struct pldm_downstream_device_iter" lvalue used as the
755 * out-value from the corresponding call to @ref
756 * decode_query_downstream_identifiers_resp
757 * @param dev The @ref "struct pldm_downstream_device" lvalue over whose
758 * descriptors to iterate
759 * @param desc The @ref "struct pldm_descriptor" lvalue into which the next
760 * descriptor instance should be decoded
761 * @param rc An lvalue of type int into which the return code from the decoding
762 * will be placed
763 *
764 * Example use of the macro is as follows:
765 *
766 * @code
767 * struct pldm_query_downstream_identifiers_resp resp;
768 * struct pldm_downstream_device_iter devs;
769 * struct pldm_downstream_device dev;
770 * int rc;
771 *
772 * rc = decode_query_downstream_identifiers_resp(..., &resp, &devs);
773 * if (rc) {
774 * // Handle any error from decoding fixed-portion of response
775 * }
776 *
777 * foreach_pldm_downstream_device(devs, dev, rc) {
778 * struct pldm_descriptor desc;
779 *
780 * foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc) {
781 * // Do something with each decoded descriptor placed in `desc`
782 * }
783 *
784 * if (rc) {
785 * // Handle any decoding error while iterating on the variable-length
786 * // set of descriptors
787 * }
788 * }
789 *
790 * if (rc) {
791 * // Handle any decoding error while iterating variable-length set of
792 * // devices
793 * }
794 * @endcode
795 */
796 #define foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc) \
797 for (struct pldm_descriptor_iter desc##_iter = \
798 ((rc) = 0, pldm_downstream_device_descriptor_iter_init( \
799 &(devs), &(dev))); \
800 (!pldm_descriptor_iter_end(&(desc##_iter)) && \
801 !((rc) = decode_pldm_descriptor_from_iter(&(desc##_iter), \
802 &(desc)))); \
803 pldm_descriptor_iter_next(&(desc##_iter)))
804
805 /** @struct pldm_query_downstream_firmware_param_req
806 *
807 * Structure representing QueryDownstreamFirmwareParameters request
808 */
809 struct pldm_get_downstream_firmware_parameters_req {
810 uint32_t data_transfer_handle;
811 uint8_t transfer_operation_flag;
812 };
813
814 /** @struct pldm_get_downstream_firmware_parameters_resp
815 *
816 * Structure representing the fixed part of QueryDownstreamFirmwareParameters
817 * response in Table 19 - GetDownstreamFirmwareParameters command format, and
818 * Table 20 - QueryDownstreamFirmwareParameters response definition in
819 * DSP0267_1.1.0.
820 *
821 * Squash the two tables into one since the definition of Table 20 is `Portion
822 * of GetDownstreamFirmwareParameters response`
823 */
824 struct pldm_get_downstream_firmware_parameters_resp {
825 uint8_t completion_code;
826 uint32_t next_data_transfer_handle;
827 uint8_t transfer_flag;
828 bitfield32_t fdp_capabilities_during_update;
829 uint16_t downstream_device_count;
830 };
831
832 /** @struct pldm_downstream_device_parameters_entry
833 *
834 * Structure representing downstream device parameter table entry defined in
835 * Table 21 - DownstreamDeviceParameterTable in DSP0267_1.1.0
836 *
837 * Clients should not allocate memory for this struct to decode the response,
838 * use `pldm_downstream_device_parameter_entry_versions` instead to make sure
839 * that the active and pending component version strings are copied from the
840 * message buffer.
841 */
842 struct pldm_downstream_device_parameters_entry {
843 uint16_t downstream_device_index;
844 uint32_t active_comp_comparison_stamp;
845 uint8_t active_comp_ver_str_type;
846 uint8_t active_comp_ver_str_len;
847 /* Append 1 bytes for null termination so that it can be used as a
848 * Null-terminated string.
849 */
850 char active_comp_release_date[PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN + 1];
851 uint32_t pending_comp_comparison_stamp;
852 uint8_t pending_comp_ver_str_type;
853 uint8_t pending_comp_ver_str_len;
854 /* Append 1 bytes for null termination so that it can be used as a
855 * Null-terminated string.
856 */
857 char pending_comp_release_date[PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN + 1];
858 bitfield16_t comp_activation_methods;
859 bitfield32_t capabilities_during_update;
860 const void *active_comp_ver_str;
861 const void *pending_comp_ver_str;
862 };
863
864 /** @struct pldm_request_update_req
865 *
866 * Structure representing fixed part of Request Update request, as wire format.
867 */
868 struct pldm_request_update_req {
869 uint32_t max_transfer_size;
870 uint16_t num_of_comp;
871 uint8_t max_outstanding_transfer_req;
872 uint16_t pkg_data_len;
873 uint8_t comp_image_set_ver_str_type;
874 uint8_t comp_image_set_ver_str_len;
875 } __attribute__((packed));
876
877 /** @struct pldm_request_update_req_full
878 *
879 * Structure representing fixed part of Request Update request, including
880 * version string. This is unpacked (contrast to struct pldm_request_update_req).
881 */
882 struct pldm_request_update_req_full {
883 uint32_t max_transfer_size;
884 uint16_t num_of_comp;
885 uint8_t max_outstanding_transfer_req;
886 uint16_t pkg_data_len;
887
888 struct pldm_firmware_string image_set_ver;
889 };
890
891 /** @struct pldm_request_update_resp
892 *
893 * Structure representing Request Update response
894 */
895 struct pldm_request_update_resp {
896 uint8_t completion_code;
897 uint16_t fd_meta_data_len;
898 uint8_t fd_will_send_pkg_data;
899 } __attribute__((packed));
900
901 /** @struct pldm_request_downstream_dev_update_req
902 *
903 * Structure representing Request Downstream Device Update request
904 */
905 struct pldm_request_downstream_device_update_req {
906 uint32_t maximum_downstream_device_transfer_size;
907 uint8_t maximum_outstanding_transfer_requests;
908 uint16_t downstream_device_package_data_length;
909 };
910 #define PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES 7
911
912 /** @struct pldm_request_downstream_dev_update_resp
913 *
914 * Structure representing Request Downstream Device Update response
915 */
916 struct pldm_request_downstream_device_update_resp {
917 uint8_t completion_code;
918 uint16_t downstream_device_meta_data_length;
919 uint8_t downstream_device_will_send_get_package_data;
920 uint16_t get_package_data_maximum_transfer_size;
921 };
922 #define PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES 6
923
924 /** @struct pldm_pass_component_table_req
925 *
926 * Structure representing PassComponentTable request, wire format.
927 * Version string data is not included.
928 * Prefer pldm_pass_component_table_req_full for new uses.
929 */
930 struct pldm_pass_component_table_req {
931 uint8_t transfer_flag;
932 uint16_t comp_classification;
933 uint16_t comp_identifier;
934 uint8_t comp_classification_index;
935 uint32_t comp_comparison_stamp;
936 uint8_t comp_ver_str_type;
937 uint8_t comp_ver_str_len;
938 } __attribute__((packed));
939
940 /** @struct pldm_pass_component_table_req_full
941 *
942 * Structure representing PassComponentTable request, including
943 * version string storage.
944 */
945 struct pldm_pass_component_table_req_full {
946 uint8_t transfer_flag;
947 uint16_t comp_classification;
948 uint16_t comp_identifier;
949 uint8_t comp_classification_index;
950 uint32_t comp_comparison_stamp;
951 struct pldm_firmware_string version;
952 };
953
954 /** @struct pldm_pass_component_table_resp
955 *
956 * Structure representing PassComponentTable response
957 */
958 struct pldm_pass_component_table_resp {
959 uint8_t completion_code;
960 uint8_t comp_resp;
961 uint8_t comp_resp_code;
962 } __attribute__((packed));
963
964 /** @struct pldm_update_component_req
965 *
966 * Structure representing UpdateComponent request, wire format.
967 * Version string data is not included.
968 * Prefer pldm_update_component_req_full for new uses.
969 */
970 struct pldm_update_component_req {
971 uint16_t comp_classification;
972 uint16_t comp_identifier;
973 uint8_t comp_classification_index;
974 uint32_t comp_comparison_stamp;
975 uint32_t comp_image_size;
976 bitfield32_t update_option_flags;
977 uint8_t comp_ver_str_type;
978 uint8_t comp_ver_str_len;
979 } __attribute__((packed));
980
981 /** @struct pldm_update_component_req_full
982 *
983 * Structure representing UpdateComponent request, including
984 * version string storage.
985 */
986 struct pldm_update_component_req_full {
987 uint16_t comp_classification;
988 uint16_t comp_identifier;
989 uint8_t comp_classification_index;
990
991 uint32_t comp_comparison_stamp;
992 struct pldm_firmware_string version;
993
994 uint32_t comp_image_size;
995 bitfield32_t update_option_flags;
996 };
997
998 /** @struct pldm_update_component_resp
999 *
1000 * Structure representing UpdateComponent response
1001 */
1002 struct pldm_update_component_resp {
1003 uint8_t completion_code;
1004 uint8_t comp_compatibility_resp;
1005 uint8_t comp_compatibility_resp_code;
1006 bitfield32_t update_option_flags_enabled;
1007 uint16_t time_before_req_fw_data;
1008 } __attribute__((packed));
1009
1010 /** @struct pldm_request_firmware_data_req
1011 *
1012 * Structure representing RequestFirmwareData request.
1013 */
1014 struct pldm_request_firmware_data_req {
1015 uint32_t offset;
1016 uint32_t length;
1017 } __attribute__((packed));
1018
1019 /** @struct pldm_apply_complete_req
1020 *
1021 * Structure representing ApplyComplete request.
1022 */
1023 struct pldm_apply_complete_req {
1024 uint8_t apply_result;
1025 bitfield16_t comp_activation_methods_modification;
1026 } __attribute__((packed));
1027
1028 /** @struct pldm_activate_firmware_req
1029 *
1030 * Structure representing ActivateFirmware request
1031 */
1032 struct pldm_activate_firmware_req {
1033 bool8_t self_contained_activation_req;
1034 } __attribute__((packed));
1035
1036 /** @struct activate_firmware_resp
1037 *
1038 * Structure representing Activate Firmware response
1039 */
1040 struct pldm_activate_firmware_resp {
1041 uint8_t completion_code;
1042 uint16_t estimated_time_activation;
1043 } __attribute__((packed));
1044
1045 /** @struct pldm_get_status_resp
1046 *
1047 * Structure representing GetStatus response.
1048 */
1049 struct pldm_get_status_resp {
1050 uint8_t completion_code;
1051 uint8_t current_state;
1052 uint8_t previous_state;
1053 uint8_t aux_state;
1054 uint8_t aux_state_status;
1055 uint8_t progress_percent;
1056 uint8_t reason_code;
1057 bitfield32_t update_option_flags_enabled;
1058 } __attribute__((packed));
1059
1060 /** @struct pldm_cancel_update_resp
1061 *
1062 * Structure representing CancelUpdate response.
1063 */
1064 struct pldm_cancel_update_resp {
1065 uint8_t completion_code;
1066 bool8_t non_functioning_component_indication;
1067 uint64_t non_functioning_component_bitmap;
1068 } __attribute__((packed));
1069
1070 /** @brief Decode the PLDM package header information
1071 *
1072 * @param[in] data - pointer to package header information
1073 * @param[in] length - available length in the firmware update package
1074 * @param[out] package_header_info - pointer to fixed part of PLDM package
1075 * header information
1076 * @param[out] package_version_str - pointer to package version string
1077 *
1078 * @return pldm_completion_codes
1079 */
1080 int decode_pldm_package_header_info(
1081 const uint8_t *data, size_t length,
1082 struct pldm_package_header_information *package_header_info,
1083 struct variable_field *package_version_str);
1084
1085 /** @brief Decode individual firmware device ID record
1086 *
1087 * @param[in] data - pointer to firmware device ID record
1088 * @param[in] length - available length in the firmware update package
1089 * @param[in] component_bitmap_bit_length - ComponentBitmapBitLengthfield
1090 * parsed from the package header info
1091 * @param[out] fw_device_id_record - pointer to fixed part of firmware device
1092 * id record
1093 * @param[out] applicable_components - pointer to ApplicableComponents
1094 * @param[out] comp_image_set_version_str - pointer to
1095 * ComponentImageSetVersionString
1096 * @param[out] record_descriptors - pointer to RecordDescriptors
1097 * @param[out] fw_device_pkg_data - pointer to FirmwareDevicePackageData
1098 *
1099 * @return pldm_completion_codes
1100 */
1101 int decode_firmware_device_id_record(
1102 const uint8_t *data, size_t length,
1103 uint16_t component_bitmap_bit_length,
1104 struct pldm_firmware_device_id_record *fw_device_id_record,
1105 struct variable_field *applicable_components,
1106 struct variable_field *comp_image_set_version_str,
1107 struct variable_field *record_descriptors,
1108 struct variable_field *fw_device_pkg_data);
1109
1110 /** @brief Decode the record descriptor entries in the firmware update package
1111 * and the Descriptors in the QueryDeviceIDentifiers command
1112 *
1113 * @param[in] data - pointer to descriptor entry
1114 * @param[in] length - remaining length of the descriptor data
1115 * @param[out] descriptor_type - pointer to descriptor type
1116 * @param[out] descriptor_data - pointer to descriptor data
1117 *
1118 * @return pldm_completion_codes
1119 */
1120 int decode_descriptor_type_length_value(const uint8_t *data, size_t length,
1121 uint16_t *descriptor_type,
1122 struct variable_field *descriptor_data);
1123
1124 /** @brief Decode the vendor defined descriptor value
1125 *
1126 * @param[in] data - pointer to vendor defined descriptor value
1127 * @param[in] length - length of the vendor defined descriptor value
1128 * @param[out] descriptor_title_str_type - pointer to vendor defined descriptor
1129 * title string type
1130 * @param[out] descriptor_title_str - pointer to vendor defined descriptor
1131 * title string
1132 * @param[out] descriptor_data - pointer to vendor defined descriptor data
1133 *
1134 * @return pldm_completion_codes
1135 */
1136 int decode_vendor_defined_descriptor_value(
1137 const uint8_t *data, size_t length, uint8_t *descriptor_title_str_type,
1138 struct variable_field *descriptor_title_str,
1139 struct variable_field *descriptor_data);
1140
1141 /** @brief Decode individual component image information
1142 *
1143 * @param[in] data - pointer to component image information
1144 * @param[in] length - available length in the firmware update package
1145 * @param[out] pldm_comp_image_info - pointer to fixed part of component image
1146 * information
1147 * @param[out] comp_version_str - pointer to component version string
1148 *
1149 * @return pldm_completion_codes
1150 */
1151 int decode_pldm_comp_image_info(
1152 const uint8_t *data, size_t length,
1153 struct pldm_component_image_information *pldm_comp_image_info,
1154 struct variable_field *comp_version_str);
1155
1156 /** @brief Create a PLDM request message for QueryDeviceIdentifiers
1157 *
1158 * @param[in] instance_id - Message's instance id
1159 * @param[in] payload_length - Length of the request message payload
1160 * @param[in,out] msg - Message will be written to this
1161 *
1162 * @return pldm_completion_codes
1163 *
1164 * @note Caller is responsible for memory alloc and dealloc of param
1165 * 'msg.payload'
1166 */
1167 int encode_query_device_identifiers_req(uint8_t instance_id,
1168 size_t payload_length,
1169 struct pldm_msg *msg);
1170
1171 /** @brief Create a PLDM response message for QueryDeviceIdentifiers
1172 *
1173 * @param[in] instance_id - Message's instance id
1174 * @param[in] descriptor_count - Number of descriptors
1175 * @param[in] descriptor - Array of descriptors
1176 * @param[in,out] msg - Message will be written to this
1177 * @param[in,out] payload_length - Size of the response message payload, updated
1178 * with used length.
1179 *
1180 * @return 0 on success, a negative errno value on failure.
1181 *
1182 * @note Caller is responsible for memory alloc and dealloc of param
1183 * 'msg.payload'
1184 */
1185 int encode_query_device_identifiers_resp(
1186 uint8_t instance_id, uint8_t descriptor_count,
1187 const struct pldm_descriptor *descriptors, struct pldm_msg *msg,
1188 size_t *payload_length);
1189
1190 /** @brief Decode QueryDeviceIdentifiers response message
1191 *
1192 * @param[in] msg - Response message
1193 * @param[in] payload_length - Length of response message payload
1194 * @param[out] completion_code - Pointer to response msg's PLDM completion code
1195 * @param[out] device_identifiers_len - Pointer to device identifiers length
1196 * @param[out] descriptor_count - Pointer to descriptor count
1197 * @param[out] descriptor_data - Pointer to descriptor data
1198 *
1199 * @return pldm_completion_codes
1200 */
1201 int decode_query_device_identifiers_resp(const struct pldm_msg *msg,
1202 size_t payload_length,
1203 uint8_t *completion_code,
1204 uint32_t *device_identifiers_len,
1205 uint8_t *descriptor_count,
1206 uint8_t **descriptor_data);
1207
1208 /** @brief Create a PLDM request message for GetFirmwareParameters
1209 *
1210 * @param[in] instance_id - Message's instance id
1211 * @param[in] payload_length - Length of the request message payload
1212 * @param[in,out] msg - Message will be written to this
1213 *
1214 * @return pldm_completion_codes
1215 *
1216 * @note Caller is responsible for memory alloc and dealloc of param
1217 * 'msg.payload'
1218 */
1219 int encode_get_firmware_parameters_req(uint8_t instance_id,
1220 size_t payload_length,
1221 struct pldm_msg *msg);
1222
1223 /** @brief Decode GetFirmwareParameters response
1224 *
1225 * @param[in] msg - Response message
1226 * @param[in] payload_length - Length of response message payload
1227 * @param[out] resp_data - Pointer to get firmware parameters response
1228 * @param[out] active_comp_image_set_ver_str - Pointer to active component
1229 * image set version string
1230 * @param[out] pending_comp_image_set_ver_str - Pointer to pending component
1231 * image set version string
1232 * @param[out] comp_parameter_table - Pointer to component parameter table
1233 *
1234 * @return pldm_completion_codes
1235 */
1236 int decode_get_firmware_parameters_resp(
1237 const struct pldm_msg *msg, size_t payload_length,
1238 struct pldm_get_firmware_parameters_resp *resp_data,
1239 struct variable_field *active_comp_image_set_ver_str,
1240 struct variable_field *pending_comp_image_set_ver_str,
1241 struct variable_field *comp_parameter_table);
1242
1243 /** @brief Decode component entries in the component parameter table which is
1244 * part of the response of GetFirmwareParameters command
1245 *
1246 * @param[in] data - Component entry
1247 * @param[in] length - Length of component entry
1248 * @param[out] component_data - Pointer to component parameter table
1249 * @param[out] active_comp_ver_str - Pointer to active component version string
1250 * @param[out] pending_comp_ver_str - Pointer to pending component version
1251 * string
1252 *
1253 * @return pldm_completion_codes
1254 */
1255 int decode_get_firmware_parameters_resp_comp_entry(
1256 const uint8_t *data, size_t length,
1257 struct pldm_component_parameter_entry *component_data,
1258 struct variable_field *active_comp_ver_str,
1259 struct variable_field *pending_comp_ver_str);
1260
1261 /** @brief Encode a GetFirmwareParameters response
1262 *
1263 * @param[in] instance_id - Message's instance id
1264 * @param[in] resp_data - Parameter data
1265 * @param[in,out] msg - Message will be written to this
1266 * @param[in,out] payload_length - Size of the response message payload, updated
1267 * with used length.
1268 *
1269 * @return 0 on success, a negative errno value on failure.
1270 */
1271 int encode_get_firmware_parameters_resp(
1272 uint8_t instance_id,
1273 const struct pldm_get_firmware_parameters_resp_full *resp_data,
1274 struct pldm_msg *msg, size_t *payload_length);
1275
1276 /** @brief Encode a ComponentParameterTable entry
1277 *
1278 * @param[in] comp - Component entry
1279 * @param[in,out] payload - Message will be written to this
1280 * @param[in,out] payload_length - Size of payload, updated
1281 * with used length.
1282 *
1283 * @return 0 on success, a negative errno value on failure.
1284 */
1285 int encode_get_firmware_parameters_resp_comp_entry(
1286 const struct pldm_component_parameter_entry_full *comp,
1287 uint8_t *payload, size_t *payload_length);
1288
1289 /** @brief Create a PLDM request message for QueryDownstreamDevices
1290 *
1291 * @param[in] instance_id - Message's instance id
1292 * @param[out] msg - Message will be written to this
1293 *
1294 * @return 0 on success, otherwise -EINVAL if the input parameters' memory
1295 * are not allocated, -EOVERFLOW if the payload length is not enough
1296 * to encode the message, -EBADMSG if the message is not valid.
1297 *
1298 * @note Caller is responsible for memory alloc and dealloc of param
1299 * 'msg.payload'
1300 */
1301 int encode_query_downstream_devices_req(uint8_t instance_id,
1302 struct pldm_msg *msg);
1303
1304 /**
1305 * @brief Decodes the response message for Querying Downstream Devices.
1306 *
1307 * @param[in] msg The PLDM message to decode.
1308 * @param[in] payload_length The length of the message payload.
1309 * @param[out] resp_data Pointer to the structure to store the decoded response data.
1310 * @return 0 on success, otherwise -EINVAL if the input parameters' memory
1311 * are not allocated, -EOVERFLOW if the payload length is not enough
1312 * to decode the message, -EBADMSG if the message is not valid.
1313 *
1314 * @note Caller is responsible for memory alloc and dealloc of param
1315 * 'msg.payload'
1316 */
1317 int decode_query_downstream_devices_resp(
1318 const struct pldm_msg *msg, size_t payload_length,
1319 struct pldm_query_downstream_devices_resp *resp_data);
1320
1321 /**
1322 * @brief Encodes a request message for Query Downstream Identifiers.
1323 *
1324 * @param[in] instance_id The instance ID of the PLDM entity.
1325 * @param[in] data_transfer_handle The handle for the data transfer.
1326 * @param[in] transfer_operation_flag The flag indicating the transfer operation.
1327 * @param[out] msg Pointer to the PLDM message structure to store the encoded message.
1328 * @param[in] payload_length The length of the payload.
1329 * @return 0 on success, otherwise -EINVAL if the input parameters' memory
1330 * are not allocated, -EOVERFLOW if the payload length is not enough
1331 * to encode the message, -EBADMSG if the message is not valid.
1332 *
1333 * @note Caller is responsible for memory alloc and dealloc of param
1334 * 'msg.payload'
1335 */
1336 int encode_query_downstream_identifiers_req(
1337 uint8_t instance_id,
1338 const struct pldm_query_downstream_identifiers_req *params_req,
1339 struct pldm_msg *msg, size_t payload_length);
1340
1341 /**
1342 * @brief Decodes the response message for Querying Downstream Identifiers.
1343 * @param[in] msg The PLDM message to decode.
1344 * @param[in] payload_length The length of the message payload.
1345 * @param[out] resp_data Pointer to the decoded response data.
1346 * @param[out] iter Pointer to the downstream device iterator structure.
1347 * @return 0 on success, otherwise -EINVAL if the input parameters' memory
1348 * are not allocated, -EOVERFLOW if the payload length is not enough
1349 * to decode the message, -EBADMSG if the message is not valid.
1350 *
1351 * @note Caller is responsible for memory alloc and dealloc of pointer params
1352 */
1353 int decode_query_downstream_identifiers_resp(
1354 const struct pldm_msg *msg, size_t payload_length,
1355 struct pldm_query_downstream_identifiers_resp *resp_data,
1356 struct pldm_downstream_device_iter *iter);
1357
1358 /**
1359 * @brief Encodes request message for Get Downstream Firmware Parameters.
1360 *
1361 * @param[in] instance_id - The instance ID of the PLDM entity.
1362 * @param[in] data_transfer_handle - The handle for the data transfer.
1363 * @param[in] transfer_operation_flag - The flag indicating the transfer operation.
1364 * @param[in,out] msg - A pointer to the PLDM message structure to store the encoded message.
1365 * @param[in] payload_length - The length of the payload.
1366 *
1367 * @return 0 on success, otherwise -EINVAL if the input parameters' memory
1368 * are not allocated, -EOVERFLOW if the payload length is not enough
1369 * to encode the message, -EBADMSG if the message is not valid.
1370 *
1371 * @note Caller is responsible for memory alloc and dealloc of param
1372 * 'msg.payload'
1373 */
1374 int encode_get_downstream_firmware_parameters_req(
1375 uint8_t instance_id,
1376 const struct pldm_get_downstream_firmware_parameters_req *params_req,
1377 struct pldm_msg *msg, size_t payload_length);
1378
1379 struct pldm_downstream_device_parameters_iter {
1380 struct variable_field field;
1381 size_t entries;
1382 };
1383
1384 /**
1385 * @brief Decode response message for Get Downstream Firmware Parameters
1386 *
1387 * @param[in] msg - The PLDM message to decode
1388 * @param[in] payload_length - The length of the message payload
1389 * @param[out] resp_data - Pointer to the structure to store the decoded response data
1390 * @param[out] downstream_device_param_table - Pointer to the variable field structure
1391 * to store the decoded downstream device
1392 * parameter table
1393 * @return 0 on success, otherwise -EINVAL if the input parameters' memory
1394 * are not allocated, -EOVERFLOW if the payload length is not enough
1395 * to decode the message, -EBADMSG if the message is not valid.
1396 *
1397 * @note Caller is responsible for memory alloc and dealloc of param
1398 * 'resp_data' and 'downstream_device_param_table'
1399 */
1400 int decode_get_downstream_firmware_parameters_resp(
1401 const struct pldm_msg *msg, size_t payload_length,
1402 struct pldm_get_downstream_firmware_parameters_resp *resp_data,
1403 struct pldm_downstream_device_parameters_iter *iter);
1404
1405 /**
1406 * @brief Decode the next downstream device parameter table entry
1407 *
1408 * @param[in,out] data - A variable field covering the table entries in the
1409 * response message data. @p data is updated to point to
1410 * the remaining entries once the current entry has been
1411 * decoded.
1412
1413 * @param[out] entry - The struct object into which the current table entry will
1414 * be decoded
1415
1416 * @param[out] versions - A variable field covering the active and
1417 * pending component version strings in the
1418 * response message data. The component version
1419 * strings can be decoded into @p entry using
1420 * decode_downstream_device_parameter_table_entry_versions()
1421 *
1422 * @return 0 on success, otherwise -EINVAL if the input parameters' memory
1423 * are not allocated, -EOVERFLOW if the payload length is not enough
1424 * to decode the entry.
1425 *
1426 * @note Caller is responsible for memory alloc and dealloc of param
1427 * 'entry', 'active_comp_ver_str' and 'pending_comp_ver_str'
1428 */
1429 int decode_pldm_downstream_device_parameters_entry_from_iter(
1430 struct pldm_downstream_device_parameters_iter *iter,
1431 struct pldm_downstream_device_parameters_entry *entry);
1432
1433 LIBPLDM_ITERATOR
pldm_downstream_device_parameters_iter_end(const struct pldm_downstream_device_parameters_iter * iter)1434 bool pldm_downstream_device_parameters_iter_end(
1435 const struct pldm_downstream_device_parameters_iter *iter)
1436 {
1437 return !iter->entries;
1438 }
1439
1440 LIBPLDM_ITERATOR
pldm_downstream_device_parameters_iter_next(struct pldm_downstream_device_parameters_iter * iter)1441 bool pldm_downstream_device_parameters_iter_next(
1442 struct pldm_downstream_device_parameters_iter *iter)
1443 {
1444 if (!iter->entries) {
1445 return false;
1446 }
1447
1448 iter->entries--;
1449 return true;
1450 }
1451
1452 /** @brief Iterator downstream device parameter entries in Get Downstream
1453 * Firmware Parameters response
1454 *
1455 * @param params The @ref "struct pldm_downstream_device_parameters_iter" lvalue
1456 * used as the out-value from the corresponding call to @ref
1457 * decode_get_downstream_firmware_parameters_resp
1458 * @param entry The @ref "struct pldm_downstream_device_parameters_entry" lvalue
1459 * into which the next parameter table entry should be decoded
1460 * @param rc An lvalue of type int into which the return code from the decoding
1461 * will be placed
1462 *
1463 * Example use of the macro is as follows:
1464 *
1465 * @code
1466 * struct pldm_get_downstream_firmware_parameters_resp resp;
1467 * struct pldm_downstream_device_parameters_iter params;
1468 * struct pldm_downstream_device_parameters_entry entry;
1469 * int rc;
1470 *
1471 * rc = decode_get_downstream_firmware_parameters_resp(..., &resp, ¶ms);
1472 * if (rc) {
1473 * // Handle any error from decoding the fixed-portion of response
1474 * }
1475 *
1476 * foreach_pldm_downstream_device_parameters_entry(params, entry, rc) {
1477 * // Do something with the decoded entry
1478 * }
1479 *
1480 * if (rc) {
1481 * // Handle any decoding error while iterating the variable-length set of
1482 * //parameter entries
1483 * }
1484 * @endcode
1485 */
1486 #define foreach_pldm_downstream_device_parameters_entry(params, entry, rc) \
1487 for ((rc) = 0; \
1488 (!pldm_downstream_device_parameters_iter_end(&(params)) && \
1489 !((rc) = decode_pldm_downstream_device_parameters_entry_from_iter( \
1490 &(params), &(entry)))); \
1491 pldm_downstream_device_parameters_iter_next(&(params)))
1492
1493 /** @brief Create PLDM request message for RequestUpdate
1494 *
1495 * @param[in] instance_id - Message's instance id
1496 * @param[in] max_transfer_size - Maximum size of the variable payload allowed
1497 * to be requested via RequestFirmwareData
1498 * command
1499 * @param[in] num_of_comp - Total number of components that will be passed to
1500 * the FD during the update
1501 * @param[in] max_outstanding_transfer_req - Total number of outstanding
1502 * RequestFirmwareData
1503 * commands that can be sent by the FD
1504 * @param[in] pkg_data_len - Value of the FirmwareDevicePackageDataLength field
1505 * present in firmware package header
1506 * @param[in] comp_image_set_ver_str_type - StringType of
1507 * ComponentImageSetVersionString
1508 * @param[in] comp_image_set_ver_str_len - The length of the
1509 * ComponentImageSetVersionString
1510 * @param[in] comp_img_set_ver_str - Component Image Set version information
1511 * @param[in,out] msg - Message will be written to this
1512 * @param[in] payload_length - Length of request message payload
1513 *
1514 * @return pldm_completion_codes
1515 *
1516 * @note Caller is responsible for memory alloc and dealloc of param
1517 * 'msg.payload'
1518 */
1519 int encode_request_update_req(uint8_t instance_id, uint32_t max_transfer_size,
1520 uint16_t num_of_comp,
1521 uint8_t max_outstanding_transfer_req,
1522 uint16_t pkg_data_len,
1523 uint8_t comp_image_set_ver_str_type,
1524 uint8_t comp_image_set_ver_str_len,
1525 const struct variable_field *comp_img_set_ver_str,
1526 struct pldm_msg *msg, size_t payload_length);
1527
1528 /** @brief Decode PLDM request message for RequestUpdate
1529 *
1530 * @param[in] msg - Message
1531 * @param[in] payload_length - Length of request message payload
1532 * @param[out] req - RequestUpdate request parameters
1533 *
1534 * @return 0 on success, a negative errno value on failure.
1535 *
1536 * @note Caller is responsible for memory alloc and dealloc of param
1537 * 'msg.payload'
1538 */
1539 int decode_request_update_req(const struct pldm_msg *msg, size_t payload_length,
1540 struct pldm_request_update_req_full *req);
1541
1542 /** @brief Decode a RequestUpdate response message
1543 *
1544 * @param[in] msg - Response message
1545 * @param[in] payload_length - Length of response message payload
1546 * @param[out] completion_code - Pointer to hold the completion code
1547 * @param[out] fd_meta_data_len - Pointer to hold the length of FD metadata
1548 * @param[out] fd_will_send_pkg_data - Pointer to hold information whether FD
1549 * will send GetPackageData command
1550 * @return pldm_completion_codes
1551 */
1552 int decode_request_update_resp(const struct pldm_msg *msg,
1553 size_t payload_length, uint8_t *completion_code,
1554 uint16_t *fd_meta_data_len,
1555 uint8_t *fd_will_send_pkg_data);
1556
1557 /** @brief Create PLDM response message for RequestUpdate
1558 *
1559 * @param[in] instance_id - Message's instance id
1560 * @param[in] resp_data - Response data
1561 * @param[out] msg - Message will be written to this
1562 * @param[inout] payload_length - Length of response message payload
1563 *
1564 * @return 0 on success, a negative errno value on failure.
1565 *
1566 * @note Caller is responsible for memory alloc and dealloc of param
1567 * 'msg.payload'
1568 */
1569 int encode_request_update_resp(uint8_t instance_id,
1570 const struct pldm_request_update_resp *resp_data,
1571 struct pldm_msg *msg, size_t *payload_length);
1572
1573 /** @brief Create PLDM request message for RequestDownstreamDeviceUpdate
1574 *
1575 * @param[in] instance_id - Message's instance id
1576 * @param[in] req_data - Request data.
1577 * @param[in,out] msg - Message will be written to this
1578 * @param[in,out] payload_length - Length of response message payload
1579 *
1580 * @return 0 on success,
1581 * -EINVAL if any argument is invalid,
1582 * -ENOMSG if the message type is incorrect,
1583 * -EOVERFLOW if the payload length is invalid
1584 *
1585 * @note Caller is responsible for memory alloc and dealloc of param
1586 * 'msg.payload'
1587 */
1588 int encode_request_downstream_device_update_req(
1589 uint8_t instance_id,
1590 const struct pldm_request_downstream_device_update_req *req_data,
1591 struct pldm_msg *msg, size_t *payload_length);
1592
1593 /** @brief Decode PLDM request message for RequestDownstreamDeviceUpdate
1594 *
1595 * @param[in] msg - Message
1596 * @param[in] payload_length - Length of request message payload
1597 * @param[out] req_data - RequestDownstreamDeviceUpdate request parameters
1598 *
1599 * @return 0 on success,
1600 * -EINVAL if any argument is invalid,
1601 * -ENOMSG if the message type is incorrect,
1602 * -EOVERFLOW if the payload length is invalid,
1603 * -EBADMSG if the message buffer was not fully consumed
1604 *
1605 * @note Caller is responsible for memory alloc and dealloc of param
1606 * 'msg.payload'
1607 */
1608 int decode_request_downstream_device_update_req(
1609 const struct pldm_msg *msg, size_t payload_length,
1610 struct pldm_request_downstream_device_update_req *req_data);
1611
1612 /** @brief Create PLDM response message for RequestDownstreamDeviceUpdate
1613 *
1614 * @param[in] instance_id - Message's instance id
1615 * @param[in] resp_data - Response data
1616 * @param[out] msg - Message will be written to this
1617 * @param[inout] payload_length - Length of response message payload
1618 *
1619 * @return 0 on success,
1620 * -EINVAL if any argument is invalid,
1621 * -ENOMSG if the message type is incorrect,
1622 * -EOVERFLOW if the payload length is invalid
1623 *
1624 * @note Caller is responsible for memory alloc and dealloc of param
1625 * 'msg.payload'
1626 */
1627 int encode_request_downstream_device_update_resp(
1628 uint8_t instance_id,
1629 const struct pldm_request_downstream_device_update_resp *resp_data,
1630 struct pldm_msg *msg, size_t *payload_length);
1631
1632 /** @brief Decode a RequestDownstreamDeviceUpdate response message
1633 *
1634 * @param[in] msg - Response message
1635 * @param[in] payload_length - Length of response message payload
1636 * @param[out] resp_data - RequestDownstreamDeviceUpdate respond parameters
1637 *
1638 * @return 0 on success,
1639 * -EINVAL if any argument is invalid,
1640 * -ENOMSG if the message type is incorrect,
1641 * -EOVERFLOW if the payload length is invalid,
1642 * -EBADMSG if the message buffer was not fully consumed
1643 */
1644 int decode_request_downstream_device_update_resp(
1645 const struct pldm_msg *msg, size_t payload_length,
1646 struct pldm_request_downstream_device_update_resp *resp_data);
1647
1648 /** @brief Create PLDM request message for PassComponentTable
1649 *
1650 * @param[in] instance_id - Message's instance id
1651 * @param[in] transfer_flag - TransferFlag
1652 * @param[in] comp_classification - ComponentClassification
1653 * @param[in] comp_identifier - ComponentIdentifier
1654 * @param[in] comp_classification_index - ComponentClassificationIndex
1655 * @param[in] comp_comparison_stamp - ComponentComparisonStamp
1656 * @param[in] comp_ver_str_type - ComponentVersionStringType
1657 * @param[in] comp_ver_str_len - ComponentVersionStringLength
1658 * @param[in] comp_ver_str - ComponentVersionString
1659 * @param[in,out] msg - Message will be written to this
1660 * @param[in] payload_length - Length of request message payload
1661 * information
1662 *
1663 * @return pldm_completion_codes
1664 *
1665 * @note Caller is responsible for memory alloc and dealloc of param
1666 * 'msg.payload'
1667 */
1668 int encode_pass_component_table_req(
1669 uint8_t instance_id, uint8_t transfer_flag,
1670 uint16_t comp_classification, uint16_t comp_identifier,
1671 uint8_t comp_classification_index, uint32_t comp_comparison_stamp,
1672 uint8_t comp_ver_str_type, uint8_t comp_ver_str_len,
1673 const struct variable_field *comp_ver_str, struct pldm_msg *msg,
1674 size_t payload_length);
1675
1676 /** @brief Decode a PassComponentTable request
1677 *
1678 * @param[in] msg - PLDM Message
1679 * @param[in] payload_length
1680 * @param[out] pcomp - Pass Component Table Request
1681 *
1682 * @return 0 on success, a negative errno value on failure.
1683 */
1684 int decode_pass_component_table_req(
1685 const struct pldm_msg *msg, size_t payload_length,
1686 struct pldm_pass_component_table_req_full *pcomp);
1687
1688 /** @brief Decode PassComponentTable response message
1689 *
1690 * @param[in] msg - Response message
1691 * @param[in] payload_length - Length of response message payload
1692 * @param[out] completion_code - Pointer to hold completion code
1693 * @param[out] comp_resp - Pointer to hold component response
1694 * @param[out] comp_resp_code - Pointer to hold component response code
1695 *
1696 * @return pldm_completion_codes
1697 */
1698 int decode_pass_component_table_resp(const struct pldm_msg *msg,
1699 size_t payload_length,
1700 uint8_t *completion_code,
1701 uint8_t *comp_resp,
1702 uint8_t *comp_resp_code);
1703
1704 /** @brief Encode PassComponentTable response
1705 *
1706 * @param[in] instance_id - PLDM Instance ID matching the request
1707 * @param[in] resp_data - response data
1708 * @param[out] msg - Response message
1709 * @param[inout] payload_length - Length of msg payload buffer,
1710 * will be updated with the written
1711 * length on success.
1712 *
1713 * @return 0 on success, a negative errno value on failure.
1714 */
1715 int encode_pass_component_table_resp(
1716 uint8_t instance_id,
1717 const struct pldm_pass_component_table_resp *resp_data,
1718 struct pldm_msg *msg, size_t *payload_length);
1719
1720 /** @brief Create PLDM request message for UpdateComponent
1721 *
1722 * @param[in] instance_id - Message's instance id
1723 * @param[in] comp_classification - ComponentClassification
1724 * @param[in] comp_identifier - ComponentIdentifier
1725 * @param[in] comp_classification_index - ComponentClassificationIndex
1726 * @param[in] comp_comparison_stamp - ComponentComparisonStamp
1727 * @param[in] comp_image_size - ComponentImageSize
1728 * @param[in] update_option_flags - UpdateOptionFlags
1729 * @param[in] comp_ver_str_type - ComponentVersionStringType
1730 * @param[in] comp_ver_str_len - ComponentVersionStringLength
1731 * @param[in] comp_ver_str - ComponentVersionString
1732 * @param[in,out] msg - Message will be written to this
1733 * @param[in] payload_length - Length of request message payload
1734 * information
1735 *
1736 * @return pldm_completion_codes
1737 *
1738 * @note Caller is responsible for memory alloc and dealloc of param
1739 * 'msg.payload'
1740 */
1741 int encode_update_component_req(
1742 uint8_t instance_id, uint16_t comp_classification,
1743 uint16_t comp_identifier, uint8_t comp_classification_index,
1744 uint32_t comp_comparison_stamp, uint32_t comp_image_size,
1745 bitfield32_t update_option_flags, uint8_t comp_ver_str_type,
1746 uint8_t comp_ver_str_len, const struct variable_field *comp_ver_str,
1747 struct pldm_msg *msg, size_t payload_length);
1748
1749 /** @brief Decode UpdateComponent request message
1750 *
1751 * @param[in] msg - Request message
1752 * @param[in] payload_length - Length of request message payload
1753 * @param[out] up - UpdateComponent request parameters
1754 *
1755 * @return 0 on success, a negative errno value on failure.
1756 */
1757 int decode_update_component_req(const struct pldm_msg *msg,
1758 size_t payload_length,
1759 struct pldm_update_component_req_full *up);
1760
1761 /** @brief Decode UpdateComponent response message
1762 *
1763 * @param[in] msg - Response message
1764 * @param[in] payload_length - Length of response message payload
1765 * @param[out] completion_code - Pointer to hold completion code
1766 * @param[out] comp_compatibility_resp - Pointer to hold component
1767 * compatibility response
1768 * @param[out] comp_compatibility_resp_code - Pointer to hold component
1769 * compatibility response code
1770 * @param[out] update_option_flags_enabled - Pointer to hold
1771 * UpdateOptionsFlagEnabled
1772 * @param[out] time_before_req_fw_data - Pointer to hold the estimated time
1773 * before sending RequestFirmwareData
1774 *
1775 * @return pldm_completion_codes
1776 */
1777 int decode_update_component_resp(const struct pldm_msg *msg,
1778 size_t payload_length,
1779 uint8_t *completion_code,
1780 uint8_t *comp_compatibility_resp,
1781 uint8_t *comp_compatibility_resp_code,
1782 bitfield32_t *update_option_flags_enabled,
1783 uint16_t *time_before_req_fw_data);
1784
1785 /** @brief Encode UpdateComponent response
1786 *
1787 * @param[in] instance_id - PLDM Instance ID matching the request
1788 * @param[in] resp_data - Response data
1789 * @param[out] msg - Response message
1790 * @param[inout] payload_length - Length of msg payload buffer,
1791 * will be updated with the written
1792 * length on success.
1793 *
1794 * @return 0 on success, a negative errno value on failure.
1795 */
1796 int encode_update_component_resp(
1797 uint8_t instance_id, const struct pldm_update_component_resp *resp_data,
1798 struct pldm_msg *msg, size_t *payload_length);
1799
1800 /** @brief Decode RequestFirmwareData request message
1801 *
1802 * @param[in] msg - Request message
1803 * @param[in] payload_length - Length of request message payload
1804 * @param[out] offset - Pointer to hold offset
1805 * @param[out] length - Pointer to hold the size of the component image
1806 * segment requested by the FD/FDP
1807 *
1808 * @return pldm_completion_codes
1809 */
1810 int decode_request_firmware_data_req(const struct pldm_msg *msg,
1811 size_t payload_length, uint32_t *offset,
1812 uint32_t *length);
1813
1814 /** @brief Encode RequestFirmwareData request
1815 *
1816 * @param[in] instance_id - PLDM Instance ID
1817 * @param[in] req_params - Request parameters
1818 * @param[in] length - firmware data length to request
1819 * @param[out] msg - Response message
1820 * @param[inout] payload_length - Length of msg payload buffer,
1821 * will be updated with the written
1822 * length on success.
1823 *
1824 * @return 0 on success, a negative errno value on failure.
1825 */
1826 int encode_request_firmware_data_req(
1827 uint8_t instance_id,
1828 const struct pldm_request_firmware_data_req *req_params,
1829 struct pldm_msg *msg, size_t *payload_length);
1830
1831 /** @brief Create PLDM response message for RequestFirmwareData
1832 *
1833 * The ComponentImagePortion is not encoded in the PLDM response message
1834 * by encode_request_firmware_data_resp to avoid an additional copy. Populating
1835 * ComponentImagePortion in the PLDM response message is handled by the user
1836 * of this API. The payload_length validation considers only the
1837 * CompletionCode.
1838 *
1839 * @param[in] instance_id - Message's instance id
1840 * @param[in] completion_code - CompletionCode
1841 * @param[in,out] msg - Message will be written to this
1842 * @param[in] payload_length - Length of response message payload
1843 *
1844 * @return pldm_completion_codes
1845 *
1846 * @note Caller is responsible for memory alloc and dealloc of param
1847 * 'msg.payload'
1848 */
1849 int encode_request_firmware_data_resp(uint8_t instance_id,
1850 uint8_t completion_code,
1851 struct pldm_msg *msg,
1852 size_t payload_length);
1853
1854 /** @brief Decode TransferComplete request message
1855 *
1856 * @param[in] msg - Request message
1857 * @param[in] payload_length - Length of request message payload
1858 * @param[out] transfer_result - Pointer to hold TransferResult
1859 *
1860 * @return pldm_completion_codes
1861 */
1862 int decode_transfer_complete_req(const struct pldm_msg *msg,
1863 size_t payload_length,
1864 uint8_t *transfer_result);
1865
1866 /** @brief Encode TransferComplete request
1867 *
1868 * @param[in] instance_id - PLDM Instance ID
1869 * @param[in] transfer_result
1870 * @param[out] msg - Response message
1871 * @param[inout] payload_length - Length of msg payload buffer,
1872 * will be updated with the written
1873 * length on success.
1874 *
1875 * @return 0 on success, a negative errno value on failure.
1876 */
1877 int encode_transfer_complete_req(uint8_t instance_id, uint8_t transfer_result,
1878 struct pldm_msg *msg, size_t *payload_length);
1879
1880 /** @brief Create PLDM response message for TransferComplete
1881 *
1882 * @param[in] instance_id - Message's instance id
1883 * @param[in] completion_code - CompletionCode
1884 * @param[in,out] msg - Message will be written to this
1885 * @param[in] payload_length - Length of response message payload
1886 *
1887 * @return pldm_completion_codes
1888 *
1889 * @note Caller is responsible for memory alloc and dealloc of param
1890 * 'msg.payload'
1891 */
1892 int encode_transfer_complete_resp(uint8_t instance_id, uint8_t completion_code,
1893 struct pldm_msg *msg, size_t payload_length);
1894
1895 /** @brief Decode VerifyComplete request message
1896 *
1897 * @param[in] msg - Request message
1898 * @param[in] payload_length - Length of request message payload
1899 * @param[in] verify_result - Pointer to hold VerifyResult
1900 *
1901 * @return pldm_completion_codes
1902 */
1903 int decode_verify_complete_req(const struct pldm_msg *msg,
1904 size_t payload_length, uint8_t *verify_result);
1905
1906 /** @brief Encode VerifyComplete request
1907 *
1908 * @param[in] instance_id - PLDM Instance ID
1909 * @param[in] verify_result
1910 * @param[out] msg - Response message
1911 * @param[inout] payload_length - Length of msg payload buffer,
1912 * will be updated with the written
1913 * length on success.
1914 *
1915 * @return 0 on success, a negative errno value on failure.
1916 */
1917 int encode_verify_complete_req(uint8_t instance_id, uint8_t verify_result,
1918 struct pldm_msg *msg, size_t *payload_length);
1919
1920 /** @brief Create PLDM response message for VerifyComplete
1921 *
1922 * @param[in] instance_id - Message's instance id
1923 * @param[in] completion_code - CompletionCode
1924 * @param[in,out] msg - Message will be written to this
1925 * @param[in] payload_length - Length of response message payload
1926 *
1927 * @return pldm_completion_codes
1928 *
1929 * @note Caller is responsible for memory alloc and dealloc of param
1930 * 'msg.payload'
1931 */
1932 int encode_verify_complete_resp(uint8_t instance_id, uint8_t completion_code,
1933 struct pldm_msg *msg, size_t payload_length);
1934
1935 /** @brief Decode ApplyComplete request message
1936 *
1937 * @param[in] msg - Request message
1938 * @param[in] payload_length - Length of request message payload
1939 * @param[in] apply_result - Pointer to hold ApplyResult
1940 * @param[in] comp_activation_methods_modification - Pointer to hold the
1941 * ComponentActivationMethodsModification
1942 *
1943 * @return pldm_completion_codes
1944 */
1945 int decode_apply_complete_req(
1946 const struct pldm_msg *msg, size_t payload_length,
1947 uint8_t *apply_result,
1948 bitfield16_t *comp_activation_methods_modification);
1949
1950 /** @brief Encode ApplyComplete request
1951 *
1952 * @param[in] instance_id - PLDM Instance ID
1953 * @param[in] req_data - Request data
1954 * @param[out] msg - Request message
1955 * @param[inout] payload_length - Length of msg payload buffer,
1956 * will be updated with the written
1957 * length on success.
1958 *
1959 * @return 0 on success, a negative errno value on failure.
1960 */
1961 int encode_apply_complete_req(uint8_t instance_id,
1962 const struct pldm_apply_complete_req *req_data,
1963 struct pldm_msg *msg, size_t *payload_length);
1964
1965 /** @brief Create PLDM response message for ApplyComplete
1966 *
1967 * @param[in] instance_id - Message's instance id
1968 * @param[in] completion_code - CompletionCode
1969 * @param[in,out] msg - Message will be written to this
1970 * @param[in] payload_length - Length of response message payload
1971 *
1972 * @return pldm_completion_codes
1973 *
1974 * @note Caller is responsible for memory alloc and dealloc of param
1975 * 'msg.payload'
1976 */
1977 int encode_apply_complete_resp(uint8_t instance_id, uint8_t completion_code,
1978 struct pldm_msg *msg, size_t payload_length);
1979
1980 /** @brief Create PLDM request message for ActivateFirmware
1981 *
1982 * @param[in] instance_id - Message's instance id
1983 * @param[in] self_contained_activation_req SelfContainedActivationRequest
1984 * @param[in,out] msg - Message will be written to this
1985 * @param[in] payload_length - Length of request message payload
1986 *
1987 * @return pldm_completion_codes
1988 *
1989 * @note Caller is responsible for memory alloc and dealloc of param
1990 * 'msg.payload'
1991 */
1992 int encode_activate_firmware_req(uint8_t instance_id,
1993 bool8_t self_contained_activation_req,
1994 struct pldm_msg *msg, size_t payload_length);
1995
1996 /** @brief Decode ActivateFirmware request
1997 *
1998 * @param[in] msg - Request message
1999 * @param[in] payload_length - Length of request message payload
2000 * @param[out] self_contained
2001 *
2002 * @return 0 on success, a negative errno value on failure.
2003 */
2004 int decode_activate_firmware_req(const struct pldm_msg *msg,
2005 size_t payload_length, bool *self_contained);
2006
2007 /** @brief Decode ActivateFirmware response message
2008 *
2009 * @param[in] msg - Response message
2010 * @param[in] payload_length - Length of response message payload
2011 * @param[out] completion_code - Pointer to hold CompletionCode
2012 * @param[out] estimated_time_activation - Pointer to hold
2013 * EstimatedTimeForSelfContainedActivation
2014 *
2015 * @return pldm_completion_codes
2016 */
2017 int decode_activate_firmware_resp(const struct pldm_msg *msg,
2018 size_t payload_length,
2019 uint8_t *completion_code,
2020 uint16_t *estimated_time_activation);
2021
2022 /** @brief Encode ActivateFirmware response
2023 *
2024 * @param[in] instance_id - PLDM Instance ID matching the request
2025 * @param[in] resp_data - Response data
2026 * @param[out] msg - Response message
2027 * @param[inout] payload_length - Length of msg payload buffer,
2028 * will be updated with the written
2029 * length on success.
2030 *
2031 * @return 0 on success, a negative errno value on failure.
2032 */
2033 int encode_activate_firmware_resp(
2034 uint8_t instance_id,
2035 const struct pldm_activate_firmware_resp *resp_data,
2036 struct pldm_msg *msg, size_t *payload_length);
2037
2038 /** @brief Create PLDM request message for GetStatus
2039 *
2040 * @param[in] instance_id - Message's instance id
2041 * @param[in,out] msg - Message will be written to this
2042 * @param[in] payload_length - Length of request message payload
2043 *
2044 * @return pldm_completion_codes
2045 *
2046 * @note Caller is responsible for memory alloc and dealloc of param
2047 * 'msg.payload'
2048 */
2049 int encode_get_status_req(uint8_t instance_id, struct pldm_msg *msg,
2050 size_t payload_length);
2051
2052 /** @brief Decode GetStatus response message
2053 *
2054 * @param[in] msg - Response message
2055 * @param[in] payload_length - Length of response message payload
2056 * @param[out] completion_code - Pointer to completion code
2057 * @param[out] current_state - Pointer to current state machine state
2058 * @param[out] previous_state - Pointer to previous different state machine
2059 * state
2060 * @param[out] aux_state - Pointer to current operation state of FD/FDP
2061 * @param[out] aux_state_status - Pointer to aux state status
2062 * @param[out] progress_percent - Pointer to progress percentage
2063 * @param[out] reason_code - Pointer to reason for entering current state
2064 * @param[out] update_option_flags_enabled - Pointer to update option flags
2065 * enabled
2066 *
2067 * @return pldm_completion_codes
2068 */
2069 int decode_get_status_resp(const struct pldm_msg *msg, size_t payload_length,
2070 uint8_t *completion_code, uint8_t *current_state,
2071 uint8_t *previous_state, uint8_t *aux_state,
2072 uint8_t *aux_state_status, uint8_t *progress_percent,
2073 uint8_t *reason_code,
2074 bitfield32_t *update_option_flags_enabled);
2075
2076 /** @brief Encode GetStatus response
2077 *
2078 * @param[in] instance_id - PLDM Instance ID matching the request
2079 * @param[in] status - GetStatus response. completion_code must be PLDM_SUCCESS.
2080 * @param[out] msg - Response message
2081 * @param[inout] payload_length - Length of msg payload buffer,
2082 * will be updated with the written
2083 * length on success.
2084 *
2085 * @return 0 on success, a negative errno value on failure.
2086 */
2087 int encode_get_status_resp(uint8_t instance_id,
2088 const struct pldm_get_status_resp *status,
2089 struct pldm_msg *msg, size_t *payload_length);
2090
2091 /** @brief Create PLDM request message for CancelUpdateComponent
2092 *
2093 * @param[in] instance_id - Message's instance id
2094 * @param[in,out] msg - Message will be written to this
2095 * @param[in] payload_length - Length of request message payload
2096 *
2097 * @return pldm_completion_codes
2098 *
2099 * @note Caller is responsible for memory alloc and dealloc of param
2100 * 'msg.payload'
2101 */
2102 int encode_cancel_update_component_req(uint8_t instance_id,
2103 struct pldm_msg *msg,
2104 size_t payload_length);
2105
2106 /** @brief Decode CancelUpdateComponent response message
2107 *
2108 * @param[in] msg - Response message
2109 * @param[in] payload_length - Length of response message payload
2110 * @param[out] completion_code - Pointer to the completion code
2111 *
2112 * @return pldm_completion_codes
2113 */
2114 int decode_cancel_update_component_resp(const struct pldm_msg *msg,
2115 size_t payload_length,
2116 uint8_t *completion_code);
2117
2118 /** @brief Create PLDM request message for CancelUpdate
2119 *
2120 * @param[in] instance_id - Message's instance id
2121 * @param[in,out] msg - Message will be written to this
2122 * @param[in] payload_length - Length of request message payload
2123 *
2124 * @return pldm_completion_codes
2125 *
2126 * @note Caller is responsible for memory alloc and dealloc of param
2127 * 'msg.payload'
2128 */
2129 int encode_cancel_update_req(uint8_t instance_id, struct pldm_msg *msg,
2130 size_t payload_length);
2131
2132 /** @brief Decode CancelUpdate response message
2133 *
2134 * @param[in] msg - Response message
2135 * @param[in] payload_length - Length of response message payload
2136 * @param[out] completion_code - Pointer to completion code
2137 * @param[out] non_functioning_component_indication - Pointer to non
2138 functioning
2139 * component indication
2140 * @param[out] non_functioning_component_bitmap - Pointer to non
2141 functioning
2142 * component bitmap
2143 *
2144 * @return pldm_completion_codes
2145 */
2146 int decode_cancel_update_resp(const struct pldm_msg *msg, size_t payload_length,
2147 uint8_t *completion_code,
2148 bool8_t *non_functioning_component_indication,
2149 bitfield64_t *non_functioning_component_bitmap);
2150
2151 /** @brief Encode CancelUpdate response
2152 *
2153 * @param[in] instance_id - PLDM Instance ID matching the request
2154 * @param[in] resp_data - Response data,
2155 * @param[out] msg - Response message
2156 * @param[inout] payload_length - Length of msg payload buffer,
2157 * will be updated with the written
2158 * length on success.
2159 *
2160 * @return 0 on success, a negative errno value on failure.
2161 */
2162 int encode_cancel_update_resp(uint8_t instance_id,
2163 const struct pldm_cancel_update_resp *resp_data,
2164 struct pldm_msg *msg, size_t *payload_length);
2165
2166 /** @brief Firmware update v1.0 package header identifier */
2167 #define PLDM_PACKAGE_HEADER_IDENTIFIER_V1_0 \
2168 { 0xF0, 0x18, 0x87, 0x8C, 0xCB, 0x7D, 0x49, 0x43, \
2169 0x98, 0x00, 0xA0, 0x2F, 0x05, 0x9A, 0xCA, 0x02 }
2170
2171 /** @brief Firmware update v1.0 package header format revision */
2172 #define PLDM_PACKAGE_HEADER_FORMAT_REVISION_FR01H 0x01
2173
2174 /** @brief Firmware update v1.1 package header identifier */
2175 #define PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1 \
2176 { \
2177 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, \
2178 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5a, \
2179 }
2180
2181 /** @brief Firmware update v1.1 package header format revision */
2182 #define PLDM_PACKAGE_HEADER_FORMAT_REVISION_FR02H 0x02
2183
2184 /** @brief Consumer-side version pinning for package format parsing
2185 *
2186 * Parsing a firmware update package requires the package to be of a revision
2187 * defined in the specification, for libpldm to support parsing a package
2188 * formatted at the specified revision, and for the consumer to support calling
2189 * libpldm's package-parsing APIs in the manner required for the package format.
2190 *
2191 * pldm_package_format_pin communicates to libpldm the maximum package format
2192 * revision supported by the consumer.
2193 *
2194 * The definition of the pldm_package_format_pin object in the consumer
2195 * application should not be open-coded. Instead, users should call on of the
2196 * following macros:
2197 *
2198 * - @ref DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR01H
2199 * - @ref DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR02H
2200 *
2201 * The package pinning operates by providing versioning over multiple structs
2202 * required to perform the package parsing. See [Conventions for extensible
2203 * system calls][lwn-extensible-syscalls] for discussion of related concepts.
2204 * Like the syscall structs described there, the structs captured here by the
2205 * pinning concept must only ever be modified by addition of new members, never
2206 * alteration of existing members.
2207 *
2208 * [lwn-extensible-syscalls]: https://lwn.net/Articles/830666/
2209 */
2210 struct pldm_package_format_pin {
2211 struct {
2212 /**
2213 * A value that communicates information about object sizes to the implementation.
2214 *
2215 * For magic version 0, the sum must be calculated using @ref LIBPLDM_SIZEAT for
2216 * the final relevant member of each relevant struct for the format revision
2217 * represented by the pin.
2218 */
2219 const uint32_t magic;
2220
2221 /**
2222 * Versioning for the derivation of the magic value
2223 *
2224 * A version value of 0 defines the magic number to be the sum of the relevant
2225 * struct sizes for the members required at the format revision specified by
2226 * the pin.
2227 */
2228 const uint8_t version;
2229 } meta;
2230 struct {
2231 /** The maximum supported package format UUID */
2232 const pldm_uuid identifier;
2233
2234 /** The maximum supported header format revision */
2235 const uint8_t revision;
2236 } format;
2237 };
2238
2239 /**
2240 * @brief Header information as parsed from the provided package
2241 *
2242 * See Table 3, DSP0267 v1.3.0.
2243 *
2244 * The provided package data must out-live the header struct.
2245 */
2246 struct pldm__package_header_information {
2247 pldm_uuid package_header_identifier;
2248 uint8_t package_header_format_revision;
2249 uint8_t package_release_date_time[PLDM_TIMESTAMP104_SIZE];
2250 uint16_t component_bitmap_bit_length;
2251 uint8_t package_version_string_type;
2252
2253 /** A field pointing to the package version string in the provided package data */
2254 struct variable_field package_version_string;
2255
2256 /* TODO: some metadata for the parsing process is stored here, reconsider */
2257 struct variable_field areas;
2258 struct variable_field package;
2259 };
2260 /* TODO: Deprecate the other struct pldm_package_header_information, remove, drop typedef */
2261 typedef struct pldm__package_header_information
2262 pldm_package_header_information_pad;
2263
2264 /* TODO: Consider providing an API to access valid bits */
2265 struct pldm_package_component_bitmap {
2266 struct variable_field bitmap;
2267 };
2268
2269 /**
2270 * @brief A firmware device ID record from the firmware update package
2271 *
2272 * See Table 4, DSP0267 v1.3.0.
2273 *
2274 * The provided package data must out-live the @ref "struct
2275 * pldm_package_firmware_device_id_record" instance.
2276 */
2277 struct pldm_package_firmware_device_id_record {
2278 uint8_t descriptor_count;
2279 bitfield32_t device_update_option_flags;
2280 uint8_t component_image_set_version_string_type;
2281
2282 /**
2283 * A field pointing to the component image set version string in the provided
2284 * package data.
2285 */
2286 struct variable_field component_image_set_version_string;
2287
2288 /**
2289 * A field pointing to the to a bitmap of length @ref
2290 * component_bitmap_bit_length in the provided package data..
2291 */
2292 struct pldm_package_component_bitmap applicable_components;
2293
2294 /**
2295 * A field pointing to record descriptors for the
2296 * firmware device. Iterate over the entries using @ref
2297 * foreach_pldm_package_firmware_device_id_record_descriptor
2298 *
2299 * See Table 7, DSP0267 v1.3.0
2300 */
2301 struct variable_field record_descriptors;
2302 struct variable_field firmware_device_package_data;
2303 };
2304
2305 /**
2306 * @brief A downstream device ID record from the firmware update package
2307 *
2308 * See Table 5, DSP0267 v1.3.0.
2309 *
2310 * The provided package data must out-live the @ref "struct
2311 * pldm_package_downstream_device_id_record" instance.
2312 */
2313 struct pldm_package_downstream_device_id_record {
2314 uint8_t descriptor_count;
2315 bitfield32_t update_option_flags;
2316 uint8_t self_contained_activation_min_version_string_type;
2317
2318 /**
2319 * A field pointing to the self-contained activation minimum version string in
2320 * the provided package data.
2321 */
2322 struct variable_field self_contained_activation_min_version_string;
2323 uint32_t self_contained_activation_min_version_comparison_stamp;
2324
2325 /**
2326 * A field pointing to a bitmap of length @ref component_bitmap_bit_length in
2327 * the provided package data.
2328 */
2329 struct pldm_package_component_bitmap applicable_components;
2330
2331 /**
2332 * A field pointing to record descriptors for the
2333 * downstream device. Iterate over the entries using @ref
2334 * foreach_pldm_package_downstream_device_id_record_descriptor
2335 *
2336 * See Table 7, DSP0267 v1.3.0
2337 */
2338 struct variable_field record_descriptors;
2339
2340 /**
2341 * A field that may point to package data to be proxied by the firmware device.
2342 * If present, points into the provided package data.
2343 */
2344 struct variable_field package_data;
2345 };
2346
2347 /**
2348 * @brief Component image information from the firmware update package.
2349 *
2350 * See Table 6, DSP0267 v1.3.0
2351 *
2352 * The provided package data must out-live the @ref "struct
2353 * pldm_package_component_image_information" instance.
2354 */
2355 struct pldm_package_component_image_information {
2356 uint16_t component_classification;
2357 uint16_t component_identifier;
2358 uint32_t component_comparison_stamp;
2359 bitfield16_t component_options;
2360 bitfield16_t requested_component_activation_method;
2361
2362 /**
2363 * A field that points to the component image for a device in the provided
2364 * package data.
2365 */
2366 struct variable_field component_image;
2367 uint8_t component_version_string_type;
2368
2369 /**
2370 * A field that points to the component version string for the image in the
2371 * provided package data.
2372 */
2373 struct variable_field component_version_string;
2374 };
2375
2376 struct pldm_package_firmware_device_id_record_iter {
2377 struct variable_field field;
2378 size_t entries;
2379 };
2380
2381 struct pldm_package_downstream_device_id_record_iter {
2382 struct variable_field field;
2383 size_t entries;
2384 };
2385
2386 struct pldm_package_component_image_information_iter {
2387 struct variable_field field;
2388 size_t entries;
2389 };
2390
2391 /**
2392 * @brief State tracking for firmware update package iteration
2393 *
2394 * Declare an instance on the stack to be initialised by @ref
2395 * decode_pldm_firmware_update_package
2396 *
2397 * The state is consumed by the following macros:
2398 *
2399 * - @ref foreach_pldm_package_firmware_device_id_record
2400 * - @ref foreach_pldm_package_firmware_device_id_record_descriptor
2401 * - @ref foreach_pldm_package_downstream_device_id_record
2402 * - @ref foreach_pldm_package_downstream_device_id_record_descriptor
2403 * - @ref foreach_pldm_package_component_image_information
2404 */
2405 struct pldm_package_iter {
2406 const pldm_package_header_information_pad *hdr;
2407
2408 /* Modified in the course of iteration */
2409 struct pldm_package_firmware_device_id_record_iter fds;
2410 struct pldm_package_downstream_device_id_record_iter dds;
2411 struct pldm_package_component_image_information_iter infos;
2412 };
2413
2414 /**
2415 * @brief Initialize the firmware update package iterator.
2416 *
2417 * @param[in] data The buffer containing the complete firmware update package
2418 * @param[in] length The length of the buffer pointed at by @p data
2419 * @param[in] pin The maximum supported package format revision of the caller
2420 * @param[out] hdr The parsed package header structure
2421 * @param[out] iter State-tracking for parsing subsequent package records and components
2422 *
2423 * Must be called to ensure version requirements for parsing are met by all
2424 * components, and to initialise @p iter prior to any subsequent extraction of
2425 * package records and components.
2426 *
2427 * @note @p data is stored in @iter for later reference, and therefore must
2428 * out-live @p iter
2429 * @note @p hdr is stored in @iter for later reference, and therefore must
2430 * out-live @p iter
2431 *
2432 * @return 0 on success. Otherwise, a negative errno value:
2433 * - -EBADMSG if the package fails to meet minimum required length for a valid
2434 * package
2435 * - -EINVAL if provided parameter values are invalid
2436 * - -ENOTSUP on unrecognised or unsupported versions for the format pin or
2437 * provided package
2438 * - -EOVERFLOW if the variable length structures extend beyond the package
2439 * data buffer
2440 * - -EPROTO if parsed values violate the package format specification
2441 * - -EUCLEAN if the package fails embedded integrity checks
2442 */
2443 int decode_pldm_firmware_update_package(
2444 const void *data, size_t length,
2445 const struct pldm_package_format_pin *pin,
2446 pldm_package_header_information_pad *hdr,
2447 struct pldm_package_iter *iter);
2448
2449 LIBPLDM_ITERATOR
pldm_package_firmware_device_id_record_iter_end(const struct pldm_package_firmware_device_id_record_iter * iter)2450 bool pldm_package_firmware_device_id_record_iter_end(
2451 const struct pldm_package_firmware_device_id_record_iter *iter)
2452 {
2453 return iter->entries == 0;
2454 }
2455
2456 LIBPLDM_ITERATOR
pldm_package_firmware_device_id_record_iter_next(struct pldm_package_firmware_device_id_record_iter * iter)2457 bool pldm_package_firmware_device_id_record_iter_next(
2458 struct pldm_package_firmware_device_id_record_iter *iter)
2459 {
2460 if (!iter->entries) {
2461 return false;
2462 }
2463 iter->entries--;
2464 return true;
2465 }
2466
2467 int pldm_package_firmware_device_id_record_iter_init(
2468 const pldm_package_header_information_pad *hdr,
2469 struct pldm_package_firmware_device_id_record_iter *iter);
2470
2471 int decode_pldm_package_firmware_device_id_record_from_iter(
2472 const pldm_package_header_information_pad *hdr,
2473 struct pldm_package_firmware_device_id_record_iter *iter,
2474 struct pldm_package_firmware_device_id_record *rec);
2475
2476 /**
2477 * @brief Iterate over a package's firmware device ID records
2478 *
2479 * @param iter[in,out] The lvalue for the instance of @ref "struct pldm_package_iter"
2480 * initialised by @ref decode_pldm_firmware_update_package
2481 * @param rec[out] An lvalue of type @ref "struct pldm_package_firmware_device_id_record"
2482 * @param rc[out] An lvalue of type int that holds the status result of parsing the
2483 * firmware device ID record
2484 *
2485 * @p rc is set to 0 on successful decode. Otherwise, on error, @p rc is set to:
2486 * - -EINVAL if parameters values are invalid
2487 * - -EOVERFLOW if the package layout exceeds the bounds of the package buffer
2488 * - -EPROTO if package metadata doesn't conform to specification constraints
2489 *
2490 * Example use of the macro is as follows:
2491 *
2492 * @code
2493 * DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR02H(pin);
2494 *
2495 * struct pldm_package_firmware_device_id_record fdrec;
2496 * pldm_package_header_information_pad hdr;
2497 * struct pldm_package_iter iter;
2498 * int rc;
2499 *
2500 * rc = decode_pldm_firmware_update_package(package, in, &pin, &hdr,
2501 * &iter);
2502 * if (rc < 0) {
2503 * // Handle header parsing failure
2504 * }
2505 * foreach_pldm_package_firmware_device_id_record(iter, fdrec, rc) {
2506 * // Do something with fdrec
2507 * }
2508 * if (rc) {
2509 * // Handle parsing failure for fdrec
2510 * }
2511 * @endcode
2512 */
2513 #define foreach_pldm_package_firmware_device_id_record(iter, rec, rc) \
2514 for ((rc) = pldm_package_firmware_device_id_record_iter_init( \
2515 (iter).hdr, &(iter).fds); \
2516 !(rc) && \
2517 !pldm_package_firmware_device_id_record_iter_end(&(iter).fds) && \
2518 !((rc) = decode_pldm_package_firmware_device_id_record_from_iter( \
2519 (iter).hdr, &(iter).fds, &(rec))); \
2520 pldm_package_firmware_device_id_record_iter_next(&(iter).fds))
2521
2522 LIBPLDM_ITERATOR
2523 struct pldm_descriptor_iter
pldm_package_firmware_device_id_record_descriptor_iter_init(struct pldm_package_firmware_device_id_record_iter * iter,struct pldm_package_firmware_device_id_record * rec)2524 pldm_package_firmware_device_id_record_descriptor_iter_init(
2525 struct pldm_package_firmware_device_id_record_iter *iter,
2526 struct pldm_package_firmware_device_id_record *rec)
2527 {
2528 (void)iter;
2529 return (struct pldm_descriptor_iter){ &rec->record_descriptors,
2530 rec->descriptor_count };
2531 }
2532
2533 /**
2534 * @brief Iterate over the descriptors in a package's firmware device ID record
2535 *
2536 * @param iter[in,out] The lvalue for the instance of @ref "struct pldm_package_iter"
2537 * initialised by @ref decode_pldm_firmware_update_package
2538 * @param rec[in] An lvalue of type @ref "struct pldm_package_firmware_device_id_record"
2539 * @param desc[out] An lvalue of type @ref "struct pldm_descriptor" that holds
2540 * the parsed descriptor
2541 * @param rc[out] An lvalue of type int that holds the status result of parsing the
2542 * firmware device ID record
2543 *
2544 * @p rc is set to 0 on successful decode. Otherwise, on error, @p rc is set to:
2545 * - -EINVAL if parameters values are invalid
2546 * - -EOVERFLOW if the package layout exceeds the bounds of the package buffer
2547 * - -EPROTO if package metadata doesn't conform to specification constraints
2548 *
2549 * Example use of the macro is as follows:
2550 *
2551 * @code
2552 * DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR02H(pin);
2553 *
2554 * struct pldm_package_firmware_device_id_record fdrec;
2555 * pldm_package_header_information_pad hdr;
2556 * struct pldm_package_iter iter;
2557 * int rc;
2558 *
2559 * rc = decode_pldm_firmware_update_package(package, in, &pin, &hdr,
2560 * &iter);
2561 * if (rc < 0) { ... }
2562 *
2563 * foreach_pldm_package_firmware_device_id_record(iter, fdrec, rc) {
2564 * struct pldm_descriptor desc;
2565 *
2566 * ...
2567 *
2568 * foreach_pldm_package_firmware_device_id_record_descriptor(
2569 * iter, fdrec, desc, rc) {
2570 * // Do something with desc
2571 * }
2572 * if (rc) {
2573 * // Handle failure to parse desc
2574 * }
2575 * }
2576 * if (rc) { ... }
2577 * @endcode
2578 */
2579 #define foreach_pldm_package_firmware_device_id_record_descriptor(iter, rec, \
2580 desc, rc) \
2581 for (struct pldm_descriptor_iter desc##_iter = \
2582 ((rc) = 0, \
2583 pldm_package_firmware_device_id_record_descriptor_iter_init( \
2584 &(iter).fds, &(rec))); \
2585 (!pldm_descriptor_iter_end(&(desc##_iter))) && \
2586 !((rc) = decode_pldm_descriptor_from_iter(&(desc##_iter), \
2587 &(desc))); \
2588 pldm_descriptor_iter_next(&(desc##_iter)))
2589
2590 LIBPLDM_ITERATOR
pldm_package_downstream_device_id_record_iter_end(const struct pldm_package_downstream_device_id_record_iter * iter)2591 bool pldm_package_downstream_device_id_record_iter_end(
2592 const struct pldm_package_downstream_device_id_record_iter *iter)
2593 {
2594 return iter->entries == 0;
2595 }
2596
2597 LIBPLDM_ITERATOR
pldm_package_downstream_device_id_record_iter_next(struct pldm_package_downstream_device_id_record_iter * iter)2598 bool pldm_package_downstream_device_id_record_iter_next(
2599 struct pldm_package_downstream_device_id_record_iter *iter)
2600 {
2601 if (!iter->entries) {
2602 return false;
2603 }
2604 iter->entries--;
2605 return true;
2606 }
2607
2608 int pldm_package_downstream_device_id_record_iter_init(
2609 const pldm_package_header_information_pad *hdr,
2610 struct pldm_package_firmware_device_id_record_iter *fds,
2611 struct pldm_package_downstream_device_id_record_iter *dds);
2612
2613 int decode_pldm_package_downstream_device_id_record_from_iter(
2614 const pldm_package_header_information_pad *hdr,
2615 struct pldm_package_downstream_device_id_record_iter *iter,
2616 struct pldm_package_downstream_device_id_record *rec);
2617
2618 /**
2619 * @brief Iterate over a package's downstream device ID records
2620 *
2621 * @param iter[in,out] The lvalue for the instance of @ref "struct pldm_package_iter"
2622 * initialised by @ref decode_pldm_firmware_update_package
2623 * @param rec[out] An lvalue of type @ref "struct pldm_package_downstream_device_id_record"
2624 * @param rc[out] An lvalue of type int that holds the status result of parsing the
2625 * firmware device ID record
2626 *
2627 * @p rc is set to 0 on successful decode. Otherwise, on error, @p rc is set to:
2628 * - -EINVAL if parameters values are invalid
2629 * - -EOVERFLOW if the package layout exceeds the bounds of the package buffer
2630 * - -EPROTO if package metadata doesn't conform to specification constraints
2631 *
2632 * Example use of the macro is as follows:
2633 *
2634 * @code
2635 * DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR02H(pin);
2636 *
2637 * struct pldm_package_downstream_device_id_record ddrec;
2638 * struct pldm_package_firmware_device_id_record fdrec;
2639 * pldm_package_header_information_pad hdr;
2640 * struct pldm_package_iter iter;
2641 * int rc;
2642 *
2643 * rc = decode_pldm_firmware_update_package(package, in, &pin, &hdr,
2644 * &iter);
2645 * if (rc < 0) { ... }
2646 *
2647 * foreach_pldm_package_firmware_device_id_record(iter, fdrec, rc) {
2648 * struct pldm_descriptor desc;
2649 * ...
2650 * foreach_pldm_package_firmware_device_id_record_descriptor(
2651 * iter, fdrec, desc, rc) {
2652 * ...
2653 * }
2654 * if (rc) { ... }
2655 * }
2656 * if (rc) { ... }
2657 *
2658 * foreach_pldm_package_downstream_device_id_record(iter, ddrec, rc) {
2659 * // Do something with ddrec
2660 * }
2661 * if (rc) {
2662 * // Handle parsing failure for ddrec
2663 * }
2664 * @endcode
2665 */
2666 #define foreach_pldm_package_downstream_device_id_record(iter, rec, rc) \
2667 for ((rc) = pldm_package_downstream_device_id_record_iter_init( \
2668 (iter).hdr, &(iter).fds, &(iter).dds); \
2669 !(rc) && \
2670 !pldm_package_downstream_device_id_record_iter_end( \
2671 &(iter).dds) && \
2672 !((rc) = decode_pldm_package_downstream_device_id_record_from_iter( \
2673 (iter).hdr, &(iter).dds, &(rec))); \
2674 pldm_package_downstream_device_id_record_iter_next(&(iter).dds))
2675
2676 LIBPLDM_ITERATOR
2677 struct pldm_descriptor_iter
pldm_package_downstream_device_id_record_descriptor_iter_init(struct pldm_package_downstream_device_id_record_iter * iter,struct pldm_package_downstream_device_id_record * rec)2678 pldm_package_downstream_device_id_record_descriptor_iter_init(
2679 struct pldm_package_downstream_device_id_record_iter *iter,
2680 struct pldm_package_downstream_device_id_record *rec)
2681 {
2682 (void)iter;
2683 return (struct pldm_descriptor_iter){ &rec->record_descriptors,
2684 rec->descriptor_count };
2685 }
2686
2687 /**
2688 * @brief Iterate over the descriptors in a package's downstream device ID record
2689 *
2690 * @param iter[in,out] The lvalue for the instance of @ref "struct pldm_package_iter"
2691 * initialised by @ref decode_pldm_firmware_update_package
2692 * @param rec[in] An lvalue of type @ref "struct pldm_package_downstream_device_id_record"
2693 * @param desc[out] An lvalue of type @ref "struct pldm_descriptor" that holds
2694 * the parsed descriptor
2695 * @param rc[out] An lvalue of type int that holds the status result of parsing the
2696 * downstream device ID record
2697 *
2698 * @p rc is set to 0 on successful decode. Otherwise, on error, @p rc is set to:
2699 * - -EINVAL if parameters values are invalid
2700 * - -EOVERFLOW if the package layout exceeds the bounds of the package buffer
2701 * - -EPROTO if package metadata doesn't conform to specification constraints
2702 *
2703 * Example use of the macro is as follows:
2704 *
2705 * @code
2706 * DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR02H(pin);
2707 *
2708 * struct pldm_package_downstream_device_id_record ddrec;
2709 * struct pldm_package_firmware_device_id_record fdrec;
2710 * pldm_package_header_information_pad hdr;
2711 * struct pldm_package_iter iter;
2712 * int rc;
2713 *
2714 * rc = decode_pldm_firmware_update_package(package, in, &pin, &hdr,
2715 * &iter);
2716 * if (rc < 0) { ... }
2717 *
2718 * foreach_pldm_package_firmware_device_id_record(iter, fdrec, rc) {
2719 * struct pldm_descriptor desc;
2720 * ...
2721 * foreach_pldm_package_firmware_device_id_record_descriptor(
2722 * iter, fdrec, desc, rc) {
2723 * ...
2724 * }
2725 * if (rc) { ... }
2726 * }
2727 * if (rc) { ... }
2728 *
2729 * foreach_pldm_package_downstream_device_id_record(iter, ddrec, rc) {
2730 * struct pldm_descriptor desc;
2731 * ...
2732 * foreach_pldm_package_downstream_device_id_record_descriptor(
2733 * iter, ddrec, desc, rc)
2734 * {
2735 * // Do something with desc
2736 * }
2737 * if (rc) {
2738 * // Handle parsing failure for desc
2739 * }
2740 * }
2741 * if (rc) { ... }
2742 * @endcode
2743 */
2744 #define foreach_pldm_package_downstream_device_id_record_descriptor(iter, rec, \
2745 desc, rc) \
2746 for (struct pldm_descriptor_iter desc##_iter = \
2747 ((rc) = 0, \
2748 pldm_package_downstream_device_id_record_descriptor_iter_init( \
2749 &(iter).dds, &(rec))); \
2750 (!pldm_descriptor_iter_end(&(desc##_iter))) && \
2751 !((rc) = decode_pldm_descriptor_from_iter(&(desc##_iter), \
2752 &(desc))); \
2753 pldm_descriptor_iter_next(&(desc##_iter)))
2754
2755 LIBPLDM_ITERATOR
pldm_package_component_image_information_iter_end(const struct pldm_package_component_image_information_iter * iter)2756 bool pldm_package_component_image_information_iter_end(
2757 const struct pldm_package_component_image_information_iter *iter)
2758 {
2759 return (iter->entries == 0);
2760 }
2761
2762 LIBPLDM_ITERATOR
pldm_package_component_image_information_iter_next(struct pldm_package_component_image_information_iter * iter)2763 bool pldm_package_component_image_information_iter_next(
2764 struct pldm_package_component_image_information_iter *iter)
2765 {
2766 if (!iter->entries) {
2767 return false;
2768 }
2769 iter->entries--;
2770 return true;
2771 }
2772
2773 int pldm_package_component_image_information_iter_init(
2774 const pldm_package_header_information_pad *hdr,
2775 struct pldm_package_downstream_device_id_record_iter *dds,
2776 struct pldm_package_component_image_information_iter *infos);
2777
2778 int decode_pldm_package_component_image_information_from_iter(
2779 const pldm_package_header_information_pad *hdr,
2780 struct pldm_package_component_image_information_iter *iter,
2781 struct pldm_package_component_image_information *info);
2782
2783 /**
2784 * @brief Iterate over the component image information contained in the package
2785 *
2786 * @param iter[in,out] The lvalue for the instance of @ref "struct pldm_package_iter"
2787 * initialised by @ref decode_pldm_firmware_update_package
2788 * @param rec[in] An lvalue of type @ref "struct pldm_package_downstream_device_id_record"
2789 * @param desc[out] An lvalue of type @ref "struct pldm_descriptor" that holds
2790 * the parsed descriptor
2791 * @param rc[out] An lvalue of type int that holds the status result of parsing the
2792 * downstream device ID record
2793 *
2794 * @p rc is set to 0 on successful decode. Otherwise, on error, @p rc is set to:
2795 * - -EINVAL if parameters values are invalid
2796 * - -EOVERFLOW if the package layout exceeds the bounds of the package buffer
2797 * - -EPROTO if package metadata doesn't conform to specification constraints
2798 *
2799 * Example use of the macro is as follows:
2800 *
2801 * @code
2802 * DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR02H(pin);
2803 *
2804 * struct pldm_package_downstream_device_id_record ddrec;
2805 * struct pldm_package_component_image_information info;
2806 * struct pldm_package_firmware_device_id_record fdrec;
2807 * pldm_package_header_information_pad hdr;
2808 * struct pldm_package_iter iter;
2809 * int rc;
2810 *
2811 * rc = decode_pldm_firmware_update_package(package, in, &pin, &hdr,
2812 * &iter);
2813 * if (rc < 0) { ... }
2814 *
2815 * foreach_pldm_package_firmware_device_id_record(iter, fdrec, rc) {
2816 * struct pldm_descriptor desc;
2817 * ...
2818 * foreach_pldm_package_firmware_device_id_record_descriptor(
2819 * iter, fdrec, desc, rc) {
2820 * ...
2821 * }
2822 * if (rc) { ... }
2823 * }
2824 * if (rc) { ... }
2825 *
2826 * foreach_pldm_package_downstream_device_id_record(iter, ddrec, rc) {
2827 * struct pldm_descriptor desc;
2828 * ...
2829 * foreach_pldm_package_downstream_device_id_record_descriptor(
2830 * iter, ddrec, desc, rc) {
2831 * ...
2832 * }
2833 * if (rc) { ... }
2834 * }
2835 * if (rc) { ... }
2836 *
2837 * foreach_pldm_package_component_image_information(iter, info, rc) {
2838 * // Do something with info
2839 * }
2840 * if (rc) {
2841 * // Handle parsing failure for info
2842 * }
2843 * @endcode
2844 */
2845 #define foreach_pldm_package_component_image_information(iter, info, rc) \
2846 for ((rc) = pldm_package_component_image_information_iter_init( \
2847 (iter).hdr, &(iter).dds, &(iter).infos); \
2848 !(rc) && \
2849 !pldm_package_component_image_information_iter_end( \
2850 &(iter).infos) && \
2851 !((rc) = decode_pldm_package_component_image_information_from_iter( \
2852 (iter).hdr, &(iter).infos, &(info))); \
2853 pldm_package_component_image_information_iter_next( \
2854 &(iter).infos))
2855
2856 /**
2857 * Declare consumer support for at most revision 1 of the firmware update
2858 * package header
2859 *
2860 * @param name The name for the pin object
2861 *
2862 * The pin object must be provided to @ref decode_pldm_firmware_update_package
2863 */
2864 #define DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR01H(name) \
2865 struct pldm_package_format_pin name = { \
2866 .meta = { \
2867 .magic = ( \
2868 LIBPLDM_SIZEAT(struct pldm__package_header_information, package) + \
2869 LIBPLDM_SIZEAT(struct pldm_package_firmware_device_id_record, firmware_device_package_data) + \
2870 LIBPLDM_SIZEAT(struct pldm_descriptor, descriptor_data) + \
2871 LIBPLDM_SIZEAT(struct pldm_package_component_image_information, component_version_string) + \
2872 LIBPLDM_SIZEAT(struct pldm_package_iter, infos) \
2873 ), \
2874 .version = 0u, \
2875 }, \
2876 .format = { \
2877 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_0, \
2878 .revision = PLDM_PACKAGE_HEADER_FORMAT_REVISION_FR01H, \
2879 } \
2880 }
2881
2882 /**
2883 * Declare consumer support for at most revision 2 of the firmware update
2884 * package header
2885 *
2886 * @param name The name for the pin object
2887 *
2888 * The pin object must be provided to @ref decode_pldm_firmware_update_package
2889 */
2890 #define DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR02H(name) \
2891 struct pldm_package_format_pin name = { \
2892 .meta = { \
2893 .magic = ( \
2894 LIBPLDM_SIZEAT(struct pldm__package_header_information, package) + \
2895 LIBPLDM_SIZEAT(struct pldm_package_firmware_device_id_record, firmware_device_package_data) + \
2896 LIBPLDM_SIZEAT(struct pldm_descriptor, descriptor_data) + \
2897 LIBPLDM_SIZEAT(struct pldm_package_downstream_device_id_record, package_data) + \
2898 LIBPLDM_SIZEAT(struct pldm_package_component_image_information, component_version_string) + \
2899 LIBPLDM_SIZEAT(struct pldm_package_iter, infos) \
2900 ), \
2901 .version = 0u, \
2902 }, \
2903 .format = { \
2904 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1, \
2905 .revision = PLDM_PACKAGE_HEADER_FORMAT_REVISION_FR02H, \
2906 } \
2907 }
2908
2909 #ifdef __cplusplus
2910 }
2911 #endif
2912
2913 #endif // End of FW_UPDATE_H
2914