#include "firmware_update.h" | |
#include <endian.h> | |
#include <string.h> | |
int encode_query_device_identifiers_req(uint8_t instance_id, | |
size_t payload_length, | |
struct pldm_msg *msg) | |
{ | |
if (msg == NULL) { | |
return PLDM_ERROR_INVALID_DATA; | |
} | |
if (payload_length != PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES) { | |
return PLDM_ERROR_INVALID_LENGTH; | |
} | |
return encode_pldm_header_only(PLDM_REQUEST, instance_id, PLDM_FWUP, | |
PLDM_QUERY_DEVICE_IDENTIFIERS, msg); | |
} | |
int decode_query_device_identifiers_resp(const struct pldm_msg *msg, | |
size_t payload_length, | |
uint8_t *completion_code, | |
uint32_t *device_identifiers_len, | |
uint8_t *descriptor_count, | |
uint8_t **descriptor_data) | |
{ | |
if (msg == NULL || completion_code == NULL || | |
device_identifiers_len == NULL || descriptor_count == NULL || | |
descriptor_data == NULL) { | |
return PLDM_ERROR_INVALID_DATA; | |
} | |
*completion_code = msg->payload[0]; | |
if (PLDM_SUCCESS != *completion_code) { | |
return PLDM_SUCCESS; | |
} | |
if (payload_length < | |
sizeof(struct pldm_query_device_identifiers_resp)) { | |
return PLDM_ERROR_INVALID_LENGTH; | |
} | |
struct pldm_query_device_identifiers_resp *response = | |
(struct pldm_query_device_identifiers_resp *)msg->payload; | |
*device_identifiers_len = le32toh(response->device_identifiers_len); | |
if (*device_identifiers_len < PLDM_FWUP_DEVICE_DESCRIPTOR_MIN_LEN) { | |
return PLDM_ERROR_INVALID_LENGTH; | |
} | |
if (payload_length != | |
sizeof(struct pldm_query_device_identifiers_resp) + | |
*device_identifiers_len) { | |
return PLDM_ERROR_INVALID_LENGTH; | |
} | |
*descriptor_count = response->descriptor_count; | |
if (*descriptor_count == 0) { | |
return PLDM_ERROR_INVALID_DATA; | |
} | |
*descriptor_data = | |
(uint8_t *)(msg->payload + | |
sizeof(struct pldm_query_device_identifiers_resp)); | |
return PLDM_SUCCESS; | |
} | |
int encode_get_firmware_parameters_req(uint8_t instance_id, | |
size_t payload_length, | |
struct pldm_msg *msg) | |
{ | |
if (msg == NULL) { | |
return PLDM_ERROR_INVALID_DATA; | |
} | |
if (payload_length != PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES) { | |
return PLDM_ERROR_INVALID_LENGTH; | |
} | |
return encode_pldm_header_only(PLDM_REQUEST, instance_id, PLDM_FWUP, | |
PLDM_GET_FIRMWARE_PARAMETERS, msg); | |
} | |
int decode_get_firmware_parameters_resp_comp_set_info( | |
const struct pldm_msg *msg, size_t payload_length, | |
struct pldm_get_firmware_parameters_resp *resp_data, | |
struct variable_field *active_comp_image_set_ver_str, | |
struct variable_field *pending_comp_image_set_ver_str) | |
{ | |
if (msg == NULL || resp_data == NULL || | |
active_comp_image_set_ver_str == NULL || | |
pending_comp_image_set_ver_str == NULL) { | |
return PLDM_ERROR_INVALID_DATA; | |
} | |
if (payload_length < sizeof(struct pldm_get_firmware_parameters_resp)) { | |
return PLDM_ERROR_INVALID_LENGTH; | |
} | |
struct pldm_get_firmware_parameters_resp *response = | |
(struct pldm_get_firmware_parameters_resp *)msg->payload; | |
resp_data->completion_code = response->completion_code; | |
if (PLDM_SUCCESS != resp_data->completion_code) { | |
return PLDM_SUCCESS; | |
} | |
if (response->active_comp_image_set_ver_str_len == 0) { | |
return PLDM_ERROR_INVALID_DATA; | |
} | |
size_t resp_len = sizeof(struct pldm_get_firmware_parameters_resp) + | |
response->active_comp_image_set_ver_str_len + | |
response->pending_comp_image_set_ver_str_len; | |
if (payload_length != resp_len) { | |
return PLDM_ERROR_INVALID_LENGTH; | |
} | |
resp_data->capabilities_during_update.value = | |
le32toh(response->capabilities_during_update.value); | |
resp_data->comp_count = le16toh(response->comp_count); | |
if (resp_data->comp_count == 0) { | |
return PLDM_ERROR; | |
} | |
resp_data->active_comp_image_set_ver_str_type = | |
response->active_comp_image_set_ver_str_type; | |
resp_data->active_comp_image_set_ver_str_len = | |
response->active_comp_image_set_ver_str_len; | |
resp_data->pending_comp_image_set_ver_str_type = | |
response->pending_comp_image_set_ver_str_type; | |
resp_data->pending_comp_image_set_ver_str_len = | |
response->pending_comp_image_set_ver_str_len; | |
active_comp_image_set_ver_str->ptr = | |
msg->payload + sizeof(struct pldm_get_firmware_parameters_resp); | |
active_comp_image_set_ver_str->length = | |
resp_data->active_comp_image_set_ver_str_len; | |
if (resp_data->pending_comp_image_set_ver_str_len != 0) { | |
pending_comp_image_set_ver_str->ptr = | |
msg->payload + | |
sizeof(struct pldm_get_firmware_parameters_resp) + | |
resp_data->active_comp_image_set_ver_str_len; | |
pending_comp_image_set_ver_str->length = | |
resp_data->pending_comp_image_set_ver_str_len; | |
} else { | |
pending_comp_image_set_ver_str->ptr = NULL; | |
pending_comp_image_set_ver_str->length = 0; | |
} | |
return PLDM_SUCCESS; | |
} | |
int decode_get_firmware_parameters_resp_comp_entry( | |
const uint8_t *data, size_t length, | |
struct pldm_component_parameter_entry *component_data, | |
struct variable_field *active_comp_ver_str, | |
struct variable_field *pending_comp_ver_str) | |
{ | |
if (data == NULL || component_data == NULL || | |
active_comp_ver_str == NULL || pending_comp_ver_str == NULL) { | |
return PLDM_ERROR_INVALID_DATA; | |
} | |
if (length < sizeof(struct pldm_component_parameter_entry)) { | |
return PLDM_ERROR_INVALID_LENGTH; | |
} | |
struct pldm_component_parameter_entry *entry = | |
(struct pldm_component_parameter_entry *)(data); | |
if (entry->active_comp_ver_str_len == 0) { | |
return PLDM_ERROR_INVALID_LENGTH; | |
} | |
size_t entry_length = sizeof(struct pldm_component_parameter_entry) + | |
entry->active_comp_ver_str_len + | |
entry->pending_comp_ver_str_len; | |
if (length != entry_length) { | |
return PLDM_ERROR_INVALID_LENGTH; | |
} | |
component_data->comp_classification = | |
le16toh(entry->comp_classification); | |
component_data->comp_identifier = le16toh(entry->comp_identifier); | |
component_data->comp_classification_index = | |
entry->comp_classification_index; | |
component_data->active_comp_comparison_stamp = | |
le32toh(entry->active_comp_comparison_stamp); | |
component_data->active_comp_ver_str_type = | |
entry->active_comp_ver_str_type; | |
component_data->active_comp_ver_str_len = | |
entry->active_comp_ver_str_len; | |
memcpy(component_data->active_comp_release_date, | |
entry->active_comp_release_date, | |
sizeof(entry->active_comp_release_date)); | |
component_data->pending_comp_comparison_stamp = | |
le32toh(entry->pending_comp_comparison_stamp); | |
component_data->pending_comp_ver_str_type = | |
entry->pending_comp_ver_str_type; | |
component_data->pending_comp_ver_str_len = | |
entry->pending_comp_ver_str_len; | |
memcpy(component_data->pending_comp_release_date, | |
entry->pending_comp_release_date, | |
sizeof(entry->pending_comp_release_date)); | |
component_data->comp_activation_methods.value = | |
le16toh(entry->comp_activation_methods.value); | |
component_data->capabilities_during_update.value = | |
le32toh(entry->capabilities_during_update.value); | |
active_comp_ver_str->ptr = | |
data + sizeof(struct pldm_component_parameter_entry); | |
active_comp_ver_str->length = entry->active_comp_ver_str_len; | |
if (entry->pending_comp_ver_str_len != 0) { | |
pending_comp_ver_str->ptr = | |
data + sizeof(struct pldm_component_parameter_entry) + | |
entry->active_comp_ver_str_len; | |
pending_comp_ver_str->length = entry->pending_comp_ver_str_len; | |
} else { | |
pending_comp_ver_str->ptr = NULL; | |
pending_comp_ver_str->length = 0; | |
} | |
return PLDM_SUCCESS; | |
} |