blob: 64c1abac9c0b50181dfa50e777280f66a5ba88b4 [file] [log] [blame]
John Wang9fa87cf2020-06-10 17:53:40 +08001#include <assert.h>
Jinu Joy Thomas8e92c6c2019-08-06 12:22:34 +05302#include <endian.h>
John Wang9fa87cf2020-06-10 17:53:40 +08003#include <stdbool.h>
Jinu Joy Thomas8e92c6c2019-08-06 12:22:34 +05304#include <string.h>
5
6#include "fru.h"
7
8int encode_get_fru_record_table_metadata_req(uint8_t instance_id,
Christian Geddes3bdb3c22020-05-01 14:55:39 -05009 struct pldm_msg *msg,
10 size_t payload_length)
Jinu Joy Thomas8e92c6c2019-08-06 12:22:34 +053011{
12 if (msg == NULL) {
13 return PLDM_ERROR_INVALID_DATA;
14 }
15
Christian Geddes3bdb3c22020-05-01 14:55:39 -050016 if (payload_length != PLDM_GET_FRU_RECORD_TABLE_METADATA_REQ_BYTES) {
17 return PLDM_ERROR_INVALID_LENGTH;
18 }
19
Jinu Joy Thomas8e92c6c2019-08-06 12:22:34 +053020 struct pldm_header_info header = {0};
21 header.instance = instance_id;
22 header.msg_type = PLDM_REQUEST;
23 header.pldm_type = PLDM_FRU;
24 header.command = PLDM_GET_FRU_RECORD_TABLE_METADATA;
25 int rc = pack_pldm_header(&header, &(msg->hdr));
26 if (PLDM_SUCCESS != rc) {
27 return rc;
28 }
Christian Geddes3bdb3c22020-05-01 14:55:39 -050029
Jinu Joy Thomas8e92c6c2019-08-06 12:22:34 +053030 return PLDM_SUCCESS;
31}
32
33int decode_get_fru_record_table_metadata_resp(
34 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
35 uint8_t *fru_data_major_version, uint8_t *fru_data_minor_version,
36 uint32_t *fru_table_maximum_size, uint32_t *fru_table_length,
37 uint16_t *total_record_set_identifiers, uint16_t *total_table_records,
38 uint32_t *checksum)
39{
40 if (msg == NULL || completion_code == NULL ||
41 fru_data_major_version == NULL || fru_data_minor_version == NULL ||
42 fru_table_maximum_size == NULL || fru_table_length == NULL ||
43 total_record_set_identifiers == NULL ||
44 total_table_records == NULL || checksum == NULL) {
45 return PLDM_ERROR_INVALID_DATA;
46 }
47
George Liu684a7162019-12-06 15:10:52 +080048 *completion_code = msg->payload[0];
49 if (PLDM_SUCCESS != *completion_code) {
50 return PLDM_SUCCESS;
51 }
52
Jinu Joy Thomas8e92c6c2019-08-06 12:22:34 +053053 if (payload_length != PLDM_GET_FRU_RECORD_TABLE_METADATA_RESP_BYTES) {
54 return PLDM_ERROR_INVALID_LENGTH;
55 }
56
57 struct pldm_get_fru_record_table_metadata_resp *response =
58 (struct pldm_get_fru_record_table_metadata_resp *)msg->payload;
Jinu Joy Thomas8e92c6c2019-08-06 12:22:34 +053059
60 *fru_data_major_version = response->fru_data_major_version;
61 *fru_data_minor_version = response->fru_data_minor_version;
62 *fru_table_maximum_size = le32toh(response->fru_table_maximum_size);
63 *fru_table_length = le32toh(response->fru_table_length);
64 *total_record_set_identifiers =
65 le16toh(response->total_record_set_identifiers);
66 *total_table_records = le16toh(response->total_table_records);
67 *checksum = le32toh(response->checksum);
68
69 return PLDM_SUCCESS;
70}
71
72int encode_get_fru_record_table_metadata_resp(
73 uint8_t instance_id, uint8_t completion_code,
74 uint8_t fru_data_major_version, uint8_t fru_data_minor_version,
75 uint32_t fru_table_maximum_size, uint32_t fru_table_length,
76 uint16_t total_record_set_identifiers, uint16_t total_table_records,
77 uint32_t checksum, struct pldm_msg *msg)
78{
79
80 if (msg == NULL) {
81 return PLDM_ERROR_INVALID_DATA;
82 }
83
84 struct pldm_header_info header = {0};
85 header.msg_type = PLDM_RESPONSE;
86 header.instance = instance_id;
87 header.pldm_type = PLDM_FRU;
88 header.command = PLDM_GET_FRU_RECORD_TABLE_METADATA;
89 int rc = pack_pldm_header(&header, &(msg->hdr));
90 if (PLDM_SUCCESS != rc) {
91 return rc;
92 }
93
94 struct pldm_get_fru_record_table_metadata_resp *response =
95 (struct pldm_get_fru_record_table_metadata_resp *)msg->payload;
96 response->completion_code = completion_code;
97 if (response->completion_code == PLDM_SUCCESS) {
98 response->fru_data_major_version = fru_data_major_version;
99 response->fru_data_minor_version = fru_data_minor_version;
100 response->fru_table_maximum_size =
101 htole32(fru_table_maximum_size);
102 response->fru_table_length = htole32(fru_table_length);
103 response->total_record_set_identifiers =
104 htole16(total_record_set_identifiers);
105 response->total_table_records = htole16(total_table_records);
106 response->checksum = htole32(checksum);
107 }
108
109 return PLDM_SUCCESS;
110}
PriyangaRamasamy497665a2019-07-30 12:48:25 +0530111
112int decode_get_fru_record_table_req(const struct pldm_msg *msg,
113 size_t payload_length,
114 uint32_t *data_transfer_handle,
115 uint8_t *transfer_operation_flag)
116{
117 if (msg == NULL || data_transfer_handle == NULL ||
118 transfer_operation_flag == NULL) {
119 return PLDM_ERROR_INVALID_DATA;
120 }
121
122 if (payload_length != PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES) {
123 return PLDM_ERROR_INVALID_LENGTH;
124 }
125
126 struct pldm_get_fru_record_table_req *req =
127 (struct pldm_get_fru_record_table_req *)msg->payload;
128
129 *data_transfer_handle = le32toh(req->data_transfer_handle);
130 *transfer_operation_flag = req->transfer_operation_flag;
131
132 return PLDM_SUCCESS;
133}
134
135int encode_get_fru_record_table_resp(uint8_t instance_id,
136 uint8_t completion_code,
137 uint32_t next_data_transfer_handle,
138 uint8_t transfer_flag,
139 struct pldm_msg *msg)
140{
141 struct pldm_header_info header = {0};
142 int rc = PLDM_ERROR_INVALID_DATA;
143
144 header.msg_type = PLDM_RESPONSE;
145 header.instance = instance_id;
146 header.pldm_type = PLDM_FRU;
147 header.command = PLDM_GET_FRU_RECORD_TABLE;
148
149 if (msg == NULL) {
150 return rc;
151 }
152
153 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
154 return rc;
155 }
156
157 struct pldm_get_fru_record_table_resp *resp =
158 (struct pldm_get_fru_record_table_resp *)msg->payload;
159
160 resp->completion_code = completion_code;
161
162 if (resp->completion_code == PLDM_SUCCESS) {
163
164 resp->next_data_transfer_handle =
165 htole32(next_data_transfer_handle);
166 resp->transfer_flag = transfer_flag;
167 }
168
169 return PLDM_SUCCESS;
170}
Tom Joseph93d68712020-01-07 10:24:41 +0530171
172int encode_fru_record(uint8_t *fru_table, size_t total_size, size_t *curr_size,
173 uint16_t record_set_id, uint8_t record_type,
174 uint8_t num_frus, uint8_t encoding, uint8_t *tlvs,
175 size_t tlvs_size)
176{
177 size_t record_hdr_size = sizeof(struct pldm_fru_record_data_format) -
178 sizeof(struct pldm_fru_record_tlv);
179
180 if ((*curr_size + record_hdr_size + tlvs_size) != total_size) {
181 return PLDM_ERROR_INVALID_LENGTH;
182 }
183
184 if (fru_table == NULL || curr_size == NULL || !tlvs_size) {
185 return PLDM_ERROR_INVALID_DATA;
186 }
187
188 struct pldm_fru_record_data_format *record =
189 (struct pldm_fru_record_data_format *)(fru_table + *curr_size);
190 record->record_set_id = htole16(record_set_id);
191 record->record_type = record_type;
192 record->num_fru_fields = num_frus;
193 record->encoding_type = encoding;
194 *curr_size += record_hdr_size;
195
196 if (tlvs) {
197 memcpy(fru_table + *curr_size, tlvs, tlvs_size);
198 *curr_size += tlvs_size;
199 }
200
201 return PLDM_SUCCESS;
202}
PriyangaRamasamyf3295be2019-07-23 12:18:40 +0530203
John Wang9fa87cf2020-06-10 17:53:40 +0800204int encode_get_fru_record_by_option_req(
205 uint8_t instance_id, uint32_t data_transfer_handle,
206 uint16_t fru_table_handle, uint16_t record_set_identifier,
207 uint8_t record_type, uint8_t field_type, uint8_t transfer_op_flag,
208 struct pldm_msg *msg, size_t payload_length)
209{
210
211 if (msg == NULL) {
212 return PLDM_ERROR_INVALID_DATA;
213 }
214
215 if (payload_length !=
216 sizeof(struct pldm_get_fru_record_by_option_req)) {
217 return PLDM_ERROR_INVALID_LENGTH;
218 }
219
220 struct pldm_header_info header = {0};
221 header.instance = instance_id;
222 header.msg_type = PLDM_REQUEST;
223 header.pldm_type = PLDM_FRU;
224 header.command = PLDM_GET_FRU_RECORD_BY_OPTION;
225 int rc = pack_pldm_header(&header, &(msg->hdr));
226 if (rc != PLDM_SUCCESS) {
227 return rc;
228 }
229
230 struct pldm_get_fru_record_by_option_req *req =
231 (struct pldm_get_fru_record_by_option_req *)msg->payload;
232
233 req->data_transfer_handle = htole32(data_transfer_handle);
234 req->fru_table_handle = htole16(fru_table_handle);
235 req->record_set_identifier = htole16(record_set_identifier);
236 req->record_type = record_type;
237 req->field_type = field_type;
238 req->transfer_op_flag = transfer_op_flag;
239
240 return PLDM_SUCCESS;
241}
242
243int decode_get_fru_record_by_option_req(
244 const struct pldm_msg *msg, size_t payload_length,
245 uint32_t *data_transfer_handle, uint16_t *fru_table_handle,
246 uint16_t *record_set_identifier, uint8_t *record_type, uint8_t *field_type,
247 uint8_t *transfer_op_flag)
248{
249 if (msg == NULL || data_transfer_handle == NULL ||
250 fru_table_handle == NULL || record_set_identifier == NULL ||
251 record_type == NULL || field_type == NULL ||
252 transfer_op_flag == NULL) {
253 return PLDM_ERROR_INVALID_DATA;
254 }
255
256 if (payload_length !=
257 sizeof(struct pldm_get_fru_record_by_option_req)) {
258 return PLDM_ERROR_INVALID_LENGTH;
259 }
260
261 struct pldm_get_fru_record_by_option_req *req =
262 (struct pldm_get_fru_record_by_option_req *)msg->payload;
263
264 *data_transfer_handle = le32toh(req->data_transfer_handle);
265 *fru_table_handle = le16toh(req->fru_table_handle);
266 *record_set_identifier = le16toh(req->record_set_identifier);
267 *record_type = req->record_type;
268 *field_type = req->field_type;
269 *transfer_op_flag = req->transfer_op_flag;
270 return PLDM_SUCCESS;
271}
272
273int encode_get_fru_record_by_option_resp(uint8_t instance_id,
274 uint8_t completion_code,
275 uint32_t next_data_transfer_handle,
276 uint8_t transfer_flag,
277 const void *fru_structure_data,
278 size_t data_size, struct pldm_msg *msg,
279 size_t payload_length)
280{
281 if (msg == NULL || fru_structure_data == NULL) {
282 return PLDM_ERROR_INVALID_DATA;
283 }
284
285 if (payload_length < PLDM_GET_FRU_RECORD_BY_OPTION_MIN_RESP_BYTES) {
286 return PLDM_ERROR_INVALID_LENGTH;
287 }
288
289 struct pldm_header_info header = {0};
290 header.instance = instance_id;
291 header.msg_type = PLDM_RESPONSE;
292 header.pldm_type = PLDM_FRU;
293 header.command = PLDM_GET_FRU_RECORD_BY_OPTION;
294 int rc = pack_pldm_header(&header, &(msg->hdr));
295 if (rc != PLDM_SUCCESS) {
296 return rc;
297 }
298
299 struct pldm_get_fru_record_by_option_resp *resp =
300 (struct pldm_get_fru_record_by_option_resp *)msg->payload;
301
302 resp->completion_code = completion_code;
303 resp->next_data_transfer_handle = htole32(next_data_transfer_handle);
304 resp->transfer_flag = transfer_flag;
305
306 if (completion_code != PLDM_SUCCESS) {
307 return PLDM_SUCCESS;
308 }
309
310 if (payload_length !=
311 PLDM_GET_FRU_RECORD_BY_OPTION_MIN_RESP_BYTES + data_size) {
312 return PLDM_ERROR_INVALID_LENGTH;
313 }
314
315 memcpy(resp->fru_structure_data, fru_structure_data, data_size);
316
317 return PLDM_SUCCESS;
318}
319
320int decode_get_fru_record_by_option_resp(
321 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
322 uint32_t *next_transfer_handle, uint8_t *transfer_flag,
323 struct variable_field *fru_structure_data)
324{
325 if (msg == NULL || completion_code == NULL ||
326 next_transfer_handle == NULL || transfer_flag == NULL ||
327 fru_structure_data == NULL) {
328 return PLDM_ERROR_INVALID_DATA;
329 }
330
331 *completion_code = msg->payload[0];
332 if (PLDM_SUCCESS != *completion_code) {
333 return PLDM_SUCCESS;
334 }
335
336 if (payload_length < PLDM_GET_FRU_RECORD_BY_OPTION_MIN_RESP_BYTES) {
337 return PLDM_ERROR_INVALID_LENGTH;
338 }
339
340 struct pldm_get_fru_record_by_option_resp *resp =
341 (struct pldm_get_fru_record_by_option_resp *)msg->payload;
342
343 *next_transfer_handle = le32toh(resp->next_data_transfer_handle);
344 *transfer_flag = resp->transfer_flag;
345 fru_structure_data->ptr = resp->fru_structure_data;
346 fru_structure_data->length =
347 payload_length - PLDM_GET_FRU_RECORD_BY_OPTION_MIN_RESP_BYTES;
348
349 return PLDM_SUCCESS;
350}
351
PriyangaRamasamyf3295be2019-07-23 12:18:40 +0530352int encode_get_fru_record_table_req(uint8_t instance_id,
353 uint32_t data_transfer_handle,
354 uint8_t transfer_operation_flag,
355 struct pldm_msg *msg, size_t payload_length)
356
357{
358 struct pldm_header_info header = {0};
359 int rc = PLDM_ERROR_INVALID_DATA;
360
361 header.msg_type = PLDM_REQUEST;
362 header.instance = instance_id;
363 header.pldm_type = PLDM_FRU;
364 header.command = PLDM_GET_FRU_RECORD_TABLE;
365
366 if (msg == NULL) {
367 return rc;
368 }
369 if (payload_length != sizeof(struct pldm_get_fru_record_table_req)) {
370 return PLDM_ERROR_INVALID_LENGTH;
371 }
372 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
373 return rc;
374 }
375
376 struct pldm_get_fru_record_table_req *req =
377 (struct pldm_get_fru_record_table_req *)msg->payload;
378 req->data_transfer_handle = htole32(data_transfer_handle);
379 req->transfer_operation_flag = transfer_operation_flag;
380
381 return PLDM_SUCCESS;
382}
383
384int decode_get_fru_record_table_resp(
385 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
386 uint32_t *next_data_transfer_handle, uint8_t *transfer_flag,
387 uint8_t *fru_record_table_data, size_t *fru_record_table_length)
388{
389 if (msg == NULL || completion_code == NULL ||
390 next_data_transfer_handle == NULL || transfer_flag == NULL ||
391 fru_record_table_data == NULL || fru_record_table_length == NULL) {
392 return PLDM_ERROR_INVALID_DATA;
393 }
394
395 *completion_code = msg->payload[0];
396 if (PLDM_SUCCESS != *completion_code) {
397 return PLDM_SUCCESS;
398 }
399 if (payload_length <= PLDM_GET_FRU_RECORD_TABLE_MIN_RESP_BYTES) {
400 return PLDM_ERROR_INVALID_LENGTH;
401 }
402
403 struct pldm_get_fru_record_table_resp *resp =
404 (struct pldm_get_fru_record_table_resp *)msg->payload;
405
406 *next_data_transfer_handle = le32toh(resp->next_data_transfer_handle);
407 *transfer_flag = resp->transfer_flag;
408 memcpy(fru_record_table_data, resp->fru_record_table_data,
409 payload_length - PLDM_GET_FRU_RECORD_TABLE_MIN_RESP_BYTES);
410 *fru_record_table_length =
411 payload_length - PLDM_GET_FRU_RECORD_TABLE_MIN_RESP_BYTES;
412
413 return PLDM_SUCCESS;
414}