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 <libpldm/base.h>
10 #include <libpldm/pldm_types.h>
11 
12 #include "stdbool.h"
13 #include <stddef.h>
14 #include <stdint.h>
15 struct variable_field;
16 
17 #define PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE		 8
18 #define PLDM_FWUP_INVALID_COMPONENT_COMPARISON_TIMESTAMP 0xffffffff
19 #define PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES		 0
20 
21 /** @brief Length of QueryDownstreamDevices response defined in DSP0267_1.1.0
22  *  Table 15 - QueryDownstreamDevices command format.
23  *
24  *  1 byte for completion code
25  *  1 byte for downstream device update supported
26  *  2 bytes for number of downstream devices
27  *  2 bytes for max number of downstream devices
28  *  4 bytes for capabilities
29  */
30 #define PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES 10
31 
32 /** @brief Length of QueryDownstreamIdentifiers request defined in DSP0267_1.1.0
33  * 	Table 16 - QueryDownstreamIdentifiers command format.
34  *
35  *  4 bytes for data transfer handle
36  *  1 byte for transfer operation flag
37 */
38 #define PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES 5
39 
40 /** @brief Minimum length of QueryDownstreamIdentifiers response from DSP0267_1.1.0
41  *  if the complement code is success.
42  *
43  *  1 byte for completion code
44  *  4 bytes for next data transfer handle
45  *  1 byte for transfer flag
46  *  4 bytes for downstream devices length
47  *  2 bytes for number of downstream devices
48  */
49 #define PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN 12
50 
51 /** @brief Minimum length of device descriptor, 2 bytes for descriptor type,
52  *         2 bytes for descriptor length and at least 1 byte of descriptor data
53  */
54 #define PLDM_FWUP_DEVICE_DESCRIPTOR_MIN_LEN 5
55 
56 /** @brief Length of GetDownstreamFirmwareParameters request defined in DSP0267_1.1.0
57  *
58  * 4 bytes for Data Transfer Handle
59  * 1 byte for Transfer Operation Flag
60  */
61 #define PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMS_REQ_BYTES 5
62 
63 /** @brief Minimum length of GetDownstreamFirmwareParameters response from
64  * DSP0267_1.1.0 if the completion code is success.
65  *
66  * 1 byte for completion code
67  * 4 bytes for next data transfer handle
68  * 1 byte for transfer flag
69  * 4 bytes for FDP capabilities during update
70  * 2 bytes for downstream device count
71  */
72 #define PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMS_RESP_MIN_LEN 12
73 
74 /** @brief Minimum length of DownstreamDeviceParameterTable entry from
75  * DSP0267_1.1.0 table 21 - DownstreamDeviceParameterTable
76  *
77  * 2 bytes for Downstream Device Index
78  * 4 bytes for Active Component Comparison Stamp
79  * 1 byte for Active Component Version String Type
80  * 1 byte for Active Component Version String Length
81  * 8 bytes for Active Component Release Date
82  * 4 bytes for Pending Component Comparison Stamp
83  * 1 byte for Pending Component Version String Type
84  * 1 byte for Pending Component Version String Length
85  * 8 bytes for Pending Component Release Date
86  * 2 bytes for Component Activation Methods
87  * 4 bytes for Capabilities During Update
88  */
89 #define PLDM_DOWNSTREAM_DEVICE_PARAMETER_ENTRY_MIN_LEN 36
90 
91 #define PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES 0
92 #define PLDM_FWUP_BASELINE_TRANSFER_SIZE       32
93 #define PLDM_FWUP_MIN_OUTSTANDING_REQ	       1
94 #define PLDM_GET_STATUS_REQ_BYTES	       0
95 /* Maximum progress percentage value*/
96 #define PLDM_FWUP_MAX_PROGRESS_PERCENT	       0x65
97 #define PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES 0
98 #define PLDM_CANCEL_UPDATE_REQ_BYTES	       0
99 
100 /** @brief PLDM component release data size in bytes defined in DSP0267_1.1.0
101  * Table 14 - ComponentParameterTable and Table 21 - ComponentParameterTable
102  *
103  * The size can be used in `ASCII[8] - ActiveComponentReleaseDate` and
104  * `ASCII[8] - PendingComponentReleaseDate` fields in the tables above.
105  */
106 #define PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN 8
107 
108 /** @brief PLDM Firmware update commands
109  */
110 enum pldm_firmware_update_commands {
111 	PLDM_QUERY_DEVICE_IDENTIFIERS = 0x01,
112 	PLDM_GET_FIRMWARE_PARAMETERS = 0x02,
113 	PLDM_QUERY_DOWNSTREAM_DEVICES = 0x03,
114 	PLDM_QUERY_DOWNSTREAM_IDENTIFIERS = 0x04,
115 	PLDM_QUERY_DOWNSTREAM_FIRMWARE_PARAMETERS = 0x05,
116 	PLDM_REQUEST_UPDATE = 0x10,
117 	PLDM_PASS_COMPONENT_TABLE = 0x13,
118 	PLDM_UPDATE_COMPONENT = 0x14,
119 	PLDM_REQUEST_FIRMWARE_DATA = 0x15,
120 	PLDM_TRANSFER_COMPLETE = 0x16,
121 	PLDM_VERIFY_COMPLETE = 0x17,
122 	PLDM_APPLY_COMPLETE = 0x18,
123 	PLDM_ACTIVATE_FIRMWARE = 0x1a,
124 	PLDM_GET_STATUS = 0x1b,
125 	PLDM_CANCEL_UPDATE_COMPONENT = 0x1c,
126 	PLDM_CANCEL_UPDATE = 0x1d
127 };
128 
129 /** @brief PLDM Firmware update completion codes
130  */
131 enum pldm_firmware_update_completion_codes {
132 	PLDM_FWUP_NOT_IN_UPDATE_MODE = 0x80,
133 	PLDM_FWUP_ALREADY_IN_UPDATE_MODE = 0x81,
134 	PLDM_FWUP_DATA_OUT_OF_RANGE = 0x82,
135 	PLDM_FWUP_INVALID_TRANSFER_LENGTH = 0x83,
136 	PLDM_FWUP_INVALID_STATE_FOR_COMMAND = 0x84,
137 	PLDM_FWUP_INCOMPLETE_UPDATE = 0x85,
138 	PLDM_FWUP_BUSY_IN_BACKGROUND = 0x86,
139 	PLDM_FWUP_CANCEL_PENDING = 0x87,
140 	PLDM_FWUP_COMMAND_NOT_EXPECTED = 0x88,
141 	PLDM_FWUP_RETRY_REQUEST_FW_DATA = 0x89,
142 	PLDM_FWUP_UNABLE_TO_INITIATE_UPDATE = 0x8a,
143 	PLDM_FWUP_ACTIVATION_NOT_REQUIRED = 0x8b,
144 	PLDM_FWUP_SELF_CONTAINED_ACTIVATION_NOT_PERMITTED = 0x8c,
145 	PLDM_FWUP_NO_DEVICE_METADATA = 0x8d,
146 	PLDM_FWUP_RETRY_REQUEST_UPDATE = 0x8e,
147 	PLDM_FWUP_NO_PACKAGE_DATA = 0x8f,
148 	PLDM_FWUP_INVALID_TRANSFER_HANDLE = 0x90,
149 	PLDM_FWUP_INVALID_TRANSFER_OPERATION_FLAG = 0x91,
150 	PLDM_FWUP_ACTIVATE_PENDING_IMAGE_NOT_PERMITTED = 0x92,
151 	PLDM_FWUP_PACKAGE_DATA_ERROR = 0x93
152 };
153 
154 /** @brief String type values defined in the PLDM firmware update specification
155  */
156 enum pldm_firmware_update_string_type {
157 	PLDM_STR_TYPE_UNKNOWN = 0,
158 	PLDM_STR_TYPE_ASCII = 1,
159 	PLDM_STR_TYPE_UTF_8 = 2,
160 	PLDM_STR_TYPE_UTF_16 = 3,
161 	PLDM_STR_TYPE_UTF_16LE = 4,
162 	PLDM_STR_TYPE_UTF_16BE = 5
163 };
164 
165 /** @brief Descriptor types defined in PLDM firmware update specification
166  */
167 enum pldm_firmware_update_descriptor_types {
168 	PLDM_FWUP_PCI_VENDOR_ID = 0x0000,
169 	PLDM_FWUP_IANA_ENTERPRISE_ID = 0x0001,
170 	PLDM_FWUP_UUID = 0x0002,
171 	PLDM_FWUP_PNP_VENDOR_ID = 0x0003,
172 	PLDM_FWUP_ACPI_VENDOR_ID = 0x0004,
173 	PLDM_FWUP_IEEE_ASSIGNED_COMPANY_ID = 0x0005,
174 	PLDM_FWUP_SCSI_VENDOR_ID = 0x0006,
175 	PLDM_FWUP_PCI_DEVICE_ID = 0x0100,
176 	PLDM_FWUP_PCI_SUBSYSTEM_VENDOR_ID = 0x0101,
177 	PLDM_FWUP_PCI_SUBSYSTEM_ID = 0x0102,
178 	PLDM_FWUP_PCI_REVISION_ID = 0x0103,
179 	PLDM_FWUP_PNP_PRODUCT_IDENTIFIER = 0x0104,
180 	PLDM_FWUP_ACPI_PRODUCT_IDENTIFIER = 0x0105,
181 	PLDM_FWUP_ASCII_MODEL_NUMBER_LONG_STRING = 0x0106,
182 	PLDM_FWUP_ASCII_MODEL_NUMBER_SHORT_STRING = 0x0107,
183 	PLDM_FWUP_SCSI_PRODUCT_ID = 0x0108,
184 	PLDM_FWUP_UBM_CONTROLLER_DEVICE_CODE = 0x0109,
185 	PLDM_FWUP_VENDOR_DEFINED = 0xffff
186 };
187 
188 /** @brief Descriptor types length defined in PLDM firmware update specification
189  */
190 enum pldm_firmware_update_descriptor_types_length {
191 	PLDM_FWUP_PCI_VENDOR_ID_LENGTH = 2,
192 	PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH = 4,
193 	PLDM_FWUP_UUID_LENGTH = 16,
194 	PLDM_FWUP_PNP_VENDOR_ID_LENGTH = 3,
195 	PLDM_FWUP_ACPI_VENDOR_ID_LENGTH = 4,
196 	PLDM_FWUP_IEEE_ASSIGNED_COMPANY_ID_LENGTH = 3,
197 	PLDM_FWUP_SCSI_VENDOR_ID_LENGTH = 8,
198 	PLDM_FWUP_PCI_DEVICE_ID_LENGTH = 2,
199 	PLDM_FWUP_PCI_SUBSYSTEM_VENDOR_ID_LENGTH = 2,
200 	PLDM_FWUP_PCI_SUBSYSTEM_ID_LENGTH = 2,
201 	PLDM_FWUP_PCI_REVISION_ID_LENGTH = 1,
202 	PLDM_FWUP_PNP_PRODUCT_IDENTIFIER_LENGTH = 4,
203 	PLDM_FWUP_ACPI_PRODUCT_IDENTIFIER_LENGTH = 4,
204 	PLDM_FWUP_ASCII_MODEL_NUMBER_LONG_STRING_LENGTH = 40,
205 	PLDM_FWUP_ASCII_MODEL_NUMBER_SHORT_STRING_LENGTH = 10,
206 	PLDM_FWUP_SCSI_PRODUCT_ID_LENGTH = 16,
207 	PLDM_FWUP_UBM_CONTROLLER_DEVICE_CODE_LENGTH = 4
208 };
209 
210 /** @brief ComponentClassification values defined in firmware update
211  *         specification
212  */
213 enum pldm_component_classification_values {
214 	PLDM_COMP_UNKNOWN = 0x0000,
215 	PLDM_COMP_OTHER = 0x0001,
216 	PLDM_COMP_DRIVER = 0x0002,
217 	PLDM_COMP_CONFIGURATION_SOFTWARE = 0x0003,
218 	PLDM_COMP_APPLICATION_SOFTWARE = 0x0004,
219 	PLDM_COMP_INSTRUMENTATION = 0x0005,
220 	PLDM_COMP_FIRMWARE_OR_BIOS = 0x0006,
221 	PLDM_COMP_DIAGNOSTIC_SOFTWARE = 0x0007,
222 	PLDM_COMP_OPERATING_SYSTEM = 0x0008,
223 	PLDM_COMP_MIDDLEWARE = 0x0009,
224 	PLDM_COMP_FIRMWARE = 0x000a,
225 	PLDM_COMP_BIOS_OR_FCODE = 0x000b,
226 	PLDM_COMP_SUPPORT_OR_SERVICEPACK = 0x000c,
227 	PLDM_COMP_SOFTWARE_BUNDLE = 0x000d,
228 	PLDM_COMP_DOWNSTREAM_DEVICE = 0xffff
229 };
230 
231 /** @brief ComponentActivationMethods is the bit position in the bitfield that
232  *         provides the capability of the FD for firmware activation. Multiple
233  *         activation methods can be supported.
234  */
235 enum pldm_comp_activation_methods {
236 	PLDM_ACTIVATION_AUTOMATIC = 0,
237 	PLDM_ACTIVATION_SELF_CONTAINED = 1,
238 	PLDM_ACTIVATION_MEDIUM_SPECIFIC_RESET = 2,
239 	PLDM_ACTIVATION_SYSTEM_REBOOT = 3,
240 	PLDM_ACTIVATION_DC_POWER_CYCLE = 4,
241 	PLDM_ACTIVATION_AC_POWER_CYCLE = 5,
242 	PLDM_SUPPORTS_ACTIVATE_PENDING_IMAGE = 6,
243 	PLDM_SUPPORTS_ACTIVATE_PENDING_IMAGE_SET = 7
244 };
245 
246 /** @brief ComponentResponse values in the response of PassComponentTable
247  */
248 enum pldm_component_responses {
249 	PLDM_CR_COMP_CAN_BE_UPDATED = 0,
250 	PLDM_CR_COMP_MAY_BE_UPDATEABLE = 1
251 };
252 
253 /** @brief ComponentResponseCode values in the response of PassComponentTable
254  */
255 enum pldm_component_response_codes {
256 	PLDM_CRC_COMP_CAN_BE_UPDATED = 0x00,
257 	PLDM_CRC_COMP_COMPARISON_STAMP_IDENTICAL = 0x01,
258 	PLDM_CRC_COMP_COMPARISON_STAMP_LOWER = 0x02,
259 	PLDM_CRC_INVALID_COMP_COMPARISON_STAMP = 0x03,
260 	PLDM_CRC_COMP_CONFLICT = 0x04,
261 	PLDM_CRC_COMP_PREREQUISITES_NOT_MET = 0x05,
262 	PLDM_CRC_COMP_NOT_SUPPORTED = 0x06,
263 	PLDM_CRC_COMP_SECURITY_RESTRICTIONS = 0x07,
264 	PLDM_CRC_INCOMPLETE_COMP_IMAGE_SET = 0x08,
265 	PLDM_CRC_ACTIVE_IMAGE_NOT_UPDATEABLE_SUBSEQUENTLY = 0x09,
266 	PLDM_CRC_COMP_VER_STR_IDENTICAL = 0x0a,
267 	PLDM_CRC_COMP_VER_STR_LOWER = 0x0b,
268 	PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MIN = 0xd0,
269 	PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MAX = 0xef
270 };
271 
272 /** @brief ComponentCompatibilityResponse values in the response of
273  *         UpdateComponent
274  */
275 enum pldm_component_compatibility_responses {
276 	PLDM_CCR_COMP_CAN_BE_UPDATED = 0,
277 	PLDM_CCR_COMP_CANNOT_BE_UPDATED = 1
278 };
279 
280 /** @brief ComponentCompatibilityResponse Code values in the response of
281  *         UpdateComponent
282  */
283 enum pldm_component_compatibility_response_codes {
284 	PLDM_CCRC_NO_RESPONSE_CODE = 0x00,
285 	PLDM_CCRC_COMP_COMPARISON_STAMP_IDENTICAL = 0x01,
286 	PLDM_CCRC_COMP_COMPARISON_STAMP_LOWER = 0x02,
287 	PLDM_CCRC_INVALID_COMP_COMPARISON_STAMP = 0x03,
288 	PLDM_CCRC_COMP_CONFLICT = 0x04,
289 	PLDM_CCRC_COMP_PREREQUISITES_NOT_MET = 0x05,
290 	PLDM_CCRC_COMP_NOT_SUPPORTED = 0x06,
291 	PLDM_CCRC_COMP_SECURITY_RESTRICTIONS = 0x07,
292 	PLDM_CCRC_INCOMPLETE_COMP_IMAGE_SET = 0x08,
293 	PLDM_CCRC_COMP_INFO_NO_MATCH = 0x09,
294 	PLDM_CCRC_COMP_VER_STR_IDENTICAL = 0x0a,
295 	PLDM_CCRC_COMP_VER_STR_LOWER = 0x0b,
296 	PLDM_CCRC_VENDOR_COMP_RESP_CODE_RANGE_MIN = 0xd0,
297 	PLDM_CCRC_VENDOR_COMP_RESP_CODE_RANGE_MAX = 0xef
298 };
299 
300 /** @brief Common error codes in TransferComplete, VerifyComplete and
301  *        ApplyComplete request
302  */
303 enum pldm_firmware_update_common_error_codes {
304 	PLDM_FWUP_TIME_OUT = 0x09,
305 	PLDM_FWUP_GENERIC_ERROR = 0x0a
306 };
307 
308 /** @brief TransferResult values in the request of TransferComplete
309  */
310 enum pldm_firmware_update_transfer_result_values {
311 	PLDM_FWUP_TRANSFER_SUCCESS = 0x00,
312 	PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT = 0x02,
313 	PLDM_FWUP_TRANSFER_ERROR_VERSION_MISMATCH = 0x02,
314 	PLDM_FWUP_FD_ABORTED_TRANSFER = 0x03,
315 	PLDM_FWUP_FD_ABORTED_TRANSFER_LOW_POWER_STATE = 0x0b,
316 	PLDM_FWUP_FD_ABORTED_TRANSFER_RESET_NEEDED = 0x0c,
317 	PLDM_FWUP_FD_ABORTED_TRANSFER_STORAGE_ISSUE = 0x0d,
318 	PLDM_FWUP_VENDOR_TRANSFER_RESULT_RANGE_MIN = 0x70,
319 	PLDM_FWUP_VENDOR_TRANSFER_RESULT_RANGE_MAX = 0x8f
320 };
321 
322 /**@brief VerifyResult values in the request of VerifyComplete
323  */
324 enum pldm_firmware_update_verify_result_values {
325 	PLDM_FWUP_VERIFY_SUCCESS = 0x00,
326 	PLDM_FWUP_VERIFY_ERROR_VERIFICATION_FAILURE = 0x01,
327 	PLDM_FWUP_VERIFY_ERROR_VERSION_MISMATCH = 0x02,
328 	PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS = 0x03,
329 	PLDM_FWUP_VERIFY_ERROR_IMAGE_INCOMPLETE = 0x04,
330 	PLDM_FWUP_VENDOR_VERIFY_RESULT_RANGE_MIN = 0x90,
331 	PLDM_FWUP_VENDOR_VERIFY_RESULT_RANGE_MAX = 0xaf
332 };
333 
334 /**@brief ApplyResult values in the request of ApplyComplete
335  */
336 enum pldm_firmware_update_apply_result_values {
337 	PLDM_FWUP_APPLY_SUCCESS = 0x00,
338 	PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD = 0x01,
339 	PLDM_FWUP_APPLY_FAILURE_MEMORY_ISSUE = 0x02,
340 	PLDM_FWUP_VENDOR_APPLY_RESULT_RANGE_MIN = 0xb0,
341 	PLDM_FWUP_VENDOR_APPLY_RESULT_RANGE_MAX = 0xcf
342 };
343 
344 /** @brief SelfContainedActivationRequest in the request of ActivateFirmware
345  */
346 enum pldm_self_contained_activation_req {
347 	PLDM_NOT_ACTIVATE_SELF_CONTAINED_COMPONENTS = false,
348 	PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS = true
349 };
350 
351 /** @brief Current state/previous state of the FD or FDP returned in GetStatus
352  *         response
353  */
354 enum pldm_firmware_device_states {
355 	PLDM_FD_STATE_IDLE = 0,
356 	PLDM_FD_STATE_LEARN_COMPONENTS = 1,
357 	PLDM_FD_STATE_READY_XFER = 2,
358 	PLDM_FD_STATE_DOWNLOAD = 3,
359 	PLDM_FD_STATE_VERIFY = 4,
360 	PLDM_FD_STATE_APPLY = 5,
361 	PLDM_FD_STATE_ACTIVATE = 6
362 };
363 
364 /** @brief Firmware device aux state in GetStatus response
365  */
366 enum pldm_get_status_aux_states {
367 	PLDM_FD_OPERATION_IN_PROGRESS = 0,
368 	PLDM_FD_OPERATION_SUCCESSFUL = 1,
369 	PLDM_FD_OPERATION_FAILED = 2,
370 	PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER = 3
371 };
372 
373 /** @brief Firmware device aux state status in GetStatus response
374  */
375 enum pldm_get_status_aux_state_status_values {
376 	PLDM_FD_AUX_STATE_IN_PROGRESS_OR_SUCCESS = 0x00,
377 	PLDM_FD_TIMEOUT = 0x09,
378 	PLDM_FD_GENERIC_ERROR = 0x0a,
379 	PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START = 0x70,
380 	PLDM_FD_VENDOR_DEFINED_STATUS_CODE_END = 0xef
381 };
382 
383 /** @brief Firmware device reason code in GetStatus response
384  */
385 enum pldm_get_status_reason_code_values {
386 	PLDM_FD_INITIALIZATION = 0,
387 	PLDM_FD_ACTIVATE_FW = 1,
388 	PLDM_FD_CANCEL_UPDATE = 2,
389 	PLDM_FD_TIMEOUT_LEARN_COMPONENT = 3,
390 	PLDM_FD_TIMEOUT_READY_XFER = 4,
391 	PLDM_FD_TIMEOUT_DOWNLOAD = 5,
392 	PLDM_FD_TIMEOUT_VERIFY = 6,
393 	PLDM_FD_TIMEOUT_APPLY = 7,
394 	PLDM_FD_STATUS_VENDOR_DEFINED_MIN = 200,
395 	PLDM_FD_STATUS_VENDOR_DEFINED_MAX = 255
396 };
397 
398 /** @brief Components functional indicator in CancelUpdate response
399  */
400 enum pldm_firmware_update_non_functioning_component_indication {
401 	PLDM_FWUP_COMPONENTS_FUNCTIONING = 0,
402 	PLDM_FWUP_COMPONENTS_NOT_FUNCTIONING = 1
403 };
404 
405 /** @brief Downstream device update supported in QueryDownstreamDevices response
406  *         defined in DSP0267_1.1.0
407 */
408 enum pldm_firmware_update_downstream_device_update_supported {
409 	PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_NOT_SUPPORTED = 0,
410 	PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED = 1
411 };
412 
413 /** @struct pldm_package_header_information
414  *
415  *  Structure representing fixed part of package header information
416  */
417 struct pldm_package_header_information {
418 	uint8_t uuid[PLDM_FWUP_UUID_LENGTH];
419 	uint8_t package_header_format_version;
420 	uint16_t package_header_size;
421 	uint8_t package_release_date_time[PLDM_TIMESTAMP104_SIZE];
422 	uint16_t component_bitmap_bit_length;
423 	uint8_t package_version_string_type;
424 	uint8_t package_version_string_length;
425 } __attribute__((packed));
426 
427 /** @struct pldm_firmware_device_id_record
428  *
429  *  Structure representing firmware device ID record
430  */
431 struct pldm_firmware_device_id_record {
432 	uint16_t record_length;
433 	uint8_t descriptor_count;
434 	bitfield32_t device_update_option_flags;
435 	uint8_t comp_image_set_version_string_type;
436 	uint8_t comp_image_set_version_string_length;
437 	uint16_t fw_device_pkg_data_length;
438 } __attribute__((packed));
439 
440 /** @struct pldm_descriptor_tlv
441  *
442  *  Structure representing descriptor type, length and value
443  */
444 struct pldm_descriptor_tlv {
445 	uint16_t descriptor_type;
446 	uint16_t descriptor_length;
447 	uint8_t descriptor_data[1];
448 } __attribute__((packed));
449 
450 /** @struct pldm_vendor_defined_descriptor_title_data
451  *
452  *  Structure representing vendor defined descriptor title sections
453  */
454 struct pldm_vendor_defined_descriptor_title_data {
455 	uint8_t vendor_defined_descriptor_title_str_type;
456 	uint8_t vendor_defined_descriptor_title_str_len;
457 	uint8_t vendor_defined_descriptor_title_str[1];
458 } __attribute__((packed));
459 
460 /** @struct pldm_component_image_information
461  *
462  *  Structure representing fixed part of individual component information in
463  *  PLDM firmware update package
464  */
465 struct pldm_component_image_information {
466 	uint16_t comp_classification;
467 	uint16_t comp_identifier;
468 	uint32_t comp_comparison_stamp;
469 	bitfield16_t comp_options;
470 	bitfield16_t requested_comp_activation_method;
471 	uint32_t comp_location_offset;
472 	uint32_t comp_size;
473 	uint8_t comp_version_string_type;
474 	uint8_t comp_version_string_length;
475 } __attribute__((packed));
476 
477 /** @struct pldm_query_device_identifiers_resp
478  *
479  *  Structure representing query device identifiers response.
480  */
481 struct pldm_query_device_identifiers_resp {
482 	uint8_t completion_code;
483 	uint32_t device_identifiers_len;
484 	uint8_t descriptor_count;
485 } __attribute__((packed));
486 
487 /** @struct pldm_get_firmware_parameters_resp
488  *
489  *  Structure representing the fixed part of GetFirmwareParameters response
490  */
491 struct pldm_get_firmware_parameters_resp {
492 	uint8_t completion_code;
493 	bitfield32_t capabilities_during_update;
494 	uint16_t comp_count;
495 	uint8_t active_comp_image_set_ver_str_type;
496 	uint8_t active_comp_image_set_ver_str_len;
497 	uint8_t pending_comp_image_set_ver_str_type;
498 	uint8_t pending_comp_image_set_ver_str_len;
499 } __attribute__((packed));
500 
501 /** @struct pldm_query_downstream_devices_resp
502  *
503  *  Structure representing response of QueryDownstreamDevices.
504  *  The definition can be found Table 15 - QueryDownstreamDevices command format
505  *  in DSP0267_1.1.0
506  */
507 struct pldm_query_downstream_devices_resp {
508 	uint8_t completion_code;
509 	uint8_t downstream_device_update_supported;
510 	uint16_t number_of_downstream_devices;
511 	uint16_t max_number_of_downstream_devices;
512 	bitfield32_t capabilities;
513 };
514 
515 /** @struct pldm_component_parameter_entry
516  *
517  *  Structure representing component parameter table entry.
518  */
519 struct pldm_component_parameter_entry {
520 	uint16_t comp_classification;
521 	uint16_t comp_identifier;
522 	uint8_t comp_classification_index;
523 	uint32_t active_comp_comparison_stamp;
524 	uint8_t active_comp_ver_str_type;
525 	uint8_t active_comp_ver_str_len;
526 	uint8_t active_comp_release_date[8];
527 	uint32_t pending_comp_comparison_stamp;
528 	uint8_t pending_comp_ver_str_type;
529 	uint8_t pending_comp_ver_str_len;
530 	uint8_t pending_comp_release_date[8];
531 	bitfield16_t comp_activation_methods;
532 	bitfield32_t capabilities_during_update;
533 } __attribute__((packed));
534 
535 /** @struct pldm_query_downstream_identifiers_req
536  *
537  *  Structure for QueryDownstreamIdentifiers request defined in Table 16 -
538  *  QueryDownstreamIdentifiers command format in DSP0267_1.1.0
539  */
540 struct pldm_query_downstream_identifiers_req {
541 	uint32_t data_transfer_handle;
542 	uint8_t transfer_operation_flag;
543 };
544 
545 /** @struct pldm_query_downstream_identifiers_resp
546  *
547  *  Structure representing the fixed part of QueryDownstreamIdentifiers response
548  *  defined in Table 16 - QueryDownstreamIdentifiers command format, and
549  *  Table 17 - QueryDownstreamIdentifiers response definition in DSP0267_1.1.0.
550  *
551  *  Squash the two tables into one since the definition of
552  *  Table 17 is `Portion of QueryDownstreamIdentifiers response`
553  */
554 struct pldm_query_downstream_identifiers_resp {
555 	uint8_t completion_code;
556 	uint32_t next_data_transfer_handle;
557 	uint8_t transfer_flag;
558 	uint32_t downstream_devices_length;
559 	uint16_t number_of_downstream_devices;
560 };
561 
562 /** @struct pldm_downstream_device
563  *
564  *  Structure representing downstream device information defined in
565  *  Table 18 - DownstreamDevice definition in DSP0267_1.1.0
566  */
567 struct pldm_downstream_device {
568 	uint16_t downstream_device_index;
569 	uint8_t downstream_descriptor_count;
570 };
571 
572 /** @struct pldm_query_downstream_firmware_param_req
573  *
574  *  Structure representing QueryDownstreamFirmwareParameters request
575  */
576 struct pldm_get_downstream_firmware_params_req {
577 	uint32_t data_transfer_handle;
578 	uint8_t transfer_operation_flag;
579 };
580 
581 /** @struct pldm_query_downstream_firmware_param_resp
582  *
583  *  Structure representing the fixed part of QueryDownstreamFirmwareParameters
584  *  response in Table 19 - GetDownstreamFirmwareParameters command format, and
585  *  Table 20 - QueryDownstreamFirmwareParameters response definition in
586  *  DSP0267_1.1.0.
587  *
588  *  Squash the two tables into one since the definition of Table 20 is `Portion
589  *  of GetDownstreamFirmwareParameters response`
590  */
591 struct pldm_get_downstream_firmware_params_resp {
592 	uint8_t completion_code;
593 	uint32_t next_data_transfer_handle;
594 	uint8_t transfer_flag;
595 	bitfield32_t fdp_capabilities_during_update;
596 	uint16_t downstream_device_count;
597 };
598 
599 /** @struct pldm_downstream_device_parameter_entry
600  *
601  *  Structure representing downstream device parameter table entry defined in
602  *  Table 21 - DownstreamDeviceParameterTable in DSP0267_1.1.0
603  *
604  *  Clients should not allocate memory for this struct to decode the response,
605  *  use `pldm_downstream_device_parameter_entry_versions` instead to make sure
606  *  that the active and pending component version strings are copied from the
607  *  message buffer.
608  */
609 struct pldm_downstream_device_parameter_entry {
610 	uint16_t downstream_device_index;
611 	uint32_t active_comp_comparison_stamp;
612 	uint8_t active_comp_ver_str_type;
613 	uint8_t active_comp_ver_str_len;
614 	/* Append 1 bytes for null termination so that it can be used as a
615 	 * Null-terminated string.
616 	 */
617 	char active_comp_release_date[PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN + 1];
618 	uint32_t pending_comp_comparison_stamp;
619 	uint8_t pending_comp_ver_str_type;
620 	uint8_t pending_comp_ver_str_len;
621 	/* Append 1 bytes for null termination so that it can be used as a
622 	 * Null-terminated string.
623 	 */
624 	char pending_comp_release_date[PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN + 1];
625 	bitfield16_t comp_activation_methods;
626 	bitfield32_t capabilities_during_update;
627 	const char *active_comp_ver_str;
628 	const char *pending_comp_ver_str;
629 };
630 
631 /** @struct pldm_downstream_device_parameter_entry_versions
632  *
633  *  Structure representing downstream device parameter table entry with
634  *  copies of active and pending component version strings to avoid the
635  *  message buffer is subsequently freed.
636  *
637  *  Clients should allocate memory for this struct then decode the response
638  *  instead of using `pldm_downstream_device_parameter_entry`.
639  */
640 struct pldm_downstream_device_parameter_entry_versions {
641 	struct pldm_downstream_device_parameter_entry entry;
642 	/* The "Length of ComponentVersionString" field is 1 byte, so
643 	 * "ComponentVersionString" can be at most 255 characters, allocate
644 	 * memory for it and append 1 bytes for null termination so that it
645 	 * can be used as a Null-terminated string.
646 	 */
647 	char active_comp_ver_str[UINT8_MAX + 1];
648 	char pending_comp_ver_str[UINT8_MAX + 1];
649 };
650 
651 /** @struct pldm_request_update_req
652  *
653  *  Structure representing fixed part of Request Update request
654  */
655 struct pldm_request_update_req {
656 	uint32_t max_transfer_size;
657 	uint16_t num_of_comp;
658 	uint8_t max_outstanding_transfer_req;
659 	uint16_t pkg_data_len;
660 	uint8_t comp_image_set_ver_str_type;
661 	uint8_t comp_image_set_ver_str_len;
662 } __attribute__((packed));
663 
664 /** @struct pldm_request_update_resp
665  *
666  *  Structure representing Request Update response
667  */
668 struct pldm_request_update_resp {
669 	uint8_t completion_code;
670 	uint16_t fd_meta_data_len;
671 	uint8_t fd_will_send_pkg_data;
672 } __attribute__((packed));
673 
674 /** @struct pldm_pass_component_table_req
675  *
676  *  Structure representing PassComponentTable request
677  */
678 struct pldm_pass_component_table_req {
679 	uint8_t transfer_flag;
680 	uint16_t comp_classification;
681 	uint16_t comp_identifier;
682 	uint8_t comp_classification_index;
683 	uint32_t comp_comparison_stamp;
684 	uint8_t comp_ver_str_type;
685 	uint8_t comp_ver_str_len;
686 } __attribute__((packed));
687 
688 /** @struct pldm_pass_component_table_resp
689  *
690  *  Structure representing PassComponentTable response
691  */
692 struct pldm_pass_component_table_resp {
693 	uint8_t completion_code;
694 	uint8_t comp_resp;
695 	uint8_t comp_resp_code;
696 } __attribute__((packed));
697 
698 /** @struct pldm_update_component_req
699  *
700  *  Structure representing UpdateComponent request
701  */
702 struct pldm_update_component_req {
703 	uint16_t comp_classification;
704 	uint16_t comp_identifier;
705 	uint8_t comp_classification_index;
706 	uint32_t comp_comparison_stamp;
707 	uint32_t comp_image_size;
708 	bitfield32_t update_option_flags;
709 	uint8_t comp_ver_str_type;
710 	uint8_t comp_ver_str_len;
711 } __attribute__((packed));
712 
713 /** @struct pldm_update_component_resp
714  *
715  *  Structure representing UpdateComponent response
716  */
717 struct pldm_update_component_resp {
718 	uint8_t completion_code;
719 	uint8_t comp_compatibility_resp;
720 	uint8_t comp_compatibility_resp_code;
721 	bitfield32_t update_option_flags_enabled;
722 	uint16_t time_before_req_fw_data;
723 } __attribute__((packed));
724 
725 /** @struct pldm_request_firmware_data_req
726  *
727  *  Structure representing RequestFirmwareData request.
728  */
729 struct pldm_request_firmware_data_req {
730 	uint32_t offset;
731 	uint32_t length;
732 } __attribute__((packed));
733 
734 /** @struct pldm_apply_complete_req
735  *
736  *  Structure representing ApplyComplete request.
737  */
738 struct pldm_apply_complete_req {
739 	uint8_t apply_result;
740 	bitfield16_t comp_activation_methods_modification;
741 } __attribute__((packed));
742 
743 /** @struct pldm_activate_firmware_req
744  *
745  *  Structure representing ActivateFirmware request
746  */
747 struct pldm_activate_firmware_req {
748 	bool8_t self_contained_activation_req;
749 } __attribute__((packed));
750 
751 /** @struct activate_firmware_resp
752  *
753  *  Structure representing Activate Firmware response
754  */
755 struct pldm_activate_firmware_resp {
756 	uint8_t completion_code;
757 	uint16_t estimated_time_activation;
758 } __attribute__((packed));
759 
760 /** @struct pldm_get_status_resp
761  *
762  *  Structure representing GetStatus response.
763  */
764 struct pldm_get_status_resp {
765 	uint8_t completion_code;
766 	uint8_t current_state;
767 	uint8_t previous_state;
768 	uint8_t aux_state;
769 	uint8_t aux_state_status;
770 	uint8_t progress_percent;
771 	uint8_t reason_code;
772 	bitfield32_t update_option_flags_enabled;
773 } __attribute__((packed));
774 
775 /** @struct pldm_cancel_update_resp
776  *
777  *  Structure representing CancelUpdate response.
778  */
779 struct pldm_cancel_update_resp {
780 	uint8_t completion_code;
781 	bool8_t non_functioning_component_indication;
782 	uint64_t non_functioning_component_bitmap;
783 } __attribute__((packed));
784 
785 /** @brief Decode the PLDM package header information
786  *
787  *  @param[in] data - pointer to package header information
788  *  @param[in] length - available length in the firmware update package
789  *  @param[out] package_header_info - pointer to fixed part of PLDM package
790  *                                    header information
791  *  @param[out] package_version_str - pointer to package version string
792  *
793  *  @return pldm_completion_codes
794  */
795 int decode_pldm_package_header_info(
796 	const uint8_t *data, size_t length,
797 	struct pldm_package_header_information *package_header_info,
798 	struct variable_field *package_version_str);
799 
800 /** @brief Decode individual firmware device ID record
801  *
802  *  @param[in] data - pointer to firmware device ID record
803  *  @param[in] length - available length in the firmware update package
804  *  @param[in] component_bitmap_bit_length - ComponentBitmapBitLengthfield
805  *                                           parsed from the package header info
806  *  @param[out] fw_device_id_record - pointer to fixed part of firmware device
807  *                                    id record
808  *  @param[out] applicable_components - pointer to ApplicableComponents
809  *  @param[out] comp_image_set_version_str - pointer to
810  *                                           ComponentImageSetVersionString
811  *  @param[out] record_descriptors - pointer to RecordDescriptors
812  *  @param[out] fw_device_pkg_data - pointer to FirmwareDevicePackageData
813  *
814  *  @return pldm_completion_codes
815  */
816 int decode_firmware_device_id_record(
817 	const uint8_t *data, size_t length,
818 	uint16_t component_bitmap_bit_length,
819 	struct pldm_firmware_device_id_record *fw_device_id_record,
820 	struct variable_field *applicable_components,
821 	struct variable_field *comp_image_set_version_str,
822 	struct variable_field *record_descriptors,
823 	struct variable_field *fw_device_pkg_data);
824 
825 /** @brief Decode the record descriptor entries in the firmware update package
826  *         and the Descriptors in the QueryDeviceIDentifiers command
827  *
828  *  @param[in] data - pointer to descriptor entry
829  *  @param[in] length - remaining length of the descriptor data
830  *  @param[out] descriptor_type - pointer to descriptor type
831  *  @param[out] descriptor_data - pointer to descriptor data
832  *
833  *  @return pldm_completion_codes
834  */
835 int decode_descriptor_type_length_value(const uint8_t *data, size_t length,
836 					uint16_t *descriptor_type,
837 					struct variable_field *descriptor_data);
838 
839 /** @brief Decode the vendor defined descriptor value
840  *
841  *  @param[in] data - pointer to vendor defined descriptor value
842  *  @param[in] length - length of the vendor defined descriptor value
843  *  @param[out] descriptor_title_str_type - pointer to vendor defined descriptor
844  *                                          title string type
845  *  @param[out] descriptor_title_str - pointer to vendor defined descriptor
846  *                                     title string
847  *  @param[out] descriptor_data - pointer to vendor defined descriptor data
848  *
849  *  @return pldm_completion_codes
850  */
851 int decode_vendor_defined_descriptor_value(
852 	const uint8_t *data, size_t length, uint8_t *descriptor_title_str_type,
853 	struct variable_field *descriptor_title_str,
854 	struct variable_field *descriptor_data);
855 
856 /** @brief Decode individual component image information
857  *
858  *  @param[in] data - pointer to component image information
859  *  @param[in] length - available length in the firmware update package
860  *  @param[out] pldm_comp_image_info - pointer to fixed part of component image
861  *                                     information
862  *  @param[out] comp_version_str - pointer to component version string
863  *
864  *  @return pldm_completion_codes
865  */
866 int decode_pldm_comp_image_info(
867 	const uint8_t *data, size_t length,
868 	struct pldm_component_image_information *pldm_comp_image_info,
869 	struct variable_field *comp_version_str);
870 
871 /** @brief Create a PLDM request message for QueryDeviceIdentifiers
872  *
873  *  @param[in] instance_id - Message's instance id
874  *  @param[in] payload_length - Length of the request message payload
875  *  @param[in,out] msg - Message will be written to this
876  *
877  *  @return pldm_completion_codes
878  *
879  *  @note  Caller is responsible for memory alloc and dealloc of param
880  *         'msg.payload'
881  */
882 int encode_query_device_identifiers_req(uint8_t instance_id,
883 					size_t payload_length,
884 					struct pldm_msg *msg);
885 
886 /** @brief Decode QueryDeviceIdentifiers response message
887  *
888  *  @param[in] msg - Response message
889  *  @param[in] payload_length - Length of response message payload
890  *  @param[out] completion_code - Pointer to response msg's PLDM completion code
891  *  @param[out] device_identifiers_len - Pointer to device identifiers length
892  *  @param[out] descriptor_count - Pointer to descriptor count
893  *  @param[out] descriptor_data - Pointer to descriptor data
894  *
895  *  @return pldm_completion_codes
896  */
897 int decode_query_device_identifiers_resp(const struct pldm_msg *msg,
898 					 size_t payload_length,
899 					 uint8_t *completion_code,
900 					 uint32_t *device_identifiers_len,
901 					 uint8_t *descriptor_count,
902 					 uint8_t **descriptor_data);
903 
904 /** @brief Create a PLDM request message for GetFirmwareParameters
905  *
906  *  @param[in] instance_id - Message's instance id
907  *  @param[in] payload_length - Length of the request message payload
908  *  @param[in,out] msg - Message will be written to this
909  *
910  *  @return pldm_completion_codes
911  *
912  *  @note  Caller is responsible for memory alloc and dealloc of param
913  *         'msg.payload'
914  */
915 int encode_get_firmware_parameters_req(uint8_t instance_id,
916 				       size_t payload_length,
917 				       struct pldm_msg *msg);
918 
919 /** @brief Decode GetFirmwareParameters response
920  *
921  *  @param[in] msg - Response message
922  *  @param[in] payload_length - Length of response message payload
923  *  @param[out] resp_data - Pointer to get firmware parameters response
924  *  @param[out] active_comp_image_set_ver_str - Pointer to active component
925  *                                              image set version string
926  *  @param[out] pending_comp_image_set_ver_str - Pointer to pending component
927  *                                               image set version string
928  *  @param[out] comp_parameter_table - Pointer to component parameter table
929  *
930  *  @return pldm_completion_codes
931  */
932 int decode_get_firmware_parameters_resp(
933 	const struct pldm_msg *msg, size_t payload_length,
934 	struct pldm_get_firmware_parameters_resp *resp_data,
935 	struct variable_field *active_comp_image_set_ver_str,
936 	struct variable_field *pending_comp_image_set_ver_str,
937 	struct variable_field *comp_parameter_table);
938 
939 /** @brief Decode component entries in the component parameter table which is
940  *         part of the response of GetFirmwareParameters command
941  *
942  *  @param[in] data - Component entry
943  *  @param[in] length - Length of component entry
944  *  @param[out] component_data - Pointer to component parameter table
945  *  @param[out] active_comp_ver_str - Pointer to active component version string
946  *  @param[out] pending_comp_ver_str - Pointer to pending component version
947  *                                     string
948  *
949  *  @return pldm_completion_codes
950  */
951 int decode_get_firmware_parameters_resp_comp_entry(
952 	const uint8_t *data, size_t length,
953 	struct pldm_component_parameter_entry *component_data,
954 	struct variable_field *active_comp_ver_str,
955 	struct variable_field *pending_comp_ver_str);
956 
957 /** @brief Create a PLDM request message for QueryDownstreamDevices
958  *
959  *  @param[in] instance_id - Message's instance id
960  *  @param[out] msg - Message will be written to this
961  *
962  *  @return pldm_completion_codes
963  *
964  *  @note  Caller is responsible for memory alloc and dealloc of param
965  *         'msg.payload'
966  */
967 int encode_query_downstream_devices_req(uint8_t instance_id,
968 					struct pldm_msg *msg);
969 
970 /**
971  * @brief Decodes the response message for Querying Downstream Devices.
972  *
973  * @param[in] msg The PLDM message to decode.
974  * @param[in] payload_length The length of the message payload.
975  * @param[out] resp_data Pointer to the structure to store the decoded response data.
976  * @return pldm_completion_codes
977  *
978  * @note  Caller is responsible for memory alloc and dealloc of param
979  *         'msg.payload'
980  */
981 int decode_query_downstream_devices_resp(
982 	const struct pldm_msg *msg, size_t payload_length,
983 	struct pldm_query_downstream_devices_resp *resp_data);
984 
985 /**
986  * @brief Encodes a request message for Query Downstream Identifiers.
987  *
988  * @param[in] instance_id The instance ID of the PLDM entity.
989  * @param[in] data_transfer_handle The handle for the data transfer.
990  * @param[in] transfer_operation_flag The flag indicating the transfer operation.
991  * @param[out] msg Pointer to the PLDM message structure to store the encoded message.
992  * @param[in] payload_length The length of the payload.
993  * @return pldm_completion_codes
994  *
995  * @note Caller is responsible for memory alloc and dealloc of param
996  *        'msg.payload'
997  */
998 int encode_query_downstream_identifiers_req(
999 	uint8_t instance_id, uint32_t data_transfer_handle,
1000 	enum transfer_op_flag transfer_operation_flag, struct pldm_msg *msg,
1001 	size_t payload_length);
1002 
1003 /**
1004  * @brief Decodes the response message for Querying Downstream Identifiers.
1005  * @param[in] msg The PLDM message to decode.
1006  * @param[in] payload_length The length of the message payload.
1007  * @param[out] resp_data Pointer to the decoded response data.
1008  * @param[out] downstream_devices Pointer to the downstream devices.
1009  * @return pldm_completion_codes
1010  *
1011  * @note Caller is responsible for memory alloc and dealloc of pointer params
1012  */
1013 int decode_query_downstream_identifiers_resp(
1014 	const struct pldm_msg *msg, size_t payload_length,
1015 	struct pldm_query_downstream_identifiers_resp *resp_data,
1016 	struct variable_field *downstream_devices);
1017 
1018 /**
1019  * @brief Encodes request message for Get Downstream Firmware Parameters.
1020  *
1021  * @param[in] instance_id - The instance ID of the PLDM entity.
1022  * @param[in] data_transfer_handle - The handle for the data transfer.
1023  * @param[in] transfer_operation_flag - The flag indicating the transfer operation.
1024  * @param[in,out] msg - A pointer to the PLDM message structure to store the encoded message.
1025  * @param[in] payload_length - The length of the payload.
1026  *
1027  * @return 0 on success, otherwise -EINVAL if the input parameters' memory
1028  *         are not allocated, -EOVERFLOW if the payload length is not enough
1029  *         to encode the message, -EBADMSG if the message is not valid.
1030  *
1031  * @note Caller is responsible for memory alloc and dealloc of param
1032  *        'msg.payload'
1033  */
1034 int encode_get_downstream_firmware_params_req(
1035 	uint8_t instance_id, uint32_t data_transfer_handle,
1036 	enum transfer_op_flag transfer_operation_flag, struct pldm_msg *msg,
1037 	size_t payload_length);
1038 
1039 /**
1040  * @brief Decode response message for Get Downstream Firmware Parameters
1041  *
1042  * @param[in] msg - The PLDM message to decode
1043  * @param[in] payload_length - The length of the message payload
1044  * @param[out] resp_data - Pointer to the structure to store the decoded response data
1045  * @param[out] downstream_device_param_table - Pointer to the variable field structure
1046  *                                           to store the decoded downstream device
1047  *                                           parameter table
1048  * @return 0 on success, otherwise -EINVAL if the input parameters' memory
1049  *         are not allocated, -EOVERFLOW if the payload length is not enough
1050  *         to decode the message, -EBADMSG if the message is not valid.
1051  *
1052  * @note Caller is responsible for memory alloc and dealloc of param
1053  *        'resp_data' and 'downstream_device_param_table'
1054  */
1055 int decode_get_downstream_firmware_params_resp(
1056 	const struct pldm_msg *msg, size_t payload_length,
1057 	struct pldm_get_downstream_firmware_params_resp *resp_data,
1058 	struct variable_field *downstream_device_param_table);
1059 
1060 /**
1061  * @brief Decode the next downstream device parameter table entry
1062  *
1063  * @param[in,out] data - A variable field covering the table entries in the
1064  *                       response message data. @p data is updated to point to
1065  *                       the remaining entries once the current entry has been
1066  *                       decoded.
1067 
1068  * @param[out] entry - The struct object into which the current table entry will
1069  *                     be decoded
1070 
1071  * @param[out] versions - A variable field covering the active and
1072  *                        pending component version strings in the
1073  *                        response message data. The component version
1074  *                        strings can be decoded into @p entry using
1075  *                        decode_downstream_device_parameter_table_entry_versions()
1076  *
1077  * @return 0 on success, otherwise -EINVAL if the input parameters' memory
1078  *         are not allocated, -EOVERFLOW if the payload length is not enough
1079  *         to decode the entry.
1080  *
1081  * @note Caller is responsible for memory alloc and dealloc of param
1082  * 	  'entry', 'active_comp_ver_str' and 'pending_comp_ver_str'
1083  */
1084 int decode_downstream_device_parameter_table_entry(
1085 	struct variable_field *data,
1086 	struct pldm_downstream_device_parameter_entry *entry,
1087 	struct variable_field *versions);
1088 
1089 /**
1090  * @brief Decode the downstream device parameter table entry versions
1091  *
1092  * @param[in] versions - pointer to version strings raw data
1093  * @param[in,out] entry - pointer to the decoded downstream device parameter table entry
1094  * @param[out] active - pointer to active component version string, the object pointed-to
1095  *                      must be at least as large as `entry->active_comp_ver_str_len + 1`
1096  * @param[out] pending - pointer to pending component version string, the object pointed-to
1097  *                      must be at least as large as `entry->pending_comp_ver_str_len + 1`
1098  *
1099  * @note Caller is responsible for memory alloc and dealloc of all the params,
1100  *    and the param `entry` should be the instance which has successfully decoded
1101  *    by `decode_downstream_device_parameter_table_entry()`.
1102  *
1103  */
1104 int decode_downstream_device_parameter_table_entry_versions(
1105 	const struct variable_field *versions,
1106 	struct pldm_downstream_device_parameter_entry *entry, char *active,
1107 	char *pending);
1108 
1109 /** @brief Create PLDM request message for RequestUpdate
1110  *
1111  *  @param[in] instance_id - Message's instance id
1112  *  @param[in] max_transfer_size - Maximum size of the variable payload allowed
1113  *                                 to be requested via RequestFirmwareData
1114  *                                 command
1115  *  @param[in] num_of_comp - Total number of components that will be passed to
1116  *                           the FD during the update
1117  *  @param[in] max_outstanding_transfer_req - Total number of outstanding
1118  * 											  RequestFirmwareData
1119  * commands that can be sent by the FD
1120  *  @param[in] pkg_data_len - Value of the FirmwareDevicePackageDataLength field
1121  *                            present in firmware package header
1122  *  @param[in] comp_image_set_ver_str_type - StringType of
1123  *                                           ComponentImageSetVersionString
1124  *  @param[in] comp_image_set_ver_str_len - The length of the
1125  *                                          ComponentImageSetVersionString
1126  *  @param[in] comp_img_set_ver_str - Component Image Set version information
1127  *  @param[in,out] msg - Message will be written to this
1128  *  @param[in] payload_length - Length of request message payload
1129  *
1130  *  @return pldm_completion_codes
1131  *
1132  *  @note Caller is responsible for memory alloc and dealloc of param
1133  *        'msg.payload'
1134  */
1135 int encode_request_update_req(uint8_t instance_id, uint32_t max_transfer_size,
1136 			      uint16_t num_of_comp,
1137 			      uint8_t max_outstanding_transfer_req,
1138 			      uint16_t pkg_data_len,
1139 			      uint8_t comp_image_set_ver_str_type,
1140 			      uint8_t comp_image_set_ver_str_len,
1141 			      const struct variable_field *comp_img_set_ver_str,
1142 			      struct pldm_msg *msg, size_t payload_length);
1143 
1144 /** @brief Decode a RequestUpdate response message
1145  *
1146  *  @param[in] msg - Response message
1147  *  @param[in] payload_length - Length of response message payload
1148  *  @param[out] completion_code - Pointer to hold the completion code
1149  *  @param[out] fd_meta_data_len - Pointer to hold the length of FD metadata
1150  *  @param[out] fd_will_send_pkg_data - Pointer to hold information whether FD
1151  *                                      will send GetPackageData command
1152  *  @return pldm_completion_codes
1153  */
1154 int decode_request_update_resp(const struct pldm_msg *msg,
1155 			       size_t payload_length, uint8_t *completion_code,
1156 			       uint16_t *fd_meta_data_len,
1157 			       uint8_t *fd_will_send_pkg_data);
1158 
1159 /** @brief Create PLDM request message for PassComponentTable
1160  *
1161  *  @param[in] instance_id - Message's instance id
1162  *  @param[in] transfer_flag - TransferFlag
1163  *  @param[in] comp_classification - ComponentClassification
1164  *  @param[in] comp_identifier - ComponentIdentifier
1165  *  @param[in] comp_classification_index - ComponentClassificationIndex
1166  *  @param[in] comp_comparison_stamp - ComponentComparisonStamp
1167  *  @param[in] comp_ver_str_type - ComponentVersionStringType
1168  *  @param[in] comp_ver_str_len - ComponentVersionStringLength
1169  *  @param[in] comp_ver_str - ComponentVersionString
1170  *  @param[in,out] msg - Message will be written to this
1171  *  @param[in] payload_length - Length of request message payload
1172  *                              information
1173  *
1174  *  @return pldm_completion_codes
1175  *
1176  *  @note  Caller is responsible for memory alloc and dealloc of param
1177  *         'msg.payload'
1178  */
1179 int encode_pass_component_table_req(
1180 	uint8_t instance_id, uint8_t transfer_flag,
1181 	uint16_t comp_classification, uint16_t comp_identifier,
1182 	uint8_t comp_classification_index, uint32_t comp_comparison_stamp,
1183 	uint8_t comp_ver_str_type, uint8_t comp_ver_str_len,
1184 	const struct variable_field *comp_ver_str, struct pldm_msg *msg,
1185 	size_t payload_length);
1186 
1187 /** @brief Decode PassComponentTable response message
1188  *
1189  *  @param[in] msg - Response message
1190  *  @param[in] payload_length - Length of response message payload
1191  *  @param[out] completion_code - Pointer to hold completion code
1192  *  @param[out] comp_resp - Pointer to hold component response
1193  *  @param[out] comp_resp_code - Pointer to hold component response code
1194  *
1195  *  @return pldm_completion_codes
1196  */
1197 int decode_pass_component_table_resp(const struct pldm_msg *msg,
1198 				     size_t payload_length,
1199 				     uint8_t *completion_code,
1200 				     uint8_t *comp_resp,
1201 				     uint8_t *comp_resp_code);
1202 
1203 /** @brief Create PLDM request message for UpdateComponent
1204  *
1205  *  @param[in] instance_id - Message's instance id
1206  *  @param[in] comp_classification - ComponentClassification
1207  *  @param[in] comp_identifier - ComponentIdentifier
1208  *  @param[in] comp_classification_index - ComponentClassificationIndex
1209  *  @param[in] comp_comparison_stamp - ComponentComparisonStamp
1210  *  @param[in] comp_image_size - ComponentImageSize
1211  *  @param[in] update_option_flags - UpdateOptionFlags
1212  *  @param[in] comp_ver_str_type - ComponentVersionStringType
1213  *  @param[in] comp_ver_str_len - ComponentVersionStringLength
1214  *  @param[in] comp_ver_str - ComponentVersionString
1215  *  @param[in,out] msg - Message will be written to this
1216  *  @param[in] payload_length - Length of request message payload
1217  *                              information
1218  *
1219  *  @return pldm_completion_codes
1220  *
1221  *  @note  Caller is responsible for memory alloc and dealloc of param
1222  *         'msg.payload'
1223  */
1224 int encode_update_component_req(
1225 	uint8_t instance_id, uint16_t comp_classification,
1226 	uint16_t comp_identifier, uint8_t comp_classification_index,
1227 	uint32_t comp_comparison_stamp, uint32_t comp_image_size,
1228 	bitfield32_t update_option_flags, uint8_t comp_ver_str_type,
1229 	uint8_t comp_ver_str_len, const struct variable_field *comp_ver_str,
1230 	struct pldm_msg *msg, size_t payload_length);
1231 
1232 /** @brief Decode UpdateComponent response message
1233  *
1234  *  @param[in] msg - Response message
1235  *  @param[in] payload_length - Length of response message payload
1236  *  @param[out] completion_code - Pointer to hold completion code
1237  *  @param[out] comp_compatibility_resp - Pointer to hold component
1238  *                                        compatibility response
1239  *  @param[out] comp_compatibility_resp_code - Pointer to hold component
1240  *                                             compatibility response code
1241  *  @param[out] update_option_flags_enabled - Pointer to hold
1242  *                                            UpdateOptionsFlagEnabled
1243  *  @param[out] time_before_req_fw_data - Pointer to hold the estimated time
1244  *                                        before sending RequestFirmwareData
1245  *
1246  *  @return pldm_completion_codes
1247  */
1248 int decode_update_component_resp(const struct pldm_msg *msg,
1249 				 size_t payload_length,
1250 				 uint8_t *completion_code,
1251 				 uint8_t *comp_compatibility_resp,
1252 				 uint8_t *comp_compatibility_resp_code,
1253 				 bitfield32_t *update_option_flags_enabled,
1254 				 uint16_t *time_before_req_fw_data);
1255 
1256 /** @brief Decode RequestFirmwareData request message
1257  *
1258  *	@param[in] msg - Request message
1259  *	@param[in] payload_length - Length of request message payload
1260  *	@param[out] offset - Pointer to hold offset
1261  *	@param[out] length - Pointer to hold the size of the component image
1262  *                       segment requested by the FD/FDP
1263  *
1264  *	@return pldm_completion_codes
1265  */
1266 int decode_request_firmware_data_req(const struct pldm_msg *msg,
1267 				     size_t payload_length, uint32_t *offset,
1268 				     uint32_t *length);
1269 
1270 /** @brief Create PLDM response message for RequestFirmwareData
1271  *
1272  *  The ComponentImagePortion is not encoded in the PLDM response message
1273  *  by encode_request_firmware_data_resp to avoid an additional copy. Populating
1274  *  ComponentImagePortion in the PLDM response message is handled by the user
1275  *  of this API. The payload_length validation considers only the
1276  *  CompletionCode.
1277  *
1278  *	@param[in] instance_id - Message's instance id
1279  *	@param[in] completion_code - CompletionCode
1280  *	@param[in,out] msg - Message will be written to this
1281  *  @param[in] payload_length - Length of response message payload
1282  *
1283  *	@return pldm_completion_codes
1284  *
1285  *	@note  Caller is responsible for memory alloc and dealloc of param
1286  *		   'msg.payload'
1287  */
1288 int encode_request_firmware_data_resp(uint8_t instance_id,
1289 				      uint8_t completion_code,
1290 				      struct pldm_msg *msg,
1291 				      size_t payload_length);
1292 
1293 /** @brief Decode TransferComplete request message
1294  *
1295  *  @param[in] msg - Request message
1296  *  @param[in] payload_length - Length of request message payload
1297  *  @param[out] transfer_result - Pointer to hold TransferResult
1298  *
1299  *  @return pldm_completion_codes
1300  */
1301 int decode_transfer_complete_req(const struct pldm_msg *msg,
1302 				 size_t payload_length,
1303 				 uint8_t *transfer_result);
1304 
1305 /** @brief Create PLDM response message for TransferComplete
1306  *
1307  *  @param[in] instance_id - Message's instance id
1308  *  @param[in] completion_code - CompletionCode
1309  *  @param[in,out] msg - Message will be written to this
1310  *  @param[in] payload_length - Length of response message payload
1311  *
1312  *  @return pldm_completion_codes
1313  *
1314  *  @note  Caller is responsible for memory alloc and dealloc of param
1315  *         'msg.payload'
1316  */
1317 int encode_transfer_complete_resp(uint8_t instance_id, uint8_t completion_code,
1318 				  struct pldm_msg *msg, size_t payload_length);
1319 
1320 /** @brief Decode VerifyComplete request message
1321  *
1322  *  @param[in] msg - Request message
1323  *  @param[in] payload_length - Length of request message payload
1324  *  @param[in] verify_result - Pointer to hold VerifyResult
1325  *
1326  *  @return pldm_completion_codes
1327  */
1328 int decode_verify_complete_req(const struct pldm_msg *msg,
1329 			       size_t payload_length, uint8_t *verify_result);
1330 
1331 /** @brief Create PLDM response message for VerifyComplete
1332  *
1333  *  @param[in] instance_id - Message's instance id
1334  *  @param[in] completion_code - CompletionCode
1335  *  @param[in,out] msg - Message will be written to this
1336  *  @param[in] payload_length - Length of response message payload
1337  *
1338  *  @return pldm_completion_codes
1339  *
1340  *  @note  Caller is responsible for memory alloc and dealloc of param
1341  *         'msg.payload'
1342  */
1343 int encode_verify_complete_resp(uint8_t instance_id, uint8_t completion_code,
1344 				struct pldm_msg *msg, size_t payload_length);
1345 
1346 /** @brief Decode ApplyComplete request message
1347  *
1348  *  @param[in] msg - Request message
1349  *  @param[in] payload_length - Length of request message payload
1350  *  @param[in] apply_result - Pointer to hold ApplyResult
1351  *  @param[in] comp_activation_methods_modification - Pointer to hold the
1352  *                                        ComponentActivationMethodsModification
1353  *
1354  *  @return pldm_completion_codes
1355  */
1356 int decode_apply_complete_req(
1357 	const struct pldm_msg *msg, size_t payload_length,
1358 	uint8_t *apply_result,
1359 	bitfield16_t *comp_activation_methods_modification);
1360 
1361 /** @brief Create PLDM response message for ApplyComplete
1362  *
1363  *  @param[in] instance_id - Message's instance id
1364  *  @param[in] completion_code - CompletionCode
1365  *  @param[in,out] msg - Message will be written to this
1366  *  @param[in] payload_length - Length of response message payload
1367  *
1368  *  @return pldm_completion_codes
1369  *
1370  *  @note Caller is responsible for memory alloc and dealloc of param
1371  *        'msg.payload'
1372  */
1373 int encode_apply_complete_resp(uint8_t instance_id, uint8_t completion_code,
1374 			       struct pldm_msg *msg, size_t payload_length);
1375 
1376 /** @brief Create PLDM request message for ActivateFirmware
1377  *
1378  *  @param[in] instance_id - Message's instance id
1379  *  @param[in] self_contained_activation_req SelfContainedActivationRequest
1380  *  @param[in,out] msg - Message will be written to this
1381  *  @param[in] payload_length - Length of request message payload
1382  *
1383  *  @return pldm_completion_codes
1384  *
1385  *  @note  Caller is responsible for memory alloc and dealloc of param
1386  *         'msg.payload'
1387  */
1388 int encode_activate_firmware_req(uint8_t instance_id,
1389 				 bool8_t self_contained_activation_req,
1390 				 struct pldm_msg *msg, size_t payload_length);
1391 
1392 /** @brief Decode ActivateFirmware response message
1393  *
1394  *  @param[in] msg - Response message
1395  *  @param[in] payload_length - Length of response message payload
1396  *  @param[out] completion_code - Pointer to hold CompletionCode
1397  *  @param[out] estimated_time_activation - Pointer to hold
1398  *                                       EstimatedTimeForSelfContainedActivation
1399  *
1400  *  @return pldm_completion_codes
1401  */
1402 int decode_activate_firmware_resp(const struct pldm_msg *msg,
1403 				  size_t payload_length,
1404 				  uint8_t *completion_code,
1405 				  uint16_t *estimated_time_activation);
1406 
1407 /** @brief Create PLDM request message for GetStatus
1408  *
1409  *  @param[in] instance_id - Message's instance id
1410  *  @param[in,out] msg - Message will be written to this
1411  *  @param[in] payload_length - Length of request message payload
1412  *
1413  *  @return pldm_completion_codes
1414  *
1415  *  @note Caller is responsible for memory alloc and dealloc of param
1416  *        'msg.payload'
1417  */
1418 int encode_get_status_req(uint8_t instance_id, struct pldm_msg *msg,
1419 			  size_t payload_length);
1420 
1421 /** @brief Decode GetStatus response message
1422  *
1423  *  @param[in] msg - Response message
1424  *  @param[in] payload_length - Length of response message payload
1425  *  @param[out] completion_code - Pointer to completion code
1426  *  @param[out] current_state - Pointer to current state machine state
1427  *  @param[out] previous_state - Pointer to previous different state machine
1428  *                               state
1429  *  @param[out] aux_state - Pointer to current operation state of FD/FDP
1430  *  @param[out] aux_state_status - Pointer to aux state status
1431  *  @param[out] progress_percent - Pointer to progress percentage
1432  *  @param[out] reason_code - Pointer to reason for entering current state
1433  *  @param[out] update_option_flags_enabled - Pointer to update option flags
1434  *                                            enabled
1435  *
1436  *  @return pldm_completion_codes
1437  */
1438 int decode_get_status_resp(const struct pldm_msg *msg, size_t payload_length,
1439 			   uint8_t *completion_code, uint8_t *current_state,
1440 			   uint8_t *previous_state, uint8_t *aux_state,
1441 			   uint8_t *aux_state_status, uint8_t *progress_percent,
1442 			   uint8_t *reason_code,
1443 			   bitfield32_t *update_option_flags_enabled);
1444 
1445 /** @brief Create PLDM request message for CancelUpdateComponent
1446  *
1447  *  @param[in] instance_id - Message's instance id
1448  *  @param[in,out] msg - Message will be written to this
1449  *  @param[in] payload_length - Length of request message payload
1450  *
1451  *  @return pldm_completion_codes
1452  *
1453  *  @note  Caller is responsible for memory alloc and dealloc of param
1454  *         'msg.payload'
1455  */
1456 int encode_cancel_update_component_req(uint8_t instance_id,
1457 				       struct pldm_msg *msg,
1458 				       size_t payload_length);
1459 
1460 /** @brief Decode CancelUpdateComponent response message
1461  *
1462  *  @param[in] msg - Response message
1463  *  @param[in] payload_length - Length of response message payload
1464  *  @param[out] completion_code - Pointer to the completion code
1465  *
1466  *  @return pldm_completion_codes
1467  */
1468 int decode_cancel_update_component_resp(const struct pldm_msg *msg,
1469 					size_t payload_length,
1470 					uint8_t *completion_code);
1471 
1472 /** @brief Create PLDM request message for CancelUpdate
1473  *
1474  *	@param[in] instance_id - Message's instance id
1475  *	@param[in,out] msg - Message will be written to this
1476  *  @param[in] payload_length - Length of request message payload
1477  *
1478  *	@return pldm_completion_codes
1479  *
1480  *	@note  Caller is responsible for memory alloc and dealloc of param
1481  *         'msg.payload'
1482  */
1483 int encode_cancel_update_req(uint8_t instance_id, struct pldm_msg *msg,
1484 			     size_t payload_length);
1485 
1486 /** @brief Decode CancelUpdate response message
1487  *
1488  *	@param[in] msg - Response message
1489  *  @param[in] payload_length - Length of response message payload
1490  *	@param[out] completion_code - Pointer to completion code
1491  *	@param[out] non_functioning_component_indication - Pointer to non
1492 						       functioning
1493  *                                                     component indication
1494  *	@param[out] non_functioning_component_bitmap - Pointer to non
1495  functioning
1496  *                                                 component bitmap
1497  *
1498  *	@return pldm_completion_codes
1499  */
1500 int decode_cancel_update_resp(const struct pldm_msg *msg, size_t payload_length,
1501 			      uint8_t *completion_code,
1502 			      bool8_t *non_functioning_component_indication,
1503 			      bitfield64_t *non_functioning_component_bitmap);
1504 
1505 #ifdef __cplusplus
1506 }
1507 #endif
1508 
1509 #endif // End of FW_UPDATE_H
1510