blob: 684a5594ce587d2a41004ae7cb8943a6e6ab4f33 [file] [log] [blame]
Andrew Jeffery9c766792022-08-10 23:12:49 +09301#include <assert.h>
2#include <endian.h>
3#include <stdbool.h>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05304#include <stdint.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +09305#include <string.h>
6
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05307#include "base.h"
Andrew Jeffery9c766792022-08-10 23:12:49 +09308#include "fru.h"
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05309#include "utils.h"
Andrew Jeffery9c766792022-08-10 23:12:49 +093010
11int encode_get_fru_record_table_metadata_req(uint8_t instance_id,
12 struct pldm_msg *msg,
13 size_t payload_length)
14{
15 if (msg == NULL) {
16 return PLDM_ERROR_INVALID_DATA;
17 }
18
19 if (payload_length != PLDM_GET_FRU_RECORD_TABLE_METADATA_REQ_BYTES) {
20 return PLDM_ERROR_INVALID_LENGTH;
21 }
22
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093023 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +093024 header.instance = instance_id;
25 header.msg_type = PLDM_REQUEST;
26 header.pldm_type = PLDM_FRU;
27 header.command = PLDM_GET_FRU_RECORD_TABLE_METADATA;
28
29 return pack_pldm_header(&header, &(msg->hdr));
30}
31
32int decode_get_fru_record_table_metadata_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093033 const struct pldm_msg *msg, size_t payload_length,
34 uint8_t *completion_code, uint8_t *fru_data_major_version,
35 uint8_t *fru_data_minor_version, uint32_t *fru_table_maximum_size,
36 uint32_t *fru_table_length, uint16_t *total_record_set_identifiers,
37 uint16_t *total_table_records, uint32_t *checksum)
Andrew Jeffery9c766792022-08-10 23:12:49 +093038{
39 if (msg == NULL || completion_code == NULL ||
40 fru_data_major_version == NULL || fru_data_minor_version == NULL ||
41 fru_table_maximum_size == NULL || fru_table_length == NULL ||
42 total_record_set_identifiers == NULL ||
43 total_table_records == NULL || checksum == NULL) {
44 return PLDM_ERROR_INVALID_DATA;
45 }
46
47 *completion_code = msg->payload[0];
48 if (PLDM_SUCCESS != *completion_code) {
49 return PLDM_SUCCESS;
50 }
51
52 if (payload_length != PLDM_GET_FRU_RECORD_TABLE_METADATA_RESP_BYTES) {
53 return PLDM_ERROR_INVALID_LENGTH;
54 }
55
56 struct pldm_get_fru_record_table_metadata_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093057 (struct pldm_get_fru_record_table_metadata_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +093058
59 *fru_data_major_version = response->fru_data_major_version;
60 *fru_data_minor_version = response->fru_data_minor_version;
61 *fru_table_maximum_size = le32toh(response->fru_table_maximum_size);
62 *fru_table_length = le32toh(response->fru_table_length);
63 *total_record_set_identifiers =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093064 le16toh(response->total_record_set_identifiers);
Andrew Jeffery9c766792022-08-10 23:12:49 +093065 *total_table_records = le16toh(response->total_table_records);
66 *checksum = le32toh(response->checksum);
67
68 return PLDM_SUCCESS;
69}
70
71int encode_get_fru_record_table_metadata_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093072 uint8_t instance_id, uint8_t completion_code,
73 uint8_t fru_data_major_version, uint8_t fru_data_minor_version,
74 uint32_t fru_table_maximum_size, uint32_t fru_table_length,
75 uint16_t total_record_set_identifiers, uint16_t total_table_records,
76 uint32_t checksum, struct pldm_msg *msg)
Andrew Jeffery9c766792022-08-10 23:12:49 +093077{
78 if (msg == NULL) {
79 return PLDM_ERROR_INVALID_DATA;
80 }
81
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093082 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +093083 header.msg_type = PLDM_RESPONSE;
84 header.instance = instance_id;
85 header.pldm_type = PLDM_FRU;
86 header.command = PLDM_GET_FRU_RECORD_TABLE_METADATA;
87
88 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
89 if (PLDM_SUCCESS != rc) {
90 return rc;
91 }
92
93 struct pldm_get_fru_record_table_metadata_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +093094 (struct pldm_get_fru_record_table_metadata_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +093095 response->completion_code = completion_code;
96 if (response->completion_code == PLDM_SUCCESS) {
97 response->fru_data_major_version = fru_data_major_version;
98 response->fru_data_minor_version = fru_data_minor_version;
99 response->fru_table_maximum_size =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930100 htole32(fru_table_maximum_size);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930101 response->fru_table_length = htole32(fru_table_length);
102 response->total_record_set_identifiers =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930103 htole16(total_record_set_identifiers);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930104 response->total_table_records = htole16(total_table_records);
105 response->checksum = htole32(checksum);
106 }
107
108 return PLDM_SUCCESS;
109}
110
111int decode_get_fru_record_table_req(const struct pldm_msg *msg,
112 size_t payload_length,
113 uint32_t *data_transfer_handle,
114 uint8_t *transfer_operation_flag)
115{
116 if (msg == NULL || data_transfer_handle == NULL ||
117 transfer_operation_flag == NULL) {
118 return PLDM_ERROR_INVALID_DATA;
119 }
120
121 if (payload_length != PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES) {
122 return PLDM_ERROR_INVALID_LENGTH;
123 }
124
125 struct pldm_get_fru_record_table_req *req =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930126 (struct pldm_get_fru_record_table_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930127
128 *data_transfer_handle = le32toh(req->data_transfer_handle);
129 *transfer_operation_flag = req->transfer_operation_flag;
130
131 return PLDM_SUCCESS;
132}
133
134int encode_get_fru_record_table_resp(uint8_t instance_id,
135 uint8_t completion_code,
136 uint32_t next_data_transfer_handle,
137 uint8_t transfer_flag,
138 struct pldm_msg *msg)
139{
140 if (msg == NULL) {
141 return PLDM_ERROR_INVALID_DATA;
142 }
143
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930144 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930145 header.msg_type = PLDM_RESPONSE;
146 header.instance = instance_id;
147 header.pldm_type = PLDM_FRU;
148 header.command = PLDM_GET_FRU_RECORD_TABLE;
149
150 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
151 if (rc > PLDM_SUCCESS) {
152 return rc;
153 }
154
155 struct pldm_get_fru_record_table_resp *resp =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930156 (struct pldm_get_fru_record_table_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930157
158 resp->completion_code = completion_code;
159
160 if (resp->completion_code == PLDM_SUCCESS) {
Andrew Jeffery9c766792022-08-10 23:12:49 +0930161 resp->next_data_transfer_handle =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930162 htole32(next_data_transfer_handle);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930163 resp->transfer_flag = transfer_flag;
164 }
165
166 return PLDM_SUCCESS;
167}
168
169int encode_fru_record(uint8_t *fru_table, size_t total_size, size_t *curr_size,
170 uint16_t record_set_id, uint8_t record_type,
171 uint8_t num_frus, uint8_t encoding, uint8_t *tlvs,
172 size_t tlvs_size)
173{
174 size_t record_hdr_size = sizeof(struct pldm_fru_record_data_format) -
175 sizeof(struct pldm_fru_record_tlv);
176
177 if (fru_table == NULL || curr_size == NULL || !tlvs_size) {
178 return PLDM_ERROR_INVALID_DATA;
179 }
180 if ((*curr_size + record_hdr_size + tlvs_size) != total_size) {
181 return PLDM_ERROR_INVALID_LENGTH;
182 }
183
184 struct pldm_fru_record_data_format *record =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930185 (struct pldm_fru_record_data_format *)(fru_table + *curr_size);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930186 record->record_set_id = htole16(record_set_id);
187 record->record_type = record_type;
188 record->num_fru_fields = num_frus;
189 record->encoding_type = encoding;
190 *curr_size += record_hdr_size;
191
192 if (tlvs) {
193 memcpy(fru_table + *curr_size, tlvs, tlvs_size);
194 *curr_size += tlvs_size;
195 }
196
197 return PLDM_SUCCESS;
198}
199
200static bool is_table_end(const struct pldm_fru_record_data_format *p,
201 const void *table, size_t table_size)
202{
203 return p ==
204 (const struct pldm_fru_record_data_format *)((uint8_t *)table +
205 table_size);
206}
207
208void get_fru_record_by_option(const uint8_t *table, size_t table_size,
209 uint8_t *record_table, size_t *record_size,
210 uint16_t rsi, uint8_t rt, uint8_t ft)
211{
212 const struct pldm_fru_record_data_format *record_data_src =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930213 (const struct pldm_fru_record_data_format *)table;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930214 struct pldm_fru_record_data_format *record_data_dest;
215 int count = 0;
216
217 const struct pldm_fru_record_tlv *tlv;
218 size_t len;
219 uint8_t *pos = record_table;
220
221 while (!is_table_end(record_data_src, table, table_size)) {
222 if ((record_data_src->record_set_id != htole16(rsi) &&
223 rsi != 0) ||
224 (record_data_src->record_type != rt && rt != 0)) {
225 tlv = record_data_src->tlvs;
226 for (int i = 0; i < record_data_src->num_fru_fields;
227 i++) {
228 len = sizeof(*tlv) - 1 + tlv->length;
229 tlv = (const struct pldm_fru_record_tlv
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930230 *)((char *)tlv + len);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930231 }
232 record_data_src =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930233 (const struct pldm_fru_record_data_format
234 *)(tlv);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930235 continue;
236 }
237
238 len = sizeof(struct pldm_fru_record_data_format) -
239 sizeof(struct pldm_fru_record_tlv);
240
241 assert(pos - record_table + len < *record_size);
242 memcpy(pos, record_data_src, len);
243
244 record_data_dest = (struct pldm_fru_record_data_format *)pos;
245 pos += len;
246
247 tlv = record_data_src->tlvs;
248 count = 0;
249 for (int i = 0; i < record_data_src->num_fru_fields; i++) {
250 len = sizeof(*tlv) - 1 + tlv->length;
251 if (tlv->type == ft || ft == 0) {
252 assert(pos - record_table + len < *record_size);
253 memcpy(pos, tlv, len);
254 pos += len;
255 count++;
256 }
257 tlv = (const struct pldm_fru_record_tlv *)((char *)tlv +
258 len);
259 }
260 record_data_dest->num_fru_fields = count;
261 record_data_src =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930262 (const struct pldm_fru_record_data_format *)(tlv);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930263 }
264
265 *record_size = pos - record_table;
266}
267
268int encode_get_fru_record_by_option_req(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930269 uint8_t instance_id, uint32_t data_transfer_handle,
270 uint16_t fru_table_handle, uint16_t record_set_identifier,
271 uint8_t record_type, uint8_t field_type, uint8_t transfer_op_flag,
272 struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930273{
Andrew Jeffery9c766792022-08-10 23:12:49 +0930274 if (msg == NULL) {
275 return PLDM_ERROR_INVALID_DATA;
276 }
277
278 if (payload_length !=
279 sizeof(struct pldm_get_fru_record_by_option_req)) {
280 return PLDM_ERROR_INVALID_LENGTH;
281 }
282
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930283 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930284 header.instance = instance_id;
285 header.msg_type = PLDM_REQUEST;
286 header.pldm_type = PLDM_FRU;
287 header.command = PLDM_GET_FRU_RECORD_BY_OPTION;
288 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
289 if (rc != PLDM_SUCCESS) {
290 return rc;
291 }
292
293 struct pldm_get_fru_record_by_option_req *req =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930294 (struct pldm_get_fru_record_by_option_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930295
296 req->data_transfer_handle = htole32(data_transfer_handle);
297 req->fru_table_handle = htole16(fru_table_handle);
298 req->record_set_identifier = htole16(record_set_identifier);
299 req->record_type = record_type;
300 req->field_type = field_type;
301 req->transfer_op_flag = transfer_op_flag;
302
303 return PLDM_SUCCESS;
304}
305
306int decode_get_fru_record_by_option_req(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930307 const struct pldm_msg *msg, size_t payload_length,
308 uint32_t *data_transfer_handle, uint16_t *fru_table_handle,
309 uint16_t *record_set_identifier, uint8_t *record_type,
310 uint8_t *field_type, uint8_t *transfer_op_flag)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930311{
312 if (msg == NULL || data_transfer_handle == NULL ||
313 fru_table_handle == NULL || record_set_identifier == NULL ||
314 record_type == NULL || field_type == NULL ||
315 transfer_op_flag == NULL) {
316 return PLDM_ERROR_INVALID_DATA;
317 }
318
319 if (payload_length !=
320 sizeof(struct pldm_get_fru_record_by_option_req)) {
321 return PLDM_ERROR_INVALID_LENGTH;
322 }
323
324 struct pldm_get_fru_record_by_option_req *req =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930325 (struct pldm_get_fru_record_by_option_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930326
327 *data_transfer_handle = le32toh(req->data_transfer_handle);
328 *fru_table_handle = le16toh(req->fru_table_handle);
329 *record_set_identifier = le16toh(req->record_set_identifier);
330 *record_type = req->record_type;
331 *field_type = req->field_type;
332 *transfer_op_flag = req->transfer_op_flag;
333 return PLDM_SUCCESS;
334}
335
336int encode_get_fru_record_by_option_resp(uint8_t instance_id,
337 uint8_t completion_code,
338 uint32_t next_data_transfer_handle,
339 uint8_t transfer_flag,
340 const void *fru_structure_data,
341 size_t data_size, struct pldm_msg *msg,
342 size_t payload_length)
343{
344 if (msg == NULL || fru_structure_data == NULL) {
345 return PLDM_ERROR_INVALID_DATA;
346 }
347
348 if (payload_length !=
349 PLDM_GET_FRU_RECORD_BY_OPTION_MIN_RESP_BYTES + data_size) {
350 return PLDM_ERROR_INVALID_LENGTH;
351 }
352
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930353 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930354 header.instance = instance_id;
355 header.msg_type = PLDM_RESPONSE;
356 header.pldm_type = PLDM_FRU;
357 header.command = PLDM_GET_FRU_RECORD_BY_OPTION;
358 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
359 if (rc != PLDM_SUCCESS) {
360 return rc;
361 }
362
363 struct pldm_get_fru_record_by_option_resp *resp =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930364 (struct pldm_get_fru_record_by_option_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930365
366 resp->completion_code = completion_code;
367 resp->next_data_transfer_handle = htole32(next_data_transfer_handle);
368 resp->transfer_flag = transfer_flag;
369
370 if (completion_code == PLDM_SUCCESS) {
371 memcpy(resp->fru_structure_data, fru_structure_data, data_size);
372 }
373
374 return PLDM_SUCCESS;
375}
376
377int decode_get_fru_record_by_option_resp(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930378 const struct pldm_msg *msg, size_t payload_length,
379 uint8_t *completion_code, uint32_t *next_transfer_handle,
380 uint8_t *transfer_flag, struct variable_field *fru_structure_data)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930381{
382 if (msg == NULL || completion_code == NULL ||
383 next_transfer_handle == NULL || transfer_flag == NULL ||
384 fru_structure_data == NULL) {
385 return PLDM_ERROR_INVALID_DATA;
386 }
387
388 *completion_code = msg->payload[0];
389 if (PLDM_SUCCESS != *completion_code) {
390 return PLDM_SUCCESS;
391 }
392
393 if (payload_length < PLDM_GET_FRU_RECORD_BY_OPTION_MIN_RESP_BYTES) {
394 return PLDM_ERROR_INVALID_LENGTH;
395 }
396
397 struct pldm_get_fru_record_by_option_resp *resp =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930398 (struct pldm_get_fru_record_by_option_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930399
400 *next_transfer_handle = le32toh(resp->next_data_transfer_handle);
401 *transfer_flag = resp->transfer_flag;
402 fru_structure_data->ptr = resp->fru_structure_data;
403 fru_structure_data->length =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930404 payload_length - PLDM_GET_FRU_RECORD_BY_OPTION_MIN_RESP_BYTES;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930405
406 return PLDM_SUCCESS;
407}
408
409int encode_get_fru_record_table_req(uint8_t instance_id,
410 uint32_t data_transfer_handle,
411 uint8_t transfer_operation_flag,
412 struct pldm_msg *msg, size_t payload_length)
413
414{
415 if (msg == NULL) {
416 return PLDM_ERROR_INVALID_DATA;
417 }
418 if (payload_length != sizeof(struct pldm_get_fru_record_table_req)) {
419 return PLDM_ERROR_INVALID_LENGTH;
420 }
421
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930422 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930423 header.msg_type = PLDM_REQUEST;
424 header.instance = instance_id;
425 header.pldm_type = PLDM_FRU;
426 header.command = PLDM_GET_FRU_RECORD_TABLE;
427
428 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
429 if (rc != PLDM_SUCCESS) {
430 return rc;
431 }
432
433 struct pldm_get_fru_record_table_req *req =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930434 (struct pldm_get_fru_record_table_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930435 req->data_transfer_handle = htole32(data_transfer_handle);
436 req->transfer_operation_flag = transfer_operation_flag;
437
438 return PLDM_SUCCESS;
439}
440
441int decode_get_fru_record_table_resp_safe(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930442 const struct pldm_msg *msg, size_t payload_length,
443 uint8_t *completion_code, uint32_t *next_data_transfer_handle,
444 uint8_t *transfer_flag, uint8_t *fru_record_table_data,
445 size_t *fru_record_table_length, size_t max_fru_record_table_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930446{
447 if (msg == NULL || completion_code == NULL ||
448 next_data_transfer_handle == NULL || transfer_flag == NULL ||
449 fru_record_table_data == NULL || fru_record_table_length == NULL) {
450 return PLDM_ERROR_INVALID_DATA;
451 }
452
453 *completion_code = msg->payload[0];
454 if (PLDM_SUCCESS != *completion_code) {
455 return PLDM_SUCCESS;
456 }
457 if (payload_length <= PLDM_GET_FRU_RECORD_TABLE_MIN_RESP_BYTES) {
458 return PLDM_ERROR_INVALID_LENGTH;
459 }
460
461 struct pldm_get_fru_record_table_resp *resp =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930462 (struct pldm_get_fru_record_table_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930463
464 *next_data_transfer_handle = le32toh(resp->next_data_transfer_handle);
465 *transfer_flag = resp->transfer_flag;
466
467 *fru_record_table_length =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930468 payload_length - PLDM_GET_FRU_RECORD_TABLE_MIN_RESP_BYTES;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930469
470 if (*fru_record_table_length > max_fru_record_table_length) {
471 return PLDM_ERROR_INVALID_LENGTH;
472 }
473
474 memcpy(fru_record_table_data, resp->fru_record_table_data,
475 *fru_record_table_length);
476
477 return PLDM_SUCCESS;
478}
479
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930480int decode_get_fru_record_table_resp(const struct pldm_msg *msg,
481 size_t payload_length,
482 uint8_t *completion_code,
483 uint32_t *next_data_transfer_handle,
484 uint8_t *transfer_flag,
485 uint8_t *fru_record_table_data,
486 size_t *fru_record_table_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930487{
488 return decode_get_fru_record_table_resp_safe(
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930489 msg, payload_length, completion_code, next_data_transfer_handle,
490 transfer_flag, fru_record_table_data, fru_record_table_length,
491 (size_t)-1);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930492}
493
494int decode_set_fru_record_table_req(const struct pldm_msg *msg,
495 size_t payload_length,
496 uint32_t *data_transfer_handle,
497 uint8_t *transfer_flag,
498 struct variable_field *fru_table_data)
499
500{
501 if (msg == NULL || data_transfer_handle == NULL ||
502 transfer_flag == NULL || fru_table_data == NULL) {
503 return PLDM_ERROR_INVALID_DATA;
504 }
505
506 if (payload_length <= PLDM_SET_FRU_RECORD_TABLE_MIN_REQ_BYTES) {
507 return PLDM_ERROR_INVALID_LENGTH;
508 }
509
510 struct pldm_set_fru_record_table_req *req =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930511 (struct pldm_set_fru_record_table_req *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930512
513 *data_transfer_handle = le32toh(req->data_transfer_handle);
514 *transfer_flag = req->transfer_flag;
515 fru_table_data->length =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930516 payload_length - PLDM_SET_FRU_RECORD_TABLE_MIN_REQ_BYTES;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930517 fru_table_data->ptr = req->fru_record_table_data;
518
519 return PLDM_SUCCESS;
520}
521
522int encode_set_fru_record_table_resp(uint8_t instance_id,
523 uint8_t completion_code,
524 uint32_t next_data_transfer_handle,
525 size_t payload_length,
526 struct pldm_msg *msg)
527{
528 if (msg == NULL) {
529 return PLDM_ERROR_INVALID_DATA;
530 }
531 if (payload_length != PLDM_SET_FRU_RECORD_TABLE_RESP_BYTES) {
532 return PLDM_ERROR_INVALID_LENGTH;
533 }
534
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930535 struct pldm_header_info header = { 0 };
Andrew Jeffery9c766792022-08-10 23:12:49 +0930536 header.instance = instance_id;
537 header.msg_type = PLDM_RESPONSE;
538 header.pldm_type = PLDM_FRU;
539 header.command = PLDM_SET_FRU_RECORD_TABLE;
540
541 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
542 if (PLDM_SUCCESS != rc) {
543 return rc;
544 }
545
546 struct pldm_set_fru_record_table_resp *response =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930547 (struct pldm_set_fru_record_table_resp *)msg->payload;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930548 response->completion_code = completion_code;
549 response->next_data_transfer_handle =
Andrew Jeffery37dd6a32023-05-12 16:04:06 +0930550 htole32(next_data_transfer_handle);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930551
552 return PLDM_SUCCESS;
553}