blob: 58dd21ff147d292a9691f0c1cc329c239db157a4 [file] [log] [blame]
gokulsanker138ceba2021-04-05 13:25:25 +05301#include "firmware_update.h"
gokulsankereca3e192021-04-05 14:57:41 +05302#include <endian.h>
gokulsankere1fb7a82021-04-05 16:09:29 +05303#include <string.h>
gokulsanker138ceba2021-04-05 13:25:25 +05304
5int encode_query_device_identifiers_req(uint8_t instance_id,
6 size_t payload_length,
7 struct pldm_msg *msg)
8{
9 if (msg == NULL) {
10 return PLDM_ERROR_INVALID_DATA;
11 }
12
13 if (payload_length != PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES) {
14 return PLDM_ERROR_INVALID_LENGTH;
15 }
16
17 return encode_pldm_header_only(PLDM_REQUEST, instance_id, PLDM_FWUP,
18 PLDM_QUERY_DEVICE_IDENTIFIERS, msg);
19}
gokulsankereca3e192021-04-05 14:57:41 +053020
21int decode_query_device_identifiers_resp(const struct pldm_msg *msg,
22 size_t payload_length,
23 uint8_t *completion_code,
24 uint32_t *device_identifiers_len,
25 uint8_t *descriptor_count,
26 uint8_t **descriptor_data)
27{
28 if (msg == NULL || completion_code == NULL ||
29 device_identifiers_len == NULL || descriptor_count == NULL ||
30 descriptor_data == NULL) {
31 return PLDM_ERROR_INVALID_DATA;
32 }
33
34 *completion_code = msg->payload[0];
35 if (PLDM_SUCCESS != *completion_code) {
36 return PLDM_SUCCESS;
37 }
38
39 if (payload_length <
40 sizeof(struct pldm_query_device_identifiers_resp)) {
41 return PLDM_ERROR_INVALID_LENGTH;
42 }
43
44 struct pldm_query_device_identifiers_resp *response =
45 (struct pldm_query_device_identifiers_resp *)msg->payload;
46 *device_identifiers_len = le32toh(response->device_identifiers_len);
47
48 if (*device_identifiers_len < PLDM_FWUP_DEVICE_DESCRIPTOR_MIN_LEN) {
49 return PLDM_ERROR_INVALID_LENGTH;
50 }
51
52 if (payload_length !=
53 sizeof(struct pldm_query_device_identifiers_resp) +
54 *device_identifiers_len) {
55 return PLDM_ERROR_INVALID_LENGTH;
56 }
57 *descriptor_count = response->descriptor_count;
58
59 if (*descriptor_count == 0) {
60 return PLDM_ERROR_INVALID_DATA;
61 }
gokulsankereca3e192021-04-05 14:57:41 +053062 *descriptor_data =
63 (uint8_t *)(msg->payload +
64 sizeof(struct pldm_query_device_identifiers_resp));
65 return PLDM_SUCCESS;
66}
gokulsanker981fbfb2021-04-05 15:17:25 +053067
68int encode_get_firmware_parameters_req(uint8_t instance_id,
69 size_t payload_length,
70 struct pldm_msg *msg)
71{
72 if (msg == NULL) {
73 return PLDM_ERROR_INVALID_DATA;
74 }
75
76 if (payload_length != PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES) {
77 return PLDM_ERROR_INVALID_LENGTH;
78 }
79
80 return encode_pldm_header_only(PLDM_REQUEST, instance_id, PLDM_FWUP,
81 PLDM_GET_FIRMWARE_PARAMETERS, msg);
82}
gokulsanker22fbb342021-04-05 15:55:06 +053083
84int decode_get_firmware_parameters_resp_comp_set_info(
85 const struct pldm_msg *msg, size_t payload_length,
86 struct pldm_get_firmware_parameters_resp *resp_data,
87 struct variable_field *active_comp_image_set_ver_str,
88 struct variable_field *pending_comp_image_set_ver_str)
89{
90 if (msg == NULL || resp_data == NULL ||
91 active_comp_image_set_ver_str == NULL ||
92 pending_comp_image_set_ver_str == NULL) {
93
94 return PLDM_ERROR_INVALID_DATA;
95 }
96
97 if (payload_length < sizeof(struct pldm_get_firmware_parameters_resp)) {
98 return PLDM_ERROR_INVALID_LENGTH;
99 }
100
101 struct pldm_get_firmware_parameters_resp *response =
102 (struct pldm_get_firmware_parameters_resp *)msg->payload;
103
104 resp_data->completion_code = response->completion_code;
105
106 if (PLDM_SUCCESS != resp_data->completion_code) {
107 return PLDM_SUCCESS;
108 }
109
110 if (response->active_comp_image_set_ver_str_len == 0) {
111 return PLDM_ERROR_INVALID_DATA;
112 }
113
114 size_t resp_len = sizeof(struct pldm_get_firmware_parameters_resp) +
115 response->active_comp_image_set_ver_str_len +
116 response->pending_comp_image_set_ver_str_len;
117
118 if (payload_length != resp_len) {
119 return PLDM_ERROR_INVALID_LENGTH;
120 }
121
122 resp_data->capabilities_during_update.value =
123 le32toh(response->capabilities_during_update.value);
124
125 resp_data->comp_count = le16toh(response->comp_count);
126 if (resp_data->comp_count == 0) {
127 return PLDM_ERROR;
128 }
129
130 resp_data->active_comp_image_set_ver_str_type =
131 response->active_comp_image_set_ver_str_type;
132 resp_data->active_comp_image_set_ver_str_len =
133 response->active_comp_image_set_ver_str_len;
134 resp_data->pending_comp_image_set_ver_str_type =
135 response->pending_comp_image_set_ver_str_type;
136 resp_data->pending_comp_image_set_ver_str_len =
137 response->pending_comp_image_set_ver_str_len;
138
139 active_comp_image_set_ver_str->ptr =
140 msg->payload + sizeof(struct pldm_get_firmware_parameters_resp);
141 active_comp_image_set_ver_str->length =
142 resp_data->active_comp_image_set_ver_str_len;
143
144 if (resp_data->pending_comp_image_set_ver_str_len != 0) {
145 pending_comp_image_set_ver_str->ptr =
146 msg->payload +
147 sizeof(struct pldm_get_firmware_parameters_resp) +
148 resp_data->active_comp_image_set_ver_str_len;
149 pending_comp_image_set_ver_str->length =
150 resp_data->pending_comp_image_set_ver_str_len;
151 } else {
152 pending_comp_image_set_ver_str->ptr = NULL;
153 pending_comp_image_set_ver_str->length = 0;
154 }
155
156 return PLDM_SUCCESS;
157}
gokulsankere1fb7a82021-04-05 16:09:29 +0530158
159int decode_get_firmware_parameters_resp_comp_entry(
160 const uint8_t *data, size_t length,
161 struct pldm_component_parameter_entry *component_data,
162 struct variable_field *active_comp_ver_str,
163 struct variable_field *pending_comp_ver_str)
164{
165 if (data == NULL || component_data == NULL ||
166 active_comp_ver_str == NULL || pending_comp_ver_str == NULL) {
167 return PLDM_ERROR_INVALID_DATA;
168 }
169
170 if (length < sizeof(struct pldm_component_parameter_entry)) {
171 return PLDM_ERROR_INVALID_LENGTH;
172 }
173
174 struct pldm_component_parameter_entry *entry =
175 (struct pldm_component_parameter_entry *)(data);
176 if (entry->active_comp_ver_str_len == 0) {
177 return PLDM_ERROR_INVALID_LENGTH;
178 }
179
180 size_t entry_length = sizeof(struct pldm_component_parameter_entry) +
181 entry->active_comp_ver_str_len +
182 entry->pending_comp_ver_str_len;
183
184 if (length != entry_length) {
185 return PLDM_ERROR_INVALID_LENGTH;
186 }
187
188 component_data->comp_classification =
189 le16toh(entry->comp_classification);
190 component_data->comp_identifier = le16toh(entry->comp_identifier);
191 component_data->comp_classification_index =
192 entry->comp_classification_index;
193 component_data->active_comp_comparison_stamp =
194 le32toh(entry->active_comp_comparison_stamp);
195 component_data->active_comp_ver_str_type =
196 entry->active_comp_ver_str_type;
197 component_data->active_comp_ver_str_len =
198 entry->active_comp_ver_str_len;
199 memcpy(component_data->active_comp_release_date,
200 entry->active_comp_release_date,
201 sizeof(entry->active_comp_release_date));
202 component_data->pending_comp_comparison_stamp =
203 le32toh(entry->pending_comp_comparison_stamp);
204 component_data->pending_comp_ver_str_type =
205 entry->pending_comp_ver_str_type;
206 component_data->pending_comp_ver_str_len =
207 entry->pending_comp_ver_str_len;
208 memcpy(component_data->pending_comp_release_date,
209 entry->pending_comp_release_date,
210 sizeof(entry->pending_comp_release_date));
211 component_data->comp_activation_methods.value =
212 le16toh(entry->comp_activation_methods.value);
213 component_data->capabilities_during_update.value =
214 le32toh(entry->capabilities_during_update.value);
215
216 active_comp_ver_str->ptr =
217 data + sizeof(struct pldm_component_parameter_entry);
218 active_comp_ver_str->length = entry->active_comp_ver_str_len;
219
220 if (entry->pending_comp_ver_str_len != 0) {
221
222 pending_comp_ver_str->ptr =
223 data + sizeof(struct pldm_component_parameter_entry) +
224 entry->active_comp_ver_str_len;
225 pending_comp_ver_str->length = entry->pending_comp_ver_str_len;
226 } else {
227 pending_comp_ver_str->ptr = NULL;
228 pending_comp_ver_str->length = 0;
229 }
230 return PLDM_SUCCESS;
231}