1 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
2 #include "api.h"
3 #include "compiler.h"
4 #include "dsp/base.h"
5 #include "msgbuf.h"
6 #include "msgbuf/platform.h"
7
8 #include <libpldm/base.h>
9 #include <libpldm/platform.h>
10 #include <libpldm/pldm_types.h>
11
12 #include <endian.h>
13 #include <stdint.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <uchar.h>
17
18 LIBPLDM_ABI_STABLE
encode_state_effecter_pdr(struct pldm_state_effecter_pdr * const effecter,const size_t allocation_size,const struct state_effecter_possible_states * const possible_states,const size_t possible_states_size,size_t * const actual_size)19 int encode_state_effecter_pdr(
20 struct pldm_state_effecter_pdr *const effecter,
21 const size_t allocation_size,
22 const struct state_effecter_possible_states *const possible_states,
23 const size_t possible_states_size, size_t *const actual_size)
24 {
25 size_t calculated_possible_states_size = 0;
26
27 if (!effecter || !possible_states || !actual_size) {
28 return PLDM_ERROR;
29 }
30
31 if (SIZE_MAX - (sizeof(*effecter) - sizeof(effecter->possible_states)) <
32 possible_states_size) {
33 return PLDM_ERROR;
34 }
35
36 if (allocation_size <
37 (sizeof(*effecter) - sizeof(effecter->possible_states)) +
38 possible_states_size) {
39 return PLDM_ERROR_INVALID_LENGTH;
40 }
41
42 // Encode possible states
43
44 {
45 char *states_ptr = (char *)possible_states;
46 char *const begin_states_ptr = states_ptr;
47
48 for (int i = 0; i < effecter->composite_effecter_count; ++i) {
49 struct state_effecter_possible_states *states =
50 (struct state_effecter_possible_states *)
51 states_ptr;
52
53 HTOLE16(states->state_set_id);
54
55 states_ptr +=
56 (sizeof(*states) - sizeof(states->states) +
57 states->possible_states_size);
58 }
59
60 calculated_possible_states_size = states_ptr - begin_states_ptr;
61 }
62
63 // Check lengths
64
65 if (possible_states_size != calculated_possible_states_size) {
66 *actual_size = 0;
67 return PLDM_ERROR;
68 }
69
70 *actual_size =
71 (sizeof(struct pldm_state_effecter_pdr) + possible_states_size -
72 sizeof(effecter->possible_states));
73
74 // Encode rest of PDR
75
76 effecter->hdr.version = 1;
77 effecter->hdr.type = PLDM_STATE_EFFECTER_PDR;
78 effecter->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
79
80 memcpy(effecter->possible_states, possible_states,
81 possible_states_size);
82
83 // Convert effecter PDR body
84 HTOLE16(effecter->terminus_handle);
85 HTOLE16(effecter->effecter_id);
86 HTOLE16(effecter->entity_type);
87 HTOLE16(effecter->entity_instance);
88 HTOLE16(effecter->container_id);
89 HTOLE16(effecter->effecter_semantic_id);
90
91 // Convert header
92 HTOLE32(effecter->hdr.record_handle);
93 HTOLE16(effecter->hdr.record_change_num);
94 HTOLE16(effecter->hdr.length);
95
96 return PLDM_SUCCESS;
97 }
98
99 LIBPLDM_ABI_STABLE
encode_state_sensor_pdr(struct pldm_state_sensor_pdr * const sensor,const size_t allocation_size,const struct state_sensor_possible_states * const possible_states,const size_t possible_states_size,size_t * const actual_size)100 int encode_state_sensor_pdr(
101 struct pldm_state_sensor_pdr *const sensor,
102 const size_t allocation_size,
103 const struct state_sensor_possible_states *const possible_states,
104 const size_t possible_states_size, size_t *const actual_size)
105 {
106 size_t calculated_possible_states_size = 0;
107
108 if (!sensor || !possible_states || !actual_size) {
109 return PLDM_ERROR;
110 }
111
112 if (SIZE_MAX - (sizeof(*sensor) - sizeof(sensor->possible_states)) <
113 possible_states_size) {
114 return PLDM_ERROR;
115 }
116
117 if (allocation_size <
118 (sizeof(*sensor) - sizeof(sensor->possible_states) +
119 possible_states_size)) {
120 return PLDM_ERROR_INVALID_LENGTH;
121 }
122
123 {
124 // Encode possible states
125 char *states_ptr = (char *)possible_states;
126 char *const begin_states_ptr = states_ptr;
127
128 for (int i = 0; i < sensor->composite_sensor_count; ++i) {
129 struct state_sensor_possible_states *states =
130 (struct state_sensor_possible_states *)
131 states_ptr;
132
133 HTOLE16(states->state_set_id);
134
135 states_ptr +=
136 (sizeof(*states) - sizeof(states->states) +
137 states->possible_states_size);
138 }
139
140 calculated_possible_states_size = states_ptr - begin_states_ptr;
141 }
142
143 // Check lengths
144
145 if (possible_states_size != calculated_possible_states_size) {
146 *actual_size = 0;
147 return PLDM_ERROR;
148 }
149
150 *actual_size = (sizeof(struct pldm_state_sensor_pdr) +
151 possible_states_size - sizeof(sensor->possible_states));
152
153 // Encode rest of PDR
154
155 sensor->hdr.version = 1;
156 sensor->hdr.type = PLDM_STATE_SENSOR_PDR;
157 sensor->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
158
159 memcpy(sensor->possible_states, possible_states, possible_states_size);
160
161 // Convert sensor PDR body
162 HTOLE16(sensor->terminus_handle);
163 HTOLE16(sensor->sensor_id);
164 HTOLE16(sensor->entity_type);
165 HTOLE16(sensor->entity_instance);
166 HTOLE16(sensor->container_id);
167
168 // Convert header
169 HTOLE32(sensor->hdr.record_handle);
170 HTOLE16(sensor->hdr.record_change_num);
171 HTOLE16(sensor->hdr.length);
172
173 return PLDM_SUCCESS;
174 }
175
176 LIBPLDM_ABI_STABLE
encode_set_state_effecter_states_resp(uint8_t instance_id,uint8_t completion_code,struct pldm_msg * msg)177 int encode_set_state_effecter_states_resp(uint8_t instance_id,
178 uint8_t completion_code,
179 struct pldm_msg *msg)
180 {
181 if (msg == NULL) {
182 return PLDM_ERROR_INVALID_DATA;
183 }
184
185 struct pldm_header_info header = { 0 };
186 header.msg_type = PLDM_RESPONSE;
187 header.instance = instance_id;
188 header.pldm_type = PLDM_PLATFORM;
189 header.command = PLDM_SET_STATE_EFFECTER_STATES;
190
191 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
192 if (rc != PLDM_SUCCESS) {
193 return rc;
194 }
195
196 msg->payload[0] = completion_code;
197
198 return PLDM_SUCCESS;
199 }
200
201 LIBPLDM_ABI_STABLE
encode_set_state_effecter_states_req(uint8_t instance_id,uint16_t effecter_id,uint8_t comp_effecter_count,set_effecter_state_field * field,struct pldm_msg * msg)202 int encode_set_state_effecter_states_req(uint8_t instance_id,
203 uint16_t effecter_id,
204 uint8_t comp_effecter_count,
205 set_effecter_state_field *field,
206 struct pldm_msg *msg)
207 {
208 if (msg == NULL) {
209 return PLDM_ERROR_INVALID_DATA;
210 }
211
212 if (comp_effecter_count < 0x1 || comp_effecter_count > 0x8 ||
213 field == NULL) {
214 return PLDM_ERROR_INVALID_DATA;
215 }
216
217 struct pldm_header_info header = { 0 };
218 header.msg_type = PLDM_REQUEST;
219 header.instance = instance_id;
220 header.pldm_type = PLDM_PLATFORM;
221 header.command = PLDM_SET_STATE_EFFECTER_STATES;
222
223 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
224 if (rc != PLDM_SUCCESS) {
225 return rc;
226 }
227
228 struct pldm_set_state_effecter_states_req *request =
229 (struct pldm_set_state_effecter_states_req *)msg->payload;
230 effecter_id = htole16(effecter_id);
231 request->effecter_id = effecter_id;
232 request->comp_effecter_count = comp_effecter_count;
233 memcpy(request->field, field,
234 (sizeof(set_effecter_state_field) * comp_effecter_count));
235
236 return PLDM_SUCCESS;
237 }
238
239 LIBPLDM_ABI_STABLE
decode_set_state_effecter_states_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code)240 int decode_set_state_effecter_states_resp(const struct pldm_msg *msg,
241 size_t payload_length,
242 uint8_t *completion_code)
243 {
244 if (msg == NULL || completion_code == NULL) {
245 return PLDM_ERROR_INVALID_DATA;
246 }
247
248 *completion_code = msg->payload[0];
249 if (PLDM_SUCCESS != *completion_code) {
250 return PLDM_SUCCESS;
251 }
252
253 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES) {
254 return PLDM_ERROR_INVALID_LENGTH;
255 }
256
257 return PLDM_SUCCESS;
258 }
259
260 #define PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE 3
261 LIBPLDM_ABI_STABLE
decode_set_state_effecter_states_req(const struct pldm_msg * msg,size_t payload_length,uint16_t * effecter_id,uint8_t * comp_effecter_count,set_effecter_state_field * field)262 int decode_set_state_effecter_states_req(const struct pldm_msg *msg,
263 size_t payload_length,
264 uint16_t *effecter_id,
265 uint8_t *comp_effecter_count,
266 set_effecter_state_field *field)
267 {
268 PLDM_MSGBUF_DEFINE_P(buf);
269 int rc;
270 int i;
271
272 if (msg == NULL || effecter_id == NULL || comp_effecter_count == NULL ||
273 field == NULL) {
274 return PLDM_ERROR_INVALID_DATA;
275 }
276
277 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) {
278 return PLDM_ERROR_INVALID_LENGTH;
279 }
280
281 rc = pldm_msgbuf_init_errno(buf,
282 PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE,
283 msg->payload, payload_length);
284 if (rc) {
285 return pldm_xlate_errno(rc);
286 }
287
288 pldm_msgbuf_extract_p(buf, effecter_id);
289 rc = pldm_msgbuf_extract_p(buf, comp_effecter_count);
290 if (rc) {
291 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
292 }
293
294 if (*comp_effecter_count > 8) {
295 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
296 }
297
298 for (i = 0; i < *comp_effecter_count; i++) {
299 pldm_msgbuf_extract(buf, field[i].set_request);
300 pldm_msgbuf_extract(buf, field[i].effecter_state);
301 }
302
303 rc = pldm_msgbuf_complete(buf);
304 if (rc) {
305 return pldm_xlate_errno(rc);
306 }
307
308 return PLDM_SUCCESS;
309 }
310
311 LIBPLDM_ABI_STABLE
decode_get_pdr_req(const struct pldm_msg * msg,size_t payload_length,uint32_t * record_hndl,uint32_t * data_transfer_hndl,uint8_t * transfer_op_flag,uint16_t * request_cnt,uint16_t * record_chg_num)312 int decode_get_pdr_req(const struct pldm_msg *msg, size_t payload_length,
313 uint32_t *record_hndl, uint32_t *data_transfer_hndl,
314 uint8_t *transfer_op_flag, uint16_t *request_cnt,
315 uint16_t *record_chg_num)
316 {
317 PLDM_MSGBUF_DEFINE_P(buf);
318 int rc;
319
320 if (msg == NULL || record_hndl == NULL || data_transfer_hndl == NULL ||
321 transfer_op_flag == NULL || request_cnt == NULL ||
322 record_chg_num == NULL) {
323 return PLDM_ERROR_INVALID_DATA;
324 }
325
326 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
327 return PLDM_ERROR_INVALID_LENGTH;
328 }
329
330 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_REQ_BYTES, msg->payload,
331 payload_length);
332 if (rc) {
333 return pldm_xlate_errno(rc);
334 }
335
336 pldm_msgbuf_extract_p(buf, record_hndl);
337 pldm_msgbuf_extract_p(buf, data_transfer_hndl);
338 pldm_msgbuf_extract_p(buf, transfer_op_flag);
339 pldm_msgbuf_extract_p(buf, request_cnt);
340 pldm_msgbuf_extract_p(buf, record_chg_num);
341
342 rc = pldm_msgbuf_complete(buf);
343 if (rc) {
344 return pldm_xlate_errno(rc);
345 }
346
347 return PLDM_SUCCESS;
348 }
349
350 LIBPLDM_ABI_DEPRECATED_UNSAFE
encode_get_pdr_resp(uint8_t instance_id,uint8_t completion_code,uint32_t next_record_hndl,uint32_t next_data_transfer_hndl,uint8_t transfer_flag,uint16_t resp_cnt,const uint8_t * record_data,uint8_t transfer_crc,struct pldm_msg * msg)351 int encode_get_pdr_resp(uint8_t instance_id, uint8_t completion_code,
352 uint32_t next_record_hndl,
353 uint32_t next_data_transfer_hndl, uint8_t transfer_flag,
354 uint16_t resp_cnt, const uint8_t *record_data,
355 uint8_t transfer_crc, struct pldm_msg *msg)
356 {
357 if (msg == NULL) {
358 return PLDM_ERROR_INVALID_DATA;
359 }
360
361 struct pldm_header_info header = { 0 };
362 header.msg_type = PLDM_RESPONSE;
363 header.instance = instance_id;
364 header.pldm_type = PLDM_PLATFORM;
365 header.command = PLDM_GET_PDR;
366
367 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
368 if (rc != PLDM_SUCCESS) {
369 return rc;
370 }
371
372 struct pldm_get_pdr_resp *response =
373 (struct pldm_get_pdr_resp *)msg->payload;
374 response->completion_code = completion_code;
375
376 if (response->completion_code == PLDM_SUCCESS) {
377 response->next_record_handle = htole32(next_record_hndl);
378 response->next_data_transfer_handle =
379 htole32(next_data_transfer_hndl);
380 response->transfer_flag = transfer_flag;
381 response->response_count = htole16(resp_cnt);
382 if (record_data != NULL && resp_cnt > 0) {
383 memcpy(response->record_data, record_data, resp_cnt);
384 }
385 if (transfer_flag == PLDM_END) {
386 uint8_t *dst = msg->payload;
387 dst += (sizeof(struct pldm_get_pdr_resp) - 1) +
388 resp_cnt;
389 *dst = transfer_crc;
390 }
391 }
392
393 return PLDM_SUCCESS;
394 }
395
396 LIBPLDM_ABI_TESTING
encode_get_pdr_repository_info_req(uint8_t instance_id,struct pldm_msg * msg,size_t payload_length LIBPLDM_CC_UNUSED)397 int encode_get_pdr_repository_info_req(uint8_t instance_id,
398 struct pldm_msg *msg,
399 size_t payload_length LIBPLDM_CC_UNUSED)
400 {
401 if (!msg) {
402 return -EINVAL;
403 }
404
405 struct pldm_header_info header = { 0 };
406 header.msg_type = PLDM_REQUEST;
407 header.instance = instance_id;
408 header.pldm_type = PLDM_PLATFORM;
409 header.command = PLDM_GET_PDR_REPOSITORY_INFO;
410
411 return pack_pldm_header_errno(&header, &(msg->hdr));
412 }
413
414 LIBPLDM_ABI_STABLE
encode_get_pdr_repository_info_resp(uint8_t instance_id,uint8_t completion_code,uint8_t repository_state,const uint8_t * update_time,const uint8_t * oem_update_time,uint32_t record_count,uint32_t repository_size,uint32_t largest_record_size,uint8_t data_transfer_handle_timeout,struct pldm_msg * msg)415 int encode_get_pdr_repository_info_resp(
416 uint8_t instance_id, uint8_t completion_code, uint8_t repository_state,
417 const uint8_t *update_time, const uint8_t *oem_update_time,
418 uint32_t record_count, uint32_t repository_size,
419 uint32_t largest_record_size, uint8_t data_transfer_handle_timeout,
420 struct pldm_msg *msg)
421 {
422 if (msg == NULL) {
423 return PLDM_ERROR_INVALID_DATA;
424 }
425
426 struct pldm_header_info header = { 0 };
427 header.msg_type = PLDM_RESPONSE;
428 header.instance = instance_id;
429 header.pldm_type = PLDM_PLATFORM;
430 header.command = PLDM_GET_PDR_REPOSITORY_INFO;
431
432 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
433 if (rc != PLDM_SUCCESS) {
434 return rc;
435 }
436
437 struct pldm_pdr_repository_info_resp *response =
438 (struct pldm_pdr_repository_info_resp *)msg->payload;
439 response->completion_code = completion_code;
440
441 if (response->completion_code == PLDM_SUCCESS) {
442 response->repository_state = repository_state;
443 if (update_time != NULL) {
444 memcpy(response->update_time, update_time,
445 PLDM_TIMESTAMP104_SIZE);
446 }
447 if (oem_update_time != NULL) {
448 memcpy(response->oem_update_time, oem_update_time,
449 PLDM_TIMESTAMP104_SIZE);
450 }
451 response->record_count = htole32(record_count);
452 response->repository_size = htole32(repository_size);
453 response->largest_record_size = htole32(largest_record_size);
454 response->data_transfer_handle_timeout =
455 data_transfer_handle_timeout;
456 }
457
458 return PLDM_SUCCESS;
459 }
460
461 LIBPLDM_ABI_DEPRECATED
decode_get_pdr_repository_info_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint8_t * repository_state,uint8_t * update_time,uint8_t * oem_update_time,uint32_t * record_count,uint32_t * repository_size,uint32_t * largest_record_size,uint8_t * data_transfer_handle_timeout)462 int decode_get_pdr_repository_info_resp(
463 const struct pldm_msg *msg, size_t payload_length,
464 uint8_t *completion_code, uint8_t *repository_state,
465 uint8_t *update_time, uint8_t *oem_update_time, uint32_t *record_count,
466 uint32_t *repository_size, uint32_t *largest_record_size,
467 uint8_t *data_transfer_handle_timeout)
468 {
469 PLDM_MSGBUF_DEFINE_P(buf);
470 int rc;
471
472 if (msg == NULL || completion_code == NULL ||
473 repository_state == NULL || update_time == NULL ||
474 oem_update_time == NULL || record_count == NULL ||
475 repository_size == NULL || largest_record_size == NULL ||
476 data_transfer_handle_timeout == NULL) {
477 return PLDM_ERROR_INVALID_DATA;
478 }
479
480 rc = pldm_msgbuf_init_errno(buf,
481 PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
482 msg->payload, payload_length);
483 if (rc) {
484 return pldm_xlate_errno(rc);
485 }
486
487 rc = pldm_msgbuf_extract_p(buf, completion_code);
488 if (rc) {
489 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
490 }
491 if (PLDM_SUCCESS != *completion_code) {
492 return PLDM_SUCCESS;
493 }
494
495 rc = pldm_msgbuf_extract_p(buf, repository_state);
496 if (rc) {
497 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
498 }
499
500 if (*repository_state > PLDM_FAILED) {
501 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
502 }
503
504 /* NOTE: Memory safety */
505 rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE, update_time,
506 PLDM_TIMESTAMP104_SIZE);
507 if (rc) {
508 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
509 }
510
511 /* NOTE: Memory safety */
512 rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE,
513 oem_update_time, PLDM_TIMESTAMP104_SIZE);
514 if (rc) {
515 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
516 }
517
518 pldm_msgbuf_extract_p(buf, record_count);
519 pldm_msgbuf_extract_p(buf, repository_size);
520 pldm_msgbuf_extract_p(buf, largest_record_size);
521 pldm_msgbuf_extract_p(buf, data_transfer_handle_timeout);
522
523 rc = pldm_msgbuf_complete(buf);
524 if (rc) {
525 return pldm_xlate_errno(rc);
526 }
527
528 return PLDM_SUCCESS;
529 }
530
531 LIBPLDM_ABI_TESTING
decode_get_pdr_repository_info_resp_safe(const struct pldm_msg * msg,size_t payload_length,struct pldm_pdr_repository_info_resp * resp)532 int decode_get_pdr_repository_info_resp_safe(
533 const struct pldm_msg *msg, size_t payload_length,
534 struct pldm_pdr_repository_info_resp *resp)
535 {
536 PLDM_MSGBUF_DEFINE_P(buf);
537 int rc;
538
539 if (msg == NULL || resp == NULL) {
540 return -EINVAL;
541 }
542
543 rc = pldm_msg_has_error(msg, payload_length);
544 if (rc) {
545 resp->completion_code = rc;
546 return 0;
547 }
548
549 rc = pldm_msgbuf_init_errno(buf,
550 PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
551 msg->payload, payload_length);
552 if (rc) {
553 return rc;
554 }
555
556 rc = pldm_msgbuf_extract(buf, resp->completion_code);
557 if (rc) {
558 return pldm_msgbuf_discard(buf, rc);
559 }
560
561 pldm_msgbuf_extract(buf, resp->repository_state);
562
563 rc = pldm_msgbuf_extract_array(buf, sizeof(resp->update_time),
564 resp->update_time,
565 sizeof(resp->update_time));
566 if (rc) {
567 return pldm_msgbuf_discard(buf, rc);
568 }
569
570 rc = pldm_msgbuf_extract_array(buf, sizeof(resp->oem_update_time),
571 resp->oem_update_time,
572 sizeof(resp->oem_update_time));
573 if (rc) {
574 return pldm_msgbuf_discard(buf, rc);
575 }
576
577 pldm_msgbuf_extract(buf, resp->record_count);
578 pldm_msgbuf_extract(buf, resp->repository_size);
579 pldm_msgbuf_extract(buf, resp->largest_record_size);
580 pldm_msgbuf_extract(buf, resp->data_transfer_handle_timeout);
581
582 return pldm_msgbuf_complete_consumed(buf);
583 }
584
585 LIBPLDM_ABI_STABLE
encode_get_pdr_req(uint8_t instance_id,uint32_t record_hndl,uint32_t data_transfer_hndl,uint8_t transfer_op_flag,uint16_t request_cnt,uint16_t record_chg_num,struct pldm_msg * msg,size_t payload_length)586 int encode_get_pdr_req(uint8_t instance_id, uint32_t record_hndl,
587 uint32_t data_transfer_hndl, uint8_t transfer_op_flag,
588 uint16_t request_cnt, uint16_t record_chg_num,
589 struct pldm_msg *msg, size_t payload_length)
590 {
591 if (msg == NULL) {
592 return PLDM_ERROR_INVALID_DATA;
593 }
594
595 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
596 return PLDM_ERROR_INVALID_LENGTH;
597 }
598
599 struct pldm_header_info header = { 0 };
600 header.msg_type = PLDM_REQUEST;
601 header.instance = instance_id;
602 header.pldm_type = PLDM_PLATFORM;
603 header.command = PLDM_GET_PDR;
604
605 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
606 if (rc != PLDM_SUCCESS) {
607 return rc;
608 }
609
610 struct pldm_get_pdr_req *request =
611 (struct pldm_get_pdr_req *)msg->payload;
612 request->record_handle = htole32(record_hndl);
613 request->data_transfer_handle = htole32(data_transfer_hndl);
614 request->transfer_op_flag = transfer_op_flag;
615 request->request_count = htole16(request_cnt);
616 request->record_change_number = htole16(record_chg_num);
617
618 return PLDM_SUCCESS;
619 }
620
621 LIBPLDM_ABI_DEPRECATED
decode_get_pdr_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint32_t * next_record_hndl,uint32_t * next_data_transfer_hndl,uint8_t * transfer_flag,uint16_t * resp_cnt,uint8_t * record_data,size_t record_data_length,uint8_t * transfer_crc)622 int decode_get_pdr_resp(const struct pldm_msg *msg, size_t payload_length,
623 uint8_t *completion_code, uint32_t *next_record_hndl,
624 uint32_t *next_data_transfer_hndl,
625 uint8_t *transfer_flag, uint16_t *resp_cnt,
626 uint8_t *record_data, size_t record_data_length,
627 uint8_t *transfer_crc)
628 {
629 PLDM_MSGBUF_DEFINE_P(buf);
630 int rc;
631
632 if (msg == NULL || completion_code == NULL ||
633 next_record_hndl == NULL || next_data_transfer_hndl == NULL ||
634 transfer_flag == NULL || resp_cnt == NULL || transfer_crc == NULL) {
635 return PLDM_ERROR_INVALID_DATA;
636 }
637
638 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES,
639 msg->payload, payload_length);
640 if (rc) {
641 return pldm_xlate_errno(rc);
642 }
643
644 rc = pldm_msgbuf_extract_p(buf, completion_code);
645 if (rc) {
646 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
647 }
648
649 if (PLDM_SUCCESS != *completion_code) {
650 return pldm_msgbuf_complete(buf);
651 }
652
653 pldm_msgbuf_extract_p(buf, next_record_hndl);
654 pldm_msgbuf_extract_p(buf, next_data_transfer_hndl);
655 pldm_msgbuf_extract_p(buf, transfer_flag);
656 rc = pldm_msgbuf_extract_p(buf, resp_cnt);
657 if (rc) {
658 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
659 }
660
661 if (*resp_cnt > 0 && record_data != NULL) {
662 if (record_data_length < *resp_cnt) {
663 return pldm_msgbuf_discard(buf,
664 PLDM_ERROR_INVALID_LENGTH);
665 }
666 /* NOTE: Memory safety */
667 rc = pldm_msgbuf_extract_array(buf, *resp_cnt, record_data,
668 *resp_cnt);
669 if (rc) {
670 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
671 }
672 }
673
674 if (*transfer_flag == PLDM_END) {
675 pldm_msgbuf_extract_p(buf, transfer_crc);
676 }
677
678 rc = pldm_msgbuf_complete(buf);
679 if (rc) {
680 return pldm_xlate_errno(rc);
681 }
682
683 return PLDM_SUCCESS;
684 }
685
686 LIBPLDM_ABI_TESTING
decode_get_pdr_resp_safe(const struct pldm_msg * msg,size_t payload_length,struct pldm_get_pdr_resp * resp,size_t resp_len,uint8_t * transfer_crc)687 int decode_get_pdr_resp_safe(const struct pldm_msg *msg, size_t payload_length,
688 struct pldm_get_pdr_resp *resp, size_t resp_len,
689 uint8_t *transfer_crc)
690 {
691 PLDM_MSGBUF_DEFINE_P(buf);
692 int rc;
693
694 if (msg == NULL || resp == NULL || transfer_crc == NULL) {
695 return -EINVAL;
696 }
697
698 rc = pldm_msg_has_error(msg, payload_length);
699 if (rc) {
700 resp->completion_code = rc;
701 return 0;
702 }
703
704 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES,
705 msg->payload, payload_length);
706 if (rc) {
707 return rc;
708 }
709
710 pldm_msgbuf_extract(buf, resp->completion_code);
711 pldm_msgbuf_extract(buf, resp->next_record_handle);
712 pldm_msgbuf_extract(buf, resp->next_data_transfer_handle);
713
714 rc = pldm_msgbuf_extract(buf, resp->transfer_flag);
715 if (rc) {
716 return pldm_msgbuf_discard(buf, rc);
717 }
718
719 rc = pldm_msgbuf_extract(buf, resp->response_count);
720 if (rc) {
721 return pldm_msgbuf_discard(buf, rc);
722 }
723
724 rc = pldm_msgbuf_extract_array(
725 buf, resp->response_count, resp->record_data,
726 resp_len - (sizeof(*resp) - sizeof(resp->record_data)));
727 if (rc) {
728 return pldm_msgbuf_discard(buf, rc);
729 }
730
731 if (resp->transfer_flag == PLDM_END) {
732 pldm_msgbuf_extract_p(buf, transfer_crc);
733 }
734
735 return pldm_msgbuf_complete_consumed(buf);
736 }
737
738 LIBPLDM_ABI_STABLE
decode_set_numeric_effecter_value_req(const struct pldm_msg * msg,size_t payload_length,uint16_t * effecter_id,uint8_t * effecter_data_size,uint8_t effecter_value[4])739 int decode_set_numeric_effecter_value_req(const struct pldm_msg *msg,
740 size_t payload_length,
741 uint16_t *effecter_id,
742 uint8_t *effecter_data_size,
743 uint8_t effecter_value[4])
744 {
745 PLDM_MSGBUF_DEFINE_P(buf);
746 int rc;
747
748 if (msg == NULL || effecter_id == NULL || effecter_data_size == NULL ||
749 effecter_value == NULL) {
750 return PLDM_ERROR_INVALID_DATA;
751 }
752
753 rc = pldm_msgbuf_init_errno(
754 buf, PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES,
755 msg->payload, payload_length);
756 if (rc) {
757 return pldm_xlate_errno(rc);
758 }
759
760 pldm_msgbuf_extract_p(buf, effecter_id);
761 rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
762 if (rc) {
763 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
764 }
765
766 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
767 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
768 }
769
770 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
771 effecter_value);
772
773 rc = pldm_msgbuf_complete(buf);
774 if (rc) {
775 return pldm_xlate_errno(rc);
776 }
777
778 return PLDM_SUCCESS;
779 }
780
781 LIBPLDM_ABI_STABLE
encode_set_numeric_effecter_value_resp(uint8_t instance_id,uint8_t completion_code,struct pldm_msg * msg,size_t payload_length)782 int encode_set_numeric_effecter_value_resp(uint8_t instance_id,
783 uint8_t completion_code,
784 struct pldm_msg *msg,
785 size_t payload_length)
786 {
787 if (msg == NULL) {
788 return PLDM_ERROR_INVALID_DATA;
789 }
790
791 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
792 return PLDM_ERROR_INVALID_LENGTH;
793 }
794
795 struct pldm_header_info header = { 0 };
796 header.msg_type = PLDM_RESPONSE;
797 header.instance = instance_id;
798 header.pldm_type = PLDM_PLATFORM;
799 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
800
801 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
802 if (rc != PLDM_SUCCESS) {
803 return rc;
804 }
805
806 msg->payload[0] = completion_code;
807
808 return rc;
809 }
810
811 LIBPLDM_ABI_STABLE
encode_set_numeric_effecter_value_req(uint8_t instance_id,uint16_t effecter_id,uint8_t effecter_data_size,const uint8_t * effecter_value,struct pldm_msg * msg,size_t payload_length)812 int encode_set_numeric_effecter_value_req(uint8_t instance_id,
813 uint16_t effecter_id,
814 uint8_t effecter_data_size,
815 const uint8_t *effecter_value,
816 struct pldm_msg *msg,
817 size_t payload_length)
818 {
819 if (msg == NULL || effecter_value == NULL) {
820 return PLDM_ERROR_INVALID_DATA;
821 }
822
823 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
824 return PLDM_ERROR_INVALID_DATA;
825 }
826
827 struct pldm_header_info header = { 0 };
828 header.msg_type = PLDM_REQUEST;
829 header.instance = instance_id;
830 header.pldm_type = PLDM_PLATFORM;
831 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
832
833 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
834 if (rc != PLDM_SUCCESS) {
835 return rc;
836 }
837
838 struct pldm_set_numeric_effecter_value_req *request =
839 (struct pldm_set_numeric_effecter_value_req *)msg->payload;
840 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
841 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
842 if (payload_length !=
843 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) {
844 return PLDM_ERROR_INVALID_LENGTH;
845 }
846 request->effecter_value[0] = *effecter_value;
847 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
848 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
849 if (payload_length !=
850 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1) {
851 return PLDM_ERROR_INVALID_LENGTH;
852 }
853
854 uint16_t val = *(uint16_t *)(effecter_value);
855 val = htole16(val);
856 memcpy(request->effecter_value, &val, sizeof(uint16_t));
857
858 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
859 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
860 if (payload_length !=
861 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3) {
862 return PLDM_ERROR_INVALID_LENGTH;
863 }
864
865 uint32_t val = *(uint32_t *)(effecter_value);
866 val = htole32(val);
867 memcpy(request->effecter_value, &val, sizeof(uint32_t));
868 }
869
870 request->effecter_id = htole16(effecter_id);
871 request->effecter_data_size = effecter_data_size;
872
873 return PLDM_SUCCESS;
874 }
875
876 LIBPLDM_ABI_STABLE
decode_set_numeric_effecter_value_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code)877 int decode_set_numeric_effecter_value_resp(const struct pldm_msg *msg,
878 size_t payload_length,
879 uint8_t *completion_code)
880 {
881 if (msg == NULL || completion_code == NULL) {
882 return PLDM_ERROR_INVALID_DATA;
883 }
884
885 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
886 return PLDM_ERROR_INVALID_LENGTH;
887 }
888
889 *completion_code = msg->payload[0];
890
891 return PLDM_SUCCESS;
892 }
893
894 LIBPLDM_ABI_STABLE
encode_get_state_sensor_readings_resp(uint8_t instance_id,uint8_t completion_code,uint8_t comp_sensor_count,get_sensor_state_field * field,struct pldm_msg * msg)895 int encode_get_state_sensor_readings_resp(uint8_t instance_id,
896 uint8_t completion_code,
897 uint8_t comp_sensor_count,
898 get_sensor_state_field *field,
899 struct pldm_msg *msg)
900 {
901 if (msg == NULL) {
902 return PLDM_ERROR_INVALID_DATA;
903 }
904
905 if (comp_sensor_count < 0x1 || comp_sensor_count > 0x8) {
906 return PLDM_ERROR_INVALID_DATA;
907 }
908
909 struct pldm_header_info header = { 0 };
910 header.msg_type = PLDM_RESPONSE;
911 header.instance = instance_id;
912 header.pldm_type = PLDM_PLATFORM;
913 header.command = PLDM_GET_STATE_SENSOR_READINGS;
914
915 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
916 if (rc != PLDM_SUCCESS) {
917 return rc;
918 }
919
920 struct pldm_get_state_sensor_readings_resp *response =
921 (struct pldm_get_state_sensor_readings_resp *)msg->payload;
922
923 response->completion_code = completion_code;
924 response->comp_sensor_count = comp_sensor_count;
925 memcpy(response->field, field,
926 (sizeof(get_sensor_state_field) * comp_sensor_count));
927
928 return PLDM_SUCCESS;
929 }
930
931 LIBPLDM_ABI_STABLE
encode_get_state_sensor_readings_req(uint8_t instance_id,uint16_t sensor_id,bitfield8_t sensor_rearm,uint8_t reserved,struct pldm_msg * msg)932 int encode_get_state_sensor_readings_req(uint8_t instance_id,
933 uint16_t sensor_id,
934 bitfield8_t sensor_rearm,
935 uint8_t reserved, struct pldm_msg *msg)
936 {
937 if (msg == NULL) {
938 return PLDM_ERROR_INVALID_DATA;
939 }
940
941 struct pldm_header_info header = { 0 };
942 header.msg_type = PLDM_REQUEST;
943 header.instance = instance_id;
944 header.pldm_type = PLDM_PLATFORM;
945 header.command = PLDM_GET_STATE_SENSOR_READINGS;
946
947 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
948 if (rc != PLDM_SUCCESS) {
949 return rc;
950 }
951
952 struct pldm_get_state_sensor_readings_req *request =
953 (struct pldm_get_state_sensor_readings_req *)msg->payload;
954
955 request->sensor_id = htole16(sensor_id);
956 request->reserved = reserved;
957 request->sensor_rearm = sensor_rearm;
958
959 return PLDM_SUCCESS;
960 }
961
962 LIBPLDM_ABI_STABLE
decode_get_state_sensor_readings_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint8_t * comp_sensor_count,get_sensor_state_field * field)963 int decode_get_state_sensor_readings_resp(const struct pldm_msg *msg,
964 size_t payload_length,
965 uint8_t *completion_code,
966 uint8_t *comp_sensor_count,
967 get_sensor_state_field *field)
968 {
969 PLDM_MSGBUF_DEFINE_P(buf);
970 uint8_t i;
971 int rc;
972
973 if (msg == NULL || completion_code == NULL ||
974 comp_sensor_count == NULL || field == NULL) {
975 return PLDM_ERROR_INVALID_DATA;
976 }
977
978 rc = pldm_msgbuf_init_errno(
979 buf, PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES,
980 msg->payload, payload_length);
981 if (rc) {
982 return pldm_xlate_errno(rc);
983 }
984
985 rc = pldm_msgbuf_extract_p(buf, completion_code);
986 if (rc) {
987 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
988 }
989
990 if (PLDM_SUCCESS != *completion_code) {
991 return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
992 }
993
994 rc = pldm_msgbuf_extract_p(buf, comp_sensor_count);
995 if (rc) {
996 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
997 }
998
999 if (*comp_sensor_count < 0x1 || *comp_sensor_count > 0x8) {
1000 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
1001 }
1002
1003 for (i = 0; i < *comp_sensor_count; i++) {
1004 pldm_msgbuf_extract(buf, field[i].sensor_op_state);
1005 pldm_msgbuf_extract(buf, field[i].present_state);
1006 pldm_msgbuf_extract(buf, field[i].previous_state);
1007 pldm_msgbuf_extract(buf, field[i].event_state);
1008 }
1009
1010 rc = pldm_msgbuf_complete_consumed(buf);
1011 if (rc) {
1012 return pldm_xlate_errno(rc);
1013 }
1014
1015 return PLDM_SUCCESS;
1016 }
1017
1018 LIBPLDM_ABI_STABLE
decode_get_state_sensor_readings_req(const struct pldm_msg * msg,size_t payload_length,uint16_t * sensor_id,bitfield8_t * sensor_rearm,uint8_t * reserved)1019 int decode_get_state_sensor_readings_req(const struct pldm_msg *msg,
1020 size_t payload_length,
1021 uint16_t *sensor_id,
1022 bitfield8_t *sensor_rearm,
1023 uint8_t *reserved)
1024 {
1025 PLDM_MSGBUF_DEFINE_P(buf);
1026 int rc;
1027
1028 if (msg == NULL || sensor_id == NULL || sensor_rearm == NULL) {
1029 return PLDM_ERROR_INVALID_DATA;
1030 }
1031
1032 rc = pldm_msgbuf_init_errno(buf,
1033 PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES,
1034 msg->payload, payload_length);
1035 if (rc) {
1036 return pldm_xlate_errno(rc);
1037 }
1038
1039 pldm_msgbuf_extract_p(buf, sensor_id);
1040 pldm_msgbuf_extract(buf, sensor_rearm->byte);
1041 pldm_msgbuf_extract_p(buf, reserved);
1042
1043 rc = pldm_msgbuf_complete(buf);
1044 if (rc) {
1045 return pldm_xlate_errno(rc);
1046 }
1047
1048 return PLDM_SUCCESS;
1049 }
1050
1051 LIBPLDM_ABI_STABLE
encode_sensor_event_data(struct pldm_sensor_event_data * const event_data,const size_t event_data_size,const uint16_t sensor_id,const enum sensor_event_class_states sensor_event_class,const uint8_t sensor_offset,const uint8_t event_state,const uint8_t previous_event_state,size_t * const actual_event_data_size)1052 int encode_sensor_event_data(
1053 struct pldm_sensor_event_data *const event_data,
1054 const size_t event_data_size, const uint16_t sensor_id,
1055 const enum sensor_event_class_states sensor_event_class,
1056 const uint8_t sensor_offset, const uint8_t event_state,
1057 const uint8_t previous_event_state,
1058 size_t *const actual_event_data_size)
1059 {
1060 *actual_event_data_size =
1061 (sizeof(*event_data) - sizeof(event_data->event_class) +
1062 sizeof(struct pldm_sensor_event_state_sensor_state));
1063
1064 if (!event_data) {
1065 return PLDM_SUCCESS;
1066 }
1067
1068 if (event_data_size < *actual_event_data_size) {
1069 *actual_event_data_size = 0;
1070 return PLDM_ERROR_INVALID_LENGTH;
1071 }
1072
1073 event_data->sensor_id = htole16(sensor_id);
1074 event_data->sensor_event_class_type = sensor_event_class;
1075
1076 struct pldm_sensor_event_state_sensor_state *const state_data =
1077 (struct pldm_sensor_event_state_sensor_state *)
1078 event_data->event_class;
1079
1080 state_data->sensor_offset = sensor_offset;
1081 state_data->event_state = event_state;
1082 state_data->previous_event_state = previous_event_state;
1083
1084 return PLDM_SUCCESS;
1085 }
1086
1087 LIBPLDM_ABI_STABLE
decode_platform_event_message_req(const struct pldm_msg * msg,size_t payload_length,uint8_t * format_version,uint8_t * tid,uint8_t * event_class,size_t * event_data_offset)1088 int decode_platform_event_message_req(const struct pldm_msg *msg,
1089 size_t payload_length,
1090 uint8_t *format_version, uint8_t *tid,
1091 uint8_t *event_class,
1092 size_t *event_data_offset)
1093 {
1094 PLDM_MSGBUF_DEFINE_P(buf);
1095 int rc;
1096
1097 if (msg == NULL || format_version == NULL || tid == NULL ||
1098 event_class == NULL || event_data_offset == NULL) {
1099 return PLDM_ERROR_INVALID_DATA;
1100 }
1101
1102 rc = pldm_msgbuf_init_errno(buf,
1103 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES,
1104 msg->payload, payload_length);
1105 if (rc) {
1106 return pldm_xlate_errno(rc);
1107 }
1108
1109 pldm_msgbuf_extract_p(buf, format_version);
1110 pldm_msgbuf_extract_p(buf, tid);
1111 pldm_msgbuf_extract_p(buf, event_class);
1112
1113 rc = pldm_msgbuf_complete(buf);
1114 if (rc) {
1115 return pldm_xlate_errno(rc);
1116 }
1117
1118 *event_data_offset =
1119 sizeof(*format_version) + sizeof(*tid) + sizeof(*event_class);
1120
1121 return PLDM_SUCCESS;
1122 }
1123
pldm_platform_poll_for_platform_event_message_validate(uint8_t transfer_operation_flag,uint16_t event_id_to_acknowledge)1124 static int pldm_platform_poll_for_platform_event_message_validate(
1125 uint8_t transfer_operation_flag, uint16_t event_id_to_acknowledge)
1126 {
1127 if (((transfer_operation_flag == PLDM_GET_FIRSTPART) &&
1128 (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_NULL)) ||
1129 ((transfer_operation_flag == PLDM_GET_NEXTPART) &&
1130 (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_FRAGMENT)) ||
1131 ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) &&
1132 (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_FRAGMENT)) ||
1133 ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) &&
1134 (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_NULL)) ||
1135 (transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY)) {
1136 return -EPROTO;
1137 }
1138
1139 return 0;
1140 }
1141
1142 LIBPLDM_ABI_STABLE
decode_poll_for_platform_event_message_req(const struct pldm_msg * msg,size_t payload_length,uint8_t * format_version,uint8_t * transfer_operation_flag,uint32_t * data_transfer_handle,uint16_t * event_id_to_acknowledge)1143 int decode_poll_for_platform_event_message_req(
1144 const struct pldm_msg *msg, size_t payload_length,
1145 uint8_t *format_version, uint8_t *transfer_operation_flag,
1146 uint32_t *data_transfer_handle, uint16_t *event_id_to_acknowledge)
1147 {
1148 PLDM_MSGBUF_DEFINE_P(buf);
1149 int rc;
1150
1151 if (msg == NULL || format_version == NULL ||
1152 transfer_operation_flag == NULL || data_transfer_handle == NULL ||
1153 event_id_to_acknowledge == NULL) {
1154 return PLDM_ERROR_INVALID_DATA;
1155 }
1156
1157 rc = pldm_msgbuf_init_errno(
1158 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES,
1159 msg->payload, payload_length);
1160 if (rc) {
1161 return pldm_xlate_errno(rc);
1162 }
1163
1164 pldm_msgbuf_extract_p(buf, format_version);
1165 rc = pldm_msgbuf_extract_p(buf, transfer_operation_flag);
1166 if (rc) {
1167 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
1168 }
1169 if (*transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY) {
1170 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
1171 }
1172
1173 pldm_msgbuf_extract_p(buf, data_transfer_handle);
1174 rc = pldm_msgbuf_extract_p(buf, event_id_to_acknowledge);
1175 if (rc) {
1176 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
1177 }
1178
1179 rc = pldm_platform_poll_for_platform_event_message_validate(
1180 *transfer_operation_flag, *event_id_to_acknowledge);
1181 if (rc < 0) {
1182 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
1183 }
1184
1185 rc = pldm_msgbuf_complete(buf);
1186 if (rc) {
1187 return pldm_xlate_errno(rc);
1188 }
1189
1190 return PLDM_SUCCESS;
1191 }
1192
1193 LIBPLDM_ABI_STABLE
encode_platform_event_message_resp(uint8_t instance_id,uint8_t completion_code,uint8_t platform_event_status,struct pldm_msg * msg)1194 int encode_platform_event_message_resp(uint8_t instance_id,
1195 uint8_t completion_code,
1196 uint8_t platform_event_status,
1197 struct pldm_msg *msg)
1198 {
1199 if (msg == NULL) {
1200 return PLDM_ERROR_INVALID_DATA;
1201 }
1202
1203 if (platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
1204 return PLDM_ERROR_INVALID_DATA;
1205 }
1206
1207 struct pldm_header_info header = { 0 };
1208 header.msg_type = PLDM_RESPONSE;
1209 header.instance = instance_id;
1210 header.pldm_type = PLDM_PLATFORM;
1211 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
1212
1213 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1214 if (rc != PLDM_SUCCESS) {
1215 return rc;
1216 }
1217
1218 struct pldm_platform_event_message_resp *response =
1219 (struct pldm_platform_event_message_resp *)msg->payload;
1220 response->completion_code = completion_code;
1221 response->platform_event_status = platform_event_status;
1222
1223 return PLDM_SUCCESS;
1224 }
1225
1226 LIBPLDM_ABI_STABLE
encode_poll_for_platform_event_message_resp(uint8_t instance_id,uint8_t completion_code,uint8_t tid,uint16_t event_id,uint32_t next_data_transfer_handle,uint8_t transfer_flag,uint8_t event_class,uint32_t event_data_size,uint8_t * event_data,uint32_t checksum,struct pldm_msg * msg,size_t payload_length)1227 int encode_poll_for_platform_event_message_resp(
1228 uint8_t instance_id, uint8_t completion_code, uint8_t tid,
1229 uint16_t event_id, uint32_t next_data_transfer_handle,
1230 uint8_t transfer_flag, uint8_t event_class, uint32_t event_data_size,
1231 uint8_t *event_data, uint32_t checksum, struct pldm_msg *msg,
1232 size_t payload_length)
1233 {
1234 PLDM_MSGBUF_DEFINE_P(buf);
1235 int rc;
1236
1237 if (!msg) {
1238 return PLDM_ERROR_INVALID_DATA;
1239 }
1240
1241 struct pldm_header_info header = { 0 };
1242 header.msg_type = PLDM_RESPONSE;
1243 header.instance = instance_id;
1244 header.pldm_type = PLDM_PLATFORM;
1245 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
1246
1247 rc = pack_pldm_header(&header, &(msg->hdr));
1248 if (rc != PLDM_SUCCESS) {
1249 return rc;
1250 }
1251
1252 rc = pldm_msgbuf_init_errno(
1253 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
1254 msg->payload, payload_length);
1255 if (rc) {
1256 return pldm_xlate_errno(rc);
1257 }
1258
1259 pldm_msgbuf_insert(buf, completion_code);
1260 pldm_msgbuf_insert(buf, tid);
1261 rc = pldm_msgbuf_insert(buf, event_id);
1262 if (rc) {
1263 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
1264 }
1265
1266 if (event_id == 0xffff || event_id == 0x0000) {
1267 if (PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES !=
1268 payload_length) {
1269 return pldm_msgbuf_discard(buf,
1270 PLDM_ERROR_INVALID_LENGTH);
1271 }
1272
1273 rc = pldm_msgbuf_complete(buf);
1274 if (rc) {
1275 return pldm_xlate_errno(rc);
1276 }
1277
1278 return PLDM_SUCCESS;
1279 }
1280
1281 if ((event_data == NULL) && (event_data_size > 0)) {
1282 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
1283 }
1284
1285 pldm_msgbuf_insert(buf, next_data_transfer_handle);
1286 pldm_msgbuf_insert(buf, transfer_flag);
1287 pldm_msgbuf_insert(buf, event_class);
1288 rc = pldm_msgbuf_insert(buf, event_data_size);
1289 if (rc) {
1290 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
1291 }
1292
1293 if ((event_data_size > 0) && event_data) {
1294 rc = pldm_msgbuf_insert_array(buf, event_data_size, event_data,
1295 event_data_size);
1296 if (rc) {
1297 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
1298 }
1299 }
1300
1301 if (transfer_flag == PLDM_END || transfer_flag == PLDM_START_AND_END) {
1302 pldm_msgbuf_insert(buf, checksum);
1303 }
1304
1305 rc = pldm_msgbuf_complete(buf);
1306 if (rc) {
1307 return pldm_xlate_errno(rc);
1308 }
1309
1310 return PLDM_SUCCESS;
1311 }
1312
1313 LIBPLDM_ABI_STABLE
encode_platform_event_message_req(uint8_t instance_id,uint8_t format_version,uint8_t tid,uint8_t event_class,const uint8_t * event_data,size_t event_data_length,struct pldm_msg * msg,size_t payload_length)1314 int encode_platform_event_message_req(
1315 uint8_t instance_id, uint8_t format_version, uint8_t tid,
1316 uint8_t event_class, const uint8_t *event_data,
1317 size_t event_data_length, struct pldm_msg *msg, size_t payload_length)
1318
1319 {
1320 if (format_version != 1) {
1321 return PLDM_ERROR_INVALID_DATA;
1322 }
1323
1324 if (msg == NULL || event_data == NULL) {
1325 return PLDM_ERROR_INVALID_DATA;
1326 }
1327
1328 if (event_data_length == 0) {
1329 return PLDM_ERROR_INVALID_DATA;
1330 }
1331
1332 if ((SIZE_MAX - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) <
1333 event_data_length) {
1334 return PLDM_ERROR_INVALID_LENGTH;
1335 }
1336
1337 if (payload_length !=
1338 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) {
1339 return PLDM_ERROR_INVALID_LENGTH;
1340 }
1341
1342 if (event_class > PLDM_CPER_EVENT &&
1343 !(event_class >= 0xf0 && event_class <= 0xfe)) {
1344 return PLDM_ERROR_INVALID_DATA;
1345 }
1346
1347 struct pldm_header_info header = { 0 };
1348 header.msg_type = PLDM_REQUEST;
1349 header.instance = instance_id;
1350 header.pldm_type = PLDM_PLATFORM;
1351 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
1352
1353 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1354 if (rc != PLDM_SUCCESS) {
1355 return rc;
1356 }
1357
1358 struct pldm_platform_event_message_req *request =
1359 (struct pldm_platform_event_message_req *)msg->payload;
1360 request->format_version = format_version;
1361 request->tid = tid;
1362 request->event_class = event_class;
1363 memcpy(request->event_data, event_data, event_data_length);
1364
1365 return PLDM_SUCCESS;
1366 }
1367
1368 LIBPLDM_ABI_STABLE
decode_platform_event_message_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint8_t * platform_event_status)1369 int decode_platform_event_message_resp(const struct pldm_msg *msg,
1370 size_t payload_length,
1371 uint8_t *completion_code,
1372 uint8_t *platform_event_status)
1373 {
1374 PLDM_MSGBUF_DEFINE_P(buf);
1375 int rc;
1376
1377 if (msg == NULL || completion_code == NULL ||
1378 platform_event_status == NULL) {
1379 return PLDM_ERROR_INVALID_DATA;
1380 }
1381
1382 rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES,
1383 msg->payload, payload_length);
1384 if (rc) {
1385 return pldm_xlate_errno(rc);
1386 }
1387
1388 rc = pldm_msgbuf_extract_p(buf, completion_code);
1389 if (rc) {
1390 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
1391 }
1392
1393 if (PLDM_SUCCESS != *completion_code) {
1394 return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
1395 }
1396
1397 rc = pldm_msgbuf_extract_p(buf, platform_event_status);
1398 if (rc) {
1399 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
1400 }
1401
1402 if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
1403 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
1404 }
1405
1406 rc = pldm_msgbuf_complete(buf);
1407 if (rc) {
1408 return pldm_xlate_errno(rc);
1409 }
1410
1411 return PLDM_SUCCESS;
1412 }
1413
1414 LIBPLDM_ABI_STABLE
encode_event_message_buffer_size_req(uint8_t instance_id,uint16_t event_receiver_max_buffer_size,struct pldm_msg * msg)1415 int encode_event_message_buffer_size_req(uint8_t instance_id,
1416 uint16_t event_receiver_max_buffer_size,
1417 struct pldm_msg *msg)
1418 {
1419 struct pldm_header_info header = { 0 };
1420 header.msg_type = PLDM_REQUEST;
1421 header.instance = instance_id;
1422 header.pldm_type = PLDM_PLATFORM;
1423 header.command = PLDM_EVENT_MESSAGE_BUFFER_SIZE;
1424
1425 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1426 if (rc != PLDM_SUCCESS) {
1427 return rc;
1428 }
1429
1430 struct pldm_event_message_buffer_size_req *request =
1431 (struct pldm_event_message_buffer_size_req *)msg->payload;
1432 request->event_receiver_max_buffer_size =
1433 event_receiver_max_buffer_size;
1434
1435 return PLDM_SUCCESS;
1436 }
1437
1438 LIBPLDM_ABI_STABLE
decode_event_message_buffer_size_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint16_t * terminus_max_buffer_size)1439 int decode_event_message_buffer_size_resp(const struct pldm_msg *msg,
1440 size_t payload_length,
1441 uint8_t *completion_code,
1442 uint16_t *terminus_max_buffer_size)
1443 {
1444 PLDM_MSGBUF_DEFINE_P(buf);
1445 int rc;
1446
1447 if (msg == NULL || completion_code == NULL ||
1448 terminus_max_buffer_size == NULL) {
1449 return PLDM_ERROR_INVALID_DATA;
1450 }
1451
1452 rc = pldm_msgbuf_init_errno(buf,
1453 PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES,
1454 msg->payload, payload_length);
1455 if (rc) {
1456 return pldm_xlate_errno(rc);
1457 }
1458
1459 rc = pldm_msgbuf_extract_p(buf, completion_code);
1460 if (rc) {
1461 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
1462 }
1463
1464 if (PLDM_SUCCESS != *completion_code) {
1465 return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
1466 }
1467
1468 pldm_msgbuf_extract_p(buf, terminus_max_buffer_size);
1469
1470 rc = pldm_msgbuf_complete_consumed(buf);
1471 if (rc) {
1472 return pldm_xlate_errno(rc);
1473 }
1474
1475 return PLDM_SUCCESS;
1476 }
1477
1478 LIBPLDM_ABI_STABLE
encode_event_message_supported_req(uint8_t instance_id,uint8_t format_version,struct pldm_msg * msg)1479 int encode_event_message_supported_req(uint8_t instance_id,
1480 uint8_t format_version,
1481 struct pldm_msg *msg)
1482 {
1483 if (format_version != 1) {
1484 return PLDM_ERROR_INVALID_DATA;
1485 }
1486
1487 if (msg == NULL) {
1488 return PLDM_ERROR_INVALID_DATA;
1489 }
1490
1491 struct pldm_header_info header = { 0 };
1492 header.msg_type = PLDM_REQUEST;
1493 header.instance = instance_id;
1494 header.pldm_type = PLDM_PLATFORM;
1495 header.command = PLDM_EVENT_MESSAGE_SUPPORTED;
1496
1497 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1498 if (rc != PLDM_SUCCESS) {
1499 return rc;
1500 }
1501
1502 struct pldm_event_message_supported_req *request =
1503 (struct pldm_event_message_supported_req *)msg->payload;
1504 request->format_version = format_version;
1505
1506 return PLDM_SUCCESS;
1507 }
1508
1509 LIBPLDM_ABI_STABLE
decode_event_message_supported_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint8_t * synchrony_config,bitfield8_t * synchrony_config_support,uint8_t * number_event_class_returned,uint8_t * event_class,uint8_t event_class_count)1510 int decode_event_message_supported_resp(const struct pldm_msg *msg,
1511 size_t payload_length,
1512 uint8_t *completion_code,
1513 uint8_t *synchrony_config,
1514 bitfield8_t *synchrony_config_support,
1515 uint8_t *number_event_class_returned,
1516 uint8_t *event_class,
1517 uint8_t event_class_count)
1518 {
1519 PLDM_MSGBUF_DEFINE_P(buf);
1520 int i;
1521 int rc;
1522
1523 if (msg == NULL || completion_code == NULL ||
1524 synchrony_config == NULL || synchrony_config_support == NULL ||
1525 number_event_class_returned == NULL || event_class == NULL) {
1526 return PLDM_ERROR_INVALID_DATA;
1527 }
1528
1529 rc = pldm_msgbuf_init_errno(buf,
1530 PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES,
1531 msg->payload, payload_length);
1532 if (rc) {
1533 return pldm_xlate_errno(rc);
1534 }
1535
1536 rc = pldm_msgbuf_extract_p(buf, completion_code);
1537 if (rc) {
1538 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
1539 }
1540
1541 if (PLDM_SUCCESS != *completion_code) {
1542 return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
1543 }
1544
1545 rc = pldm_msgbuf_extract_p(buf, synchrony_config);
1546 if (rc) {
1547 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
1548 }
1549
1550 if (*synchrony_config > PLDM_MESSAGE_TYPE_ASYNCHRONOUS_WITH_HEARTBEAT) {
1551 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
1552 }
1553
1554 pldm_msgbuf_extract_p(buf, &synchrony_config_support->byte);
1555
1556 rc = pldm_msgbuf_extract_p(buf, number_event_class_returned);
1557 if (rc) {
1558 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
1559 }
1560
1561 if (*number_event_class_returned == 0) {
1562 rc = pldm_msgbuf_complete(buf);
1563 if (rc) {
1564 return pldm_xlate_errno(rc);
1565 }
1566
1567 return PLDM_SUCCESS;
1568 }
1569
1570 if (event_class_count < *number_event_class_returned) {
1571 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_LENGTH);
1572 }
1573
1574 for (i = 0; i < *number_event_class_returned; i++) {
1575 pldm_msgbuf_extract(buf, event_class[i]);
1576 }
1577
1578 rc = pldm_msgbuf_complete_consumed(buf);
1579 if (rc) {
1580 return pldm_xlate_errno(rc);
1581 }
1582
1583 return PLDM_SUCCESS;
1584 }
1585
1586 LIBPLDM_ABI_STABLE
decode_sensor_event_data(const uint8_t * event_data,size_t event_data_length,uint16_t * sensor_id,uint8_t * sensor_event_class_type,size_t * event_class_data_offset)1587 int decode_sensor_event_data(const uint8_t *event_data,
1588 size_t event_data_length, uint16_t *sensor_id,
1589 uint8_t *sensor_event_class_type,
1590 size_t *event_class_data_offset)
1591 {
1592 PLDM_MSGBUF_DEFINE_P(buf);
1593 int rc;
1594
1595 if (event_data == NULL || sensor_id == NULL ||
1596 sensor_event_class_type == NULL ||
1597 event_class_data_offset == NULL) {
1598 return PLDM_ERROR_INVALID_DATA;
1599 }
1600
1601 rc = pldm_msgbuf_init_errno(buf, PLDM_SENSOR_EVENT_DATA_MIN_LENGTH,
1602 event_data, event_data_length);
1603 if (rc) {
1604 return pldm_xlate_errno(rc);
1605 }
1606
1607 if (event_data_length < PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) {
1608 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_LENGTH);
1609 }
1610
1611 size_t event_class_data_length =
1612 event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES;
1613
1614 pldm_msgbuf_extract_p(buf, sensor_id);
1615 rc = pldm_msgbuf_extract_p(buf, sensor_event_class_type);
1616 if (rc) {
1617 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
1618 }
1619
1620 if (*sensor_event_class_type == PLDM_SENSOR_OP_STATE) {
1621 if (event_class_data_length !=
1622 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
1623 return pldm_msgbuf_discard(buf,
1624 PLDM_ERROR_INVALID_LENGTH);
1625 }
1626 } else if (*sensor_event_class_type == PLDM_STATE_SENSOR_STATE) {
1627 if (event_class_data_length !=
1628 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
1629 return pldm_msgbuf_discard(buf,
1630 PLDM_ERROR_INVALID_LENGTH);
1631 }
1632 } else if (*sensor_event_class_type == PLDM_NUMERIC_SENSOR_STATE) {
1633 if (event_class_data_length <
1634 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
1635 event_class_data_length >
1636 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
1637 return pldm_msgbuf_discard(buf,
1638 PLDM_ERROR_INVALID_LENGTH);
1639 }
1640 } else {
1641 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
1642 }
1643
1644 *event_class_data_offset =
1645 sizeof(*sensor_id) + sizeof(*sensor_event_class_type);
1646
1647 rc = pldm_msgbuf_complete(buf);
1648 if (rc) {
1649 return pldm_xlate_errno(rc);
1650 }
1651
1652 return PLDM_SUCCESS;
1653 }
1654
1655 LIBPLDM_ABI_STABLE
decode_sensor_op_data(const uint8_t * sensor_data,size_t sensor_data_length,uint8_t * present_op_state,uint8_t * previous_op_state)1656 int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length,
1657 uint8_t *present_op_state, uint8_t *previous_op_state)
1658 {
1659 PLDM_MSGBUF_DEFINE_P(buf);
1660 int rc;
1661
1662 if (sensor_data == NULL || present_op_state == NULL ||
1663 previous_op_state == NULL) {
1664 return PLDM_ERROR_INVALID_DATA;
1665 }
1666
1667 rc = pldm_msgbuf_init_errno(
1668 buf, PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH, sensor_data,
1669 sensor_data_length);
1670 if (rc) {
1671 return pldm_xlate_errno(rc);
1672 }
1673
1674 pldm_msgbuf_extract_p(buf, present_op_state);
1675 pldm_msgbuf_extract_p(buf, previous_op_state);
1676
1677 rc = pldm_msgbuf_complete_consumed(buf);
1678 if (rc) {
1679 return pldm_xlate_errno(rc);
1680 }
1681
1682 return PLDM_SUCCESS;
1683 }
1684
1685 LIBPLDM_ABI_STABLE
decode_state_sensor_data(const uint8_t * sensor_data,size_t sensor_data_length,uint8_t * sensor_offset,uint8_t * event_state,uint8_t * previous_event_state)1686 int decode_state_sensor_data(const uint8_t *sensor_data,
1687 size_t sensor_data_length, uint8_t *sensor_offset,
1688 uint8_t *event_state,
1689 uint8_t *previous_event_state)
1690 {
1691 PLDM_MSGBUF_DEFINE_P(buf);
1692 int rc;
1693
1694 if (sensor_data == NULL || sensor_offset == NULL ||
1695 event_state == NULL || previous_event_state == NULL) {
1696 return PLDM_ERROR_INVALID_DATA;
1697 }
1698
1699 rc = pldm_msgbuf_init_errno(
1700 buf, PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH,
1701 sensor_data, sensor_data_length);
1702 if (rc) {
1703 return pldm_xlate_errno(rc);
1704 }
1705
1706 pldm_msgbuf_extract_p(buf, sensor_offset);
1707 pldm_msgbuf_extract_p(buf, event_state);
1708 pldm_msgbuf_extract_p(buf, previous_event_state);
1709
1710 rc = pldm_msgbuf_complete_consumed(buf);
1711 if (rc) {
1712 return pldm_xlate_errno(rc);
1713 }
1714
1715 return PLDM_SUCCESS;
1716 }
1717
1718 LIBPLDM_ABI_STABLE
decode_numeric_sensor_data(const uint8_t * sensor_data,size_t sensor_data_length,uint8_t * event_state,uint8_t * previous_event_state,uint8_t * sensor_data_size,uint32_t * present_reading)1719 int decode_numeric_sensor_data(const uint8_t *sensor_data,
1720 size_t sensor_data_length, uint8_t *event_state,
1721 uint8_t *previous_event_state,
1722 uint8_t *sensor_data_size,
1723 uint32_t *present_reading)
1724 {
1725 PLDM_MSGBUF_DEFINE_P(buf);
1726 int rc;
1727
1728 if (sensor_data == NULL || sensor_data_size == NULL ||
1729 event_state == NULL || previous_event_state == NULL ||
1730 present_reading == NULL) {
1731 return PLDM_ERROR_INVALID_DATA;
1732 }
1733
1734 if (sensor_data_length >
1735 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
1736 return PLDM_ERROR_INVALID_LENGTH;
1737 }
1738
1739 rc = pldm_msgbuf_init_errno(
1740 buf, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH,
1741 sensor_data, sensor_data_length);
1742 if (rc) {
1743 return pldm_xlate_errno(rc);
1744 }
1745
1746 pldm_msgbuf_extract_p(buf, event_state);
1747 pldm_msgbuf_extract_p(buf, previous_event_state);
1748 rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
1749 if (rc) {
1750 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
1751 }
1752
1753 /*
1754 * The implementation below is bonkers, but it's because the function
1755 * prototype is bonkers. The `present_reading` argument should have been
1756 * a tagged union.
1757 */
1758 switch (*sensor_data_size) {
1759 case PLDM_SENSOR_DATA_SIZE_UINT8: {
1760 uint8_t val;
1761 if (!pldm_msgbuf_extract(buf, val)) {
1762 *present_reading = (uint32_t)val;
1763 }
1764 break;
1765 }
1766 case PLDM_SENSOR_DATA_SIZE_SINT8: {
1767 int8_t val;
1768 if (!pldm_msgbuf_extract(buf, val)) {
1769 *present_reading = (uint32_t)(int32_t)val;
1770 }
1771 break;
1772 }
1773 case PLDM_SENSOR_DATA_SIZE_UINT16: {
1774 uint16_t val;
1775 if (!pldm_msgbuf_extract(buf, val)) {
1776 *present_reading = (uint32_t)val;
1777 }
1778 break;
1779 }
1780 case PLDM_SENSOR_DATA_SIZE_SINT16: {
1781 int16_t val;
1782 if (!pldm_msgbuf_extract(buf, val)) {
1783 *present_reading = (uint32_t)(int32_t)val;
1784 }
1785 break;
1786 }
1787 case PLDM_SENSOR_DATA_SIZE_UINT32: {
1788 uint32_t val;
1789 if (!pldm_msgbuf_extract(buf, val)) {
1790 *present_reading = (uint32_t)val;
1791 }
1792 break;
1793 }
1794 case PLDM_SENSOR_DATA_SIZE_SINT32: {
1795 int32_t val;
1796 if (!pldm_msgbuf_extract(buf, val)) {
1797 *present_reading = (uint32_t)val;
1798 }
1799 break;
1800 }
1801 default:
1802 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
1803 }
1804
1805 rc = pldm_msgbuf_complete_consumed(buf);
1806 if (rc) {
1807 return pldm_xlate_errno(rc);
1808 }
1809
1810 return PLDM_SUCCESS;
1811 }
1812
1813 LIBPLDM_ABI_STABLE
decode_numeric_sensor_pdr_data(const void * pdr_data,size_t pdr_data_length,struct pldm_numeric_sensor_value_pdr * pdr_value)1814 int decode_numeric_sensor_pdr_data(
1815 const void *pdr_data, size_t pdr_data_length,
1816 struct pldm_numeric_sensor_value_pdr *pdr_value)
1817 {
1818 PLDM_MSGBUF_DEFINE_P(buf);
1819 int rc;
1820
1821 if (!pdr_data || !pdr_value) {
1822 return PLDM_ERROR_INVALID_DATA;
1823 }
1824
1825 rc = pldm_msgbuf_init_errno(buf, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
1826 pdr_data, pdr_data_length);
1827 if (rc) {
1828 return pldm_xlate_errno(rc);
1829 }
1830
1831 rc = pldm_msgbuf_extract_value_pdr_hdr(
1832 buf, &pdr_value->hdr, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
1833 pdr_data_length);
1834 if (rc) {
1835 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
1836 }
1837
1838 pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
1839 pldm_msgbuf_extract(buf, pdr_value->sensor_id);
1840 pldm_msgbuf_extract(buf, pdr_value->entity_type);
1841 pldm_msgbuf_extract(buf, pdr_value->entity_instance_num);
1842 pldm_msgbuf_extract(buf, pdr_value->container_id);
1843 pldm_msgbuf_extract(buf, pdr_value->sensor_init);
1844 pldm_msgbuf_extract(buf, pdr_value->sensor_auxiliary_names_pdr);
1845 pldm_msgbuf_extract(buf, pdr_value->base_unit);
1846 pldm_msgbuf_extract(buf, pdr_value->unit_modifier);
1847 pldm_msgbuf_extract(buf, pdr_value->rate_unit);
1848 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle);
1849 pldm_msgbuf_extract(buf, pdr_value->aux_unit);
1850 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier);
1851 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit);
1852 pldm_msgbuf_extract(buf, pdr_value->rel);
1853 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle);
1854 pldm_msgbuf_extract(buf, pdr_value->is_linear);
1855
1856 rc = pldm_msgbuf_extract(buf, pdr_value->sensor_data_size);
1857 if (rc) {
1858 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
1859 }
1860 if (pdr_value->sensor_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
1861 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
1862 }
1863
1864 pldm_msgbuf_extract(buf, pdr_value->resolution);
1865 pldm_msgbuf_extract(buf, pdr_value->offset);
1866 pldm_msgbuf_extract(buf, pdr_value->accuracy);
1867 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance);
1868 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance);
1869 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1870 &pdr_value->hysteresis);
1871 pldm_msgbuf_extract(buf, pdr_value->supported_thresholds.byte);
1872 pldm_msgbuf_extract(
1873 buf, pdr_value->threshold_and_hysteresis_volatility.byte);
1874 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval);
1875 pldm_msgbuf_extract(buf, pdr_value->update_interval);
1876 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1877 &pdr_value->max_readable);
1878 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1879 &pdr_value->min_readable);
1880
1881 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
1882 if (rc) {
1883 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
1884 }
1885 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
1886 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
1887 }
1888
1889 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
1890 pldm_msgbuf_extract_range_field_format(
1891 buf, pdr_value->range_field_format, pdr_value->nominal_value);
1892 pldm_msgbuf_extract_range_field_format(
1893 buf, pdr_value->range_field_format, pdr_value->normal_max);
1894 pldm_msgbuf_extract_range_field_format(
1895 buf, pdr_value->range_field_format, pdr_value->normal_min);
1896 pldm_msgbuf_extract_range_field_format(
1897 buf, pdr_value->range_field_format, pdr_value->warning_high);
1898 pldm_msgbuf_extract_range_field_format(
1899 buf, pdr_value->range_field_format, pdr_value->warning_low);
1900 pldm_msgbuf_extract_range_field_format(
1901 buf, pdr_value->range_field_format, pdr_value->critical_high);
1902 pldm_msgbuf_extract_range_field_format(
1903 buf, pdr_value->range_field_format, pdr_value->critical_low);
1904 pldm_msgbuf_extract_range_field_format(
1905 buf, pdr_value->range_field_format, pdr_value->fatal_high);
1906 pldm_msgbuf_extract_range_field_format(
1907 buf, pdr_value->range_field_format, pdr_value->fatal_low);
1908
1909 rc = pldm_msgbuf_complete(buf);
1910 if (rc) {
1911 return pldm_xlate_errno(rc);
1912 }
1913
1914 return PLDM_SUCCESS;
1915 }
1916
1917 LIBPLDM_ABI_STABLE
encode_get_numeric_effecter_value_req(uint8_t instance_id,uint16_t effecter_id,struct pldm_msg * msg)1918 int encode_get_numeric_effecter_value_req(uint8_t instance_id,
1919 uint16_t effecter_id,
1920 struct pldm_msg *msg)
1921 {
1922 if (msg == NULL) {
1923 return PLDM_ERROR_INVALID_DATA;
1924 }
1925
1926 struct pldm_header_info header = { 0 };
1927 header.msg_type = PLDM_REQUEST;
1928 header.instance = instance_id;
1929 header.pldm_type = PLDM_PLATFORM;
1930 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1931
1932 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1933 if (rc != PLDM_SUCCESS) {
1934 return rc;
1935 }
1936
1937 struct pldm_get_numeric_effecter_value_req *request =
1938 (struct pldm_get_numeric_effecter_value_req *)msg->payload;
1939 request->effecter_id = htole16(effecter_id);
1940
1941 return PLDM_SUCCESS;
1942 }
1943
1944 LIBPLDM_ABI_STABLE
encode_get_numeric_effecter_value_resp(uint8_t instance_id,uint8_t completion_code,uint8_t effecter_data_size,uint8_t effecter_oper_state,const uint8_t * pending_value,const uint8_t * present_value,struct pldm_msg * msg,size_t payload_length)1945 int encode_get_numeric_effecter_value_resp(
1946 uint8_t instance_id, uint8_t completion_code,
1947 uint8_t effecter_data_size, uint8_t effecter_oper_state,
1948 const uint8_t *pending_value, const uint8_t *present_value,
1949 struct pldm_msg *msg, size_t payload_length)
1950 {
1951 if (msg == NULL || pending_value == NULL || present_value == NULL) {
1952 return PLDM_ERROR_INVALID_DATA;
1953 }
1954
1955 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1956 return PLDM_ERROR_INVALID_DATA;
1957 }
1958
1959 if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1960 return PLDM_ERROR_INVALID_DATA;
1961 }
1962
1963 struct pldm_header_info header = { 0 };
1964 header.msg_type = PLDM_RESPONSE;
1965 header.instance = instance_id;
1966 header.pldm_type = PLDM_PLATFORM;
1967 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1968
1969 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1970 if (rc != PLDM_SUCCESS) {
1971 return rc;
1972 }
1973
1974 struct pldm_get_numeric_effecter_value_resp *response =
1975 (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
1976
1977 response->completion_code = completion_code;
1978 response->effecter_data_size = effecter_data_size;
1979 response->effecter_oper_state = effecter_oper_state;
1980
1981 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1982 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1983 if (payload_length !=
1984 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1985 return PLDM_ERROR_INVALID_LENGTH;
1986 }
1987 response->pending_and_present_values[0] = *pending_value;
1988 response->pending_and_present_values[1] = *present_value;
1989
1990 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1991 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1992 if (payload_length !=
1993 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
1994 return PLDM_ERROR_INVALID_LENGTH;
1995 }
1996 uint16_t val_pending = *(uint16_t *)pending_value;
1997 val_pending = htole16(val_pending);
1998 memcpy(response->pending_and_present_values, &val_pending,
1999 sizeof(uint16_t));
2000 uint16_t val_present = *(uint16_t *)present_value;
2001 val_present = htole16(val_present);
2002 memcpy((response->pending_and_present_values +
2003 sizeof(uint16_t)),
2004 &val_present, sizeof(uint16_t));
2005
2006 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
2007 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
2008 if (payload_length !=
2009 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
2010 return PLDM_ERROR_INVALID_LENGTH;
2011 }
2012 uint32_t val_pending = *(uint32_t *)pending_value;
2013 val_pending = htole32(val_pending);
2014 memcpy(response->pending_and_present_values, &val_pending,
2015 sizeof(uint32_t));
2016 uint32_t val_present = *(uint32_t *)present_value;
2017 val_present = htole32(val_present);
2018 memcpy((response->pending_and_present_values +
2019 sizeof(uint32_t)),
2020 &val_present, sizeof(uint32_t));
2021 }
2022 return PLDM_SUCCESS;
2023 }
2024
2025 LIBPLDM_ABI_STABLE
decode_get_numeric_effecter_value_req(const struct pldm_msg * msg,size_t payload_length,uint16_t * effecter_id)2026 int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg,
2027 size_t payload_length,
2028 uint16_t *effecter_id)
2029 {
2030 PLDM_MSGBUF_DEFINE_P(buf);
2031 int rc;
2032
2033 if (msg == NULL || effecter_id == NULL) {
2034 return PLDM_ERROR_INVALID_DATA;
2035 }
2036
2037 rc = pldm_msgbuf_init_errno(buf,
2038 PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES,
2039 msg->payload, payload_length);
2040 if (rc) {
2041 return pldm_xlate_errno(rc);
2042 }
2043
2044 pldm_msgbuf_extract_p(buf, effecter_id);
2045
2046 rc = pldm_msgbuf_complete_consumed(buf);
2047 if (rc) {
2048 return pldm_xlate_errno(rc);
2049 }
2050
2051 return PLDM_SUCCESS;
2052 }
2053
2054 LIBPLDM_ABI_STABLE
decode_get_numeric_effecter_value_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint8_t * effecter_data_size,uint8_t * effecter_oper_state,uint8_t * pending_value,uint8_t * present_value)2055 int decode_get_numeric_effecter_value_resp(const struct pldm_msg *msg,
2056 size_t payload_length,
2057 uint8_t *completion_code,
2058 uint8_t *effecter_data_size,
2059 uint8_t *effecter_oper_state,
2060 uint8_t *pending_value,
2061 uint8_t *present_value)
2062 {
2063 PLDM_MSGBUF_DEFINE_P(buf);
2064 int rc;
2065
2066 if (msg == NULL || effecter_data_size == NULL ||
2067 effecter_oper_state == NULL || pending_value == NULL ||
2068 present_value == NULL) {
2069 return PLDM_ERROR_INVALID_DATA;
2070 }
2071
2072 rc = pldm_msgbuf_init_errno(
2073 buf, PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES,
2074 msg->payload, payload_length);
2075 if (rc) {
2076 return pldm_xlate_errno(rc);
2077 }
2078
2079 rc = pldm_msgbuf_extract_p(buf, completion_code);
2080 if (rc) {
2081 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
2082 }
2083
2084 if (PLDM_SUCCESS != *completion_code) {
2085 return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
2086 }
2087
2088 rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
2089 if (rc) {
2090 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
2091 }
2092
2093 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
2094 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
2095 }
2096
2097 rc = pldm_msgbuf_extract_p(buf, effecter_oper_state);
2098 if (rc) {
2099 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
2100 }
2101
2102 if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
2103 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
2104 }
2105
2106 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
2107 pending_value);
2108 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
2109 present_value);
2110
2111 rc = pldm_msgbuf_complete_consumed(buf);
2112 if (rc) {
2113 return pldm_xlate_errno(rc);
2114 }
2115
2116 return PLDM_SUCCESS;
2117 }
2118
2119 LIBPLDM_ABI_STABLE
encode_pldm_pdr_repository_chg_event_data(uint8_t event_data_format,uint8_t number_of_change_records,const uint8_t * event_data_operations,const uint8_t * numbers_of_change_entries,const uint32_t * const * change_entries,struct pldm_pdr_repository_chg_event_data * event_data,size_t * actual_change_records_size,size_t max_change_records_size)2120 int encode_pldm_pdr_repository_chg_event_data(
2121 uint8_t event_data_format, uint8_t number_of_change_records,
2122 const uint8_t *event_data_operations,
2123 const uint8_t *numbers_of_change_entries,
2124 const uint32_t *const *change_entries,
2125 struct pldm_pdr_repository_chg_event_data *event_data,
2126 size_t *actual_change_records_size, size_t max_change_records_size)
2127 {
2128 if (event_data_operations == NULL ||
2129 numbers_of_change_entries == NULL || change_entries == NULL) {
2130 return PLDM_ERROR_INVALID_DATA;
2131 }
2132
2133 size_t expected_size =
2134 sizeof(event_data_format) + sizeof(number_of_change_records);
2135
2136 expected_size +=
2137 sizeof(*event_data_operations) * number_of_change_records;
2138 expected_size +=
2139 sizeof(*numbers_of_change_entries) * number_of_change_records;
2140
2141 for (uint8_t i = 0; i < number_of_change_records; ++i) {
2142 expected_size += sizeof(*change_entries[0]) *
2143 numbers_of_change_entries[i];
2144 }
2145
2146 *actual_change_records_size = expected_size;
2147
2148 if (event_data == NULL) {
2149 return PLDM_SUCCESS;
2150 }
2151
2152 if (max_change_records_size < expected_size) {
2153 return PLDM_ERROR_INVALID_LENGTH;
2154 }
2155
2156 event_data->event_data_format = event_data_format;
2157 event_data->number_of_change_records = number_of_change_records;
2158
2159 struct pldm_pdr_repository_change_record_data *record_data =
2160 (struct pldm_pdr_repository_change_record_data *)
2161 event_data->change_records;
2162
2163 for (uint8_t i = 0; i < number_of_change_records; ++i) {
2164 record_data->event_data_operation = event_data_operations[i];
2165 record_data->number_of_change_entries =
2166 numbers_of_change_entries[i];
2167
2168 for (uint8_t j = 0; j < record_data->number_of_change_entries;
2169 ++j) {
2170 record_data->change_entry[j] =
2171 htole32(change_entries[i][j]);
2172 }
2173
2174 record_data =
2175 (struct pldm_pdr_repository_change_record_data
2176 *)(record_data->change_entry +
2177 record_data->number_of_change_entries);
2178 }
2179
2180 return PLDM_SUCCESS;
2181 }
2182
2183 LIBPLDM_ABI_STABLE
decode_pldm_pdr_repository_chg_event_data(const uint8_t * event_data,size_t event_data_size,uint8_t * event_data_format,uint8_t * number_of_change_records,size_t * change_record_data_offset)2184 int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data,
2185 size_t event_data_size,
2186 uint8_t *event_data_format,
2187 uint8_t *number_of_change_records,
2188 size_t *change_record_data_offset)
2189 {
2190 PLDM_MSGBUF_DEFINE_P(buf);
2191 int rc;
2192
2193 if (event_data == NULL || event_data_format == NULL ||
2194 number_of_change_records == NULL ||
2195 change_record_data_offset == NULL) {
2196 return PLDM_ERROR_INVALID_DATA;
2197 }
2198
2199 rc = pldm_msgbuf_init_errno(buf,
2200 PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH,
2201 event_data, event_data_size);
2202 if (rc) {
2203 return pldm_xlate_errno(rc);
2204 }
2205
2206 pldm_msgbuf_extract_p(buf, event_data_format);
2207 pldm_msgbuf_extract_p(buf, number_of_change_records);
2208
2209 *change_record_data_offset =
2210 sizeof(*event_data_format) + sizeof(*number_of_change_records);
2211
2212 rc = pldm_msgbuf_complete(buf);
2213 if (rc) {
2214 return pldm_xlate_errno(rc);
2215 }
2216
2217 return PLDM_SUCCESS;
2218 }
2219
2220 LIBPLDM_ABI_STABLE
decode_pldm_message_poll_event_data(const void * event_data,size_t event_data_length,struct pldm_message_poll_event * poll_event)2221 int decode_pldm_message_poll_event_data(
2222 const void *event_data, size_t event_data_length,
2223 struct pldm_message_poll_event *poll_event)
2224 {
2225 PLDM_MSGBUF_DEFINE_P(buf);
2226 int rc;
2227
2228 if (!event_data || !poll_event) {
2229 return -EINVAL;
2230 }
2231
2232 rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
2233 event_data_length);
2234 if (rc) {
2235 return rc;
2236 }
2237
2238 pldm_msgbuf_extract(buf, poll_event->format_version);
2239 rc = pldm_msgbuf_extract(buf, poll_event->event_id);
2240 if (rc) {
2241 return pldm_msgbuf_discard(buf, rc);
2242 }
2243
2244 if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) {
2245 return pldm_msgbuf_discard(buf, -EPROTO);
2246 }
2247
2248 pldm_msgbuf_extract(buf, poll_event->data_transfer_handle);
2249
2250 return pldm_msgbuf_complete_consumed(buf);
2251 }
2252
2253 LIBPLDM_ABI_TESTING
encode_pldm_message_poll_event_data(const struct pldm_message_poll_event * poll_event,void * event_data,size_t event_data_length)2254 int encode_pldm_message_poll_event_data(
2255 const struct pldm_message_poll_event *poll_event, void *event_data,
2256 size_t event_data_length)
2257 {
2258 PLDM_MSGBUF_DEFINE_P(buf);
2259 int rc;
2260
2261 if (poll_event == NULL || event_data == NULL) {
2262 return -EINVAL;
2263 }
2264
2265 if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) {
2266 return -EPROTO;
2267 }
2268
2269 rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
2270 event_data_length);
2271 if (rc) {
2272 return rc;
2273 }
2274 pldm_msgbuf_insert(buf, poll_event->format_version);
2275 pldm_msgbuf_insert(buf, poll_event->event_id);
2276 pldm_msgbuf_insert(buf, poll_event->data_transfer_handle);
2277
2278 return pldm_msgbuf_complete_consumed(buf);
2279 }
2280
2281 LIBPLDM_ABI_STABLE
decode_pldm_pdr_repository_change_record_data(const uint8_t * change_record_data,size_t change_record_data_size,uint8_t * event_data_operation,uint8_t * number_of_change_entries,size_t * change_entry_data_offset)2282 int decode_pldm_pdr_repository_change_record_data(
2283 const uint8_t *change_record_data, size_t change_record_data_size,
2284 uint8_t *event_data_operation, uint8_t *number_of_change_entries,
2285 size_t *change_entry_data_offset)
2286 {
2287 PLDM_MSGBUF_DEFINE_P(buf);
2288 int rc;
2289
2290 if (change_record_data == NULL || event_data_operation == NULL ||
2291 number_of_change_entries == NULL ||
2292 change_entry_data_offset == NULL) {
2293 return PLDM_ERROR_INVALID_DATA;
2294 }
2295
2296 rc = pldm_msgbuf_init_errno(
2297 buf, PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH,
2298 change_record_data, change_record_data_size);
2299 if (rc) {
2300 return pldm_xlate_errno(rc);
2301 }
2302
2303 pldm_msgbuf_extract_p(buf, event_data_operation);
2304 pldm_msgbuf_extract_p(buf, number_of_change_entries);
2305
2306 *change_entry_data_offset = sizeof(*event_data_operation) +
2307 sizeof(*number_of_change_entries);
2308
2309 rc = pldm_msgbuf_complete(buf);
2310 if (rc) {
2311 return pldm_xlate_errno(rc);
2312 }
2313
2314 return PLDM_SUCCESS;
2315 }
2316
2317 LIBPLDM_ABI_STABLE
encode_get_sensor_reading_req(uint8_t instance_id,uint16_t sensor_id,uint8_t rearm_event_state,struct pldm_msg * msg)2318 int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id,
2319 uint8_t rearm_event_state,
2320 struct pldm_msg *msg)
2321 {
2322 if (msg == NULL) {
2323 return PLDM_ERROR_INVALID_DATA;
2324 }
2325
2326 struct pldm_header_info header = { 0 };
2327 header.msg_type = PLDM_REQUEST;
2328 header.instance = instance_id;
2329 header.pldm_type = PLDM_PLATFORM;
2330 header.command = PLDM_GET_SENSOR_READING;
2331
2332 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2333 if (rc != PLDM_SUCCESS) {
2334 return rc;
2335 }
2336
2337 struct pldm_get_sensor_reading_req *request =
2338 (struct pldm_get_sensor_reading_req *)msg->payload;
2339
2340 request->sensor_id = htole16(sensor_id);
2341 request->rearm_event_state = rearm_event_state;
2342
2343 return PLDM_SUCCESS;
2344 }
2345
2346 LIBPLDM_ABI_STABLE
decode_get_sensor_reading_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint8_t * sensor_data_size,uint8_t * sensor_operational_state,uint8_t * sensor_event_message_enable,uint8_t * present_state,uint8_t * previous_state,uint8_t * event_state,uint8_t * present_reading)2347 int decode_get_sensor_reading_resp(
2348 const struct pldm_msg *msg, size_t payload_length,
2349 uint8_t *completion_code, uint8_t *sensor_data_size,
2350 uint8_t *sensor_operational_state, uint8_t *sensor_event_message_enable,
2351 uint8_t *present_state, uint8_t *previous_state, uint8_t *event_state,
2352 uint8_t *present_reading)
2353 {
2354 PLDM_MSGBUF_DEFINE_P(buf);
2355 int rc;
2356
2357 if (msg == NULL || completion_code == NULL ||
2358 sensor_data_size == NULL || sensor_operational_state == NULL ||
2359 sensor_event_message_enable == NULL || present_state == NULL ||
2360 previous_state == NULL || event_state == NULL ||
2361 present_reading == NULL) {
2362 return PLDM_ERROR_INVALID_DATA;
2363 }
2364
2365 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_MIN_RESP_BYTES,
2366 msg->payload, payload_length);
2367 if (rc) {
2368 return pldm_xlate_errno(rc);
2369 }
2370
2371 rc = pldm_msgbuf_extract_p(buf, completion_code);
2372 if (rc) {
2373 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
2374 }
2375
2376 if (PLDM_SUCCESS != *completion_code) {
2377 return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
2378 }
2379
2380 rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
2381 if (rc) {
2382 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
2383 }
2384
2385 if (*sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) {
2386 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
2387 }
2388
2389 pldm_msgbuf_extract_p(buf, sensor_operational_state);
2390 pldm_msgbuf_extract_p(buf, sensor_event_message_enable);
2391 pldm_msgbuf_extract_p(buf, present_state);
2392 pldm_msgbuf_extract_p(buf, previous_state);
2393 pldm_msgbuf_extract_p(buf, event_state);
2394
2395 pldm_msgbuf_extract_sensor_value(buf, *sensor_data_size,
2396 present_reading);
2397
2398 rc = pldm_msgbuf_complete_consumed(buf);
2399 if (rc) {
2400 return pldm_xlate_errno(rc);
2401 }
2402
2403 return PLDM_SUCCESS;
2404 }
2405
2406 LIBPLDM_ABI_STABLE
encode_get_sensor_reading_resp(uint8_t instance_id,uint8_t completion_code,uint8_t sensor_data_size,uint8_t sensor_operational_state,uint8_t sensor_event_message_enable,uint8_t present_state,uint8_t previous_state,uint8_t event_state,const uint8_t * present_reading,struct pldm_msg * msg,size_t payload_length)2407 int encode_get_sensor_reading_resp(uint8_t instance_id, uint8_t completion_code,
2408 uint8_t sensor_data_size,
2409 uint8_t sensor_operational_state,
2410 uint8_t sensor_event_message_enable,
2411 uint8_t present_state,
2412 uint8_t previous_state, uint8_t event_state,
2413 const uint8_t *present_reading,
2414 struct pldm_msg *msg, size_t payload_length)
2415 {
2416 if (msg == NULL || present_reading == NULL) {
2417 return PLDM_ERROR_INVALID_DATA;
2418 }
2419
2420 if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
2421 return PLDM_ERROR_INVALID_DATA;
2422 }
2423
2424 struct pldm_header_info header = { 0 };
2425 header.msg_type = PLDM_RESPONSE;
2426 header.instance = instance_id;
2427 header.pldm_type = PLDM_PLATFORM;
2428 header.command = PLDM_GET_SENSOR_READING;
2429
2430 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2431 if (rc != PLDM_SUCCESS) {
2432 return rc;
2433 }
2434
2435 struct pldm_get_sensor_reading_resp *response =
2436 (struct pldm_get_sensor_reading_resp *)msg->payload;
2437
2438 response->completion_code = completion_code;
2439 response->sensor_data_size = sensor_data_size;
2440 response->sensor_operational_state = sensor_operational_state;
2441 response->sensor_event_message_enable = sensor_event_message_enable;
2442 response->present_state = present_state;
2443 response->previous_state = previous_state;
2444 response->event_state = event_state;
2445
2446 if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
2447 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
2448 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
2449 return PLDM_ERROR_INVALID_LENGTH;
2450 }
2451 response->present_reading[0] = *present_reading;
2452
2453 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
2454 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
2455 if (payload_length !=
2456 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
2457 return PLDM_ERROR_INVALID_LENGTH;
2458 }
2459 uint16_t val = *(uint16_t *)present_reading;
2460 val = htole16(val);
2461 memcpy(response->present_reading, &val, 2);
2462
2463 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
2464 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
2465 if (payload_length !=
2466 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
2467 return PLDM_ERROR_INVALID_LENGTH;
2468 }
2469 uint32_t val = *(uint32_t *)present_reading;
2470 val = htole32(val);
2471 memcpy(response->present_reading, &val, 4);
2472 }
2473
2474 return PLDM_SUCCESS;
2475 }
2476
2477 LIBPLDM_ABI_STABLE
decode_get_sensor_reading_req(const struct pldm_msg * msg,size_t payload_length,uint16_t * sensor_id,uint8_t * rearm_event_state)2478 int decode_get_sensor_reading_req(const struct pldm_msg *msg,
2479 size_t payload_length, uint16_t *sensor_id,
2480 uint8_t *rearm_event_state)
2481 {
2482 PLDM_MSGBUF_DEFINE_P(buf);
2483 int rc;
2484
2485 if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) {
2486 return PLDM_ERROR_INVALID_DATA;
2487 }
2488
2489 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_REQ_BYTES,
2490 msg->payload, payload_length);
2491 if (rc) {
2492 return pldm_xlate_errno(rc);
2493 }
2494
2495 pldm_msgbuf_extract_p(buf, sensor_id);
2496 pldm_msgbuf_extract_p(buf, rearm_event_state);
2497
2498 rc = pldm_msgbuf_complete(buf);
2499 if (rc) {
2500 return pldm_xlate_errno(rc);
2501 }
2502
2503 return PLDM_SUCCESS;
2504 }
2505
2506 LIBPLDM_ABI_TESTING
encode_get_event_receiver_req(uint8_t instance_id,struct pldm_msg * msg,size_t payload_length LIBPLDM_CC_UNUSED)2507 int encode_get_event_receiver_req(uint8_t instance_id, struct pldm_msg *msg,
2508 size_t payload_length LIBPLDM_CC_UNUSED)
2509 {
2510 struct pldm_header_info header;
2511 header.msg_type = PLDM_REQUEST;
2512 header.instance = instance_id;
2513 header.pldm_type = PLDM_PLATFORM;
2514 header.command = PLDM_GET_EVENT_RECEIVER;
2515
2516 if (!msg) {
2517 return -EINVAL;
2518 }
2519
2520 return pack_pldm_header_errno(&header, &(msg->hdr));
2521 }
2522
2523 LIBPLDM_ABI_TESTING
encode_get_event_receiver_resp(uint8_t instance_id,struct pldm_get_event_receiver_resp * event_receiver_info,struct pldm_msg * msg,size_t * payload_length)2524 int encode_get_event_receiver_resp(
2525 uint8_t instance_id,
2526 struct pldm_get_event_receiver_resp *event_receiver_info,
2527 struct pldm_msg *msg, size_t *payload_length)
2528 {
2529 PLDM_MSGBUF_DEFINE_P(buf);
2530 int rc;
2531 if (!msg || !event_receiver_info) {
2532 return -EINVAL;
2533 }
2534
2535 /* See Table 2, DSP0245 v1.4.0 */
2536 if (event_receiver_info->transport_protocol_type !=
2537 PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
2538 return -ENOTSUP;
2539 }
2540
2541 struct pldm_header_info header = { 0 };
2542 header.msg_type = PLDM_RESPONSE;
2543 header.instance = instance_id;
2544 header.pldm_type = PLDM_PLATFORM;
2545 header.command = PLDM_GET_EVENT_RECEIVER;
2546
2547 rc = pack_pldm_header_errno(&header, &(msg->hdr));
2548 if (rc) {
2549 return rc;
2550 }
2551 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_EVENT_RECEIVER_MIN_RESP_BYTES,
2552 msg->payload, *payload_length);
2553 if (rc) {
2554 return rc;
2555 }
2556
2557 pldm_msgbuf_insert(buf, event_receiver_info->completion_code);
2558 pldm_msgbuf_insert(buf, event_receiver_info->transport_protocol_type);
2559 pldm_msgbuf_insert(
2560 buf, event_receiver_info->event_receiver_address.mctp_eid);
2561 return pldm_msgbuf_complete_used(buf, *payload_length, payload_length);
2562 }
2563
2564 LIBPLDM_ABI_STABLE
decode_get_event_receiver_resp(const struct pldm_msg * msg,size_t payload_length,struct pldm_get_event_receiver_resp * resp)2565 int decode_get_event_receiver_resp(const struct pldm_msg *msg,
2566 size_t payload_length,
2567 struct pldm_get_event_receiver_resp *resp)
2568 {
2569 PLDM_MSGBUF_DEFINE_P(buf);
2570 int rc;
2571 if (!msg) {
2572 return -EINVAL;
2573 }
2574
2575 rc = pldm_msg_has_error(msg, payload_length);
2576 if (rc) {
2577 resp->completion_code = rc;
2578 return 0;
2579 }
2580
2581 rc = pldm_msgbuf_init_errno(buf, PLDM_GET_EVENT_RECEIVER_MIN_RESP_BYTES,
2582 msg->payload, payload_length);
2583 if (rc) {
2584 return rc;
2585 }
2586 pldm_msgbuf_extract(buf, resp->completion_code);
2587 rc = pldm_msgbuf_extract(buf, resp->transport_protocol_type);
2588 if (rc) {
2589 return pldm_msgbuf_discard(buf, rc);
2590 }
2591 if (resp->transport_protocol_type ==
2592 PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
2593 pldm_msgbuf_extract(buf, resp->event_receiver_address.mctp_eid);
2594 } else {
2595 return pldm_msgbuf_discard(buf, -ENOTSUP);
2596 }
2597 return pldm_msgbuf_complete_consumed(buf);
2598 }
2599
2600 LIBPLDM_ABI_STABLE
encode_set_event_receiver_req(uint8_t instance_id,uint8_t event_message_global_enable,uint8_t transport_protocol_type,uint8_t event_receiver_address_info,uint16_t heartbeat_timer,struct pldm_msg * msg)2601 int encode_set_event_receiver_req(uint8_t instance_id,
2602 uint8_t event_message_global_enable,
2603 uint8_t transport_protocol_type,
2604 uint8_t event_receiver_address_info,
2605 uint16_t heartbeat_timer,
2606 struct pldm_msg *msg)
2607 {
2608 if (msg == NULL) {
2609 return PLDM_ERROR_INVALID_DATA;
2610 }
2611
2612 if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
2613 return PLDM_ERROR_INVALID_DATA;
2614 }
2615
2616 struct pldm_header_info header = { 0 };
2617 header.msg_type = PLDM_REQUEST;
2618 header.instance = instance_id;
2619 header.pldm_type = PLDM_PLATFORM;
2620 header.command = PLDM_SET_EVENT_RECEIVER;
2621
2622 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2623 if (rc != PLDM_SUCCESS) {
2624 return rc;
2625 }
2626
2627 struct pldm_set_event_receiver_req *request =
2628 (struct pldm_set_event_receiver_req *)msg->payload;
2629 request->event_message_global_enable = event_message_global_enable;
2630
2631 request->transport_protocol_type = transport_protocol_type;
2632 request->event_receiver_address_info = event_receiver_address_info;
2633
2634 if (event_message_global_enable ==
2635 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {
2636 if (heartbeat_timer == 0) {
2637 return PLDM_ERROR_INVALID_DATA;
2638 }
2639 request->heartbeat_timer = htole16(heartbeat_timer);
2640 }
2641
2642 return PLDM_SUCCESS;
2643 }
2644
2645 LIBPLDM_ABI_STABLE
decode_set_event_receiver_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code)2646 int decode_set_event_receiver_resp(const struct pldm_msg *msg,
2647 size_t payload_length,
2648 uint8_t *completion_code)
2649 {
2650 PLDM_MSGBUF_DEFINE_P(buf);
2651 int rc;
2652
2653 if (msg == NULL || completion_code == NULL) {
2654 return PLDM_ERROR_INVALID_DATA;
2655 }
2656
2657 rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_RESP_BYTES,
2658 msg->payload, payload_length);
2659 if (rc) {
2660 return pldm_xlate_errno(rc);
2661 }
2662
2663 pldm_msgbuf_extract_p(buf, completion_code);
2664
2665 rc = pldm_msgbuf_complete(buf);
2666 if (rc) {
2667 return pldm_xlate_errno(rc);
2668 }
2669
2670 return PLDM_SUCCESS;
2671 }
2672
2673 LIBPLDM_ABI_STABLE
decode_set_event_receiver_req(const struct pldm_msg * msg,size_t payload_length,uint8_t * event_message_global_enable,uint8_t * transport_protocol_type,uint8_t * event_receiver_address_info,uint16_t * heartbeat_timer)2674 int decode_set_event_receiver_req(const struct pldm_msg *msg,
2675 size_t payload_length,
2676 uint8_t *event_message_global_enable,
2677 uint8_t *transport_protocol_type,
2678 uint8_t *event_receiver_address_info,
2679 uint16_t *heartbeat_timer)
2680
2681 {
2682 PLDM_MSGBUF_DEFINE_P(buf);
2683 int rc;
2684
2685 if (msg == NULL || event_message_global_enable == NULL ||
2686 transport_protocol_type == NULL ||
2687 event_receiver_address_info == NULL || heartbeat_timer == NULL) {
2688 return PLDM_ERROR_INVALID_DATA;
2689 }
2690
2691 rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_MIN_REQ_BYTES,
2692 msg->payload, payload_length);
2693 if (rc) {
2694 return pldm_xlate_errno(rc);
2695 }
2696
2697 pldm_msgbuf_extract_p(buf, event_message_global_enable);
2698 if (rc) {
2699 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
2700 }
2701
2702 pldm_msgbuf_extract_p(buf, transport_protocol_type);
2703 pldm_msgbuf_extract_p(buf, event_receiver_address_info);
2704 if (*event_message_global_enable ==
2705 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {
2706 pldm_msgbuf_extract_p(buf, heartbeat_timer);
2707 }
2708
2709 rc = pldm_msgbuf_complete(buf);
2710 if (rc) {
2711 return pldm_xlate_errno(rc);
2712 }
2713
2714 if ((*event_message_global_enable ==
2715 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) &&
2716 (*heartbeat_timer == 0)) {
2717 return PLDM_ERROR_INVALID_DATA;
2718 }
2719
2720 return PLDM_SUCCESS;
2721 }
2722
2723 LIBPLDM_ABI_STABLE
encode_set_event_receiver_resp(uint8_t instance_id,uint8_t completion_code,struct pldm_msg * msg)2724 int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code,
2725 struct pldm_msg *msg)
2726
2727 {
2728 if (msg == NULL) {
2729 return PLDM_ERROR_INVALID_DATA;
2730 }
2731
2732 struct pldm_header_info header = { 0 };
2733 header.instance = instance_id;
2734 header.msg_type = PLDM_RESPONSE;
2735 header.pldm_type = PLDM_PLATFORM;
2736 header.command = PLDM_SET_EVENT_RECEIVER;
2737
2738 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2739 if (rc != PLDM_SUCCESS) {
2740 return rc;
2741 }
2742
2743 msg->payload[0] = completion_code;
2744
2745 return PLDM_SUCCESS;
2746 }
2747
2748 LIBPLDM_ABI_STABLE
encode_poll_for_platform_event_message_req(uint8_t instance_id,uint8_t format_version,uint8_t transfer_operation_flag,uint32_t data_transfer_handle,uint16_t event_id_to_acknowledge,struct pldm_msg * msg,size_t payload_length)2749 int encode_poll_for_platform_event_message_req(uint8_t instance_id,
2750 uint8_t format_version,
2751 uint8_t transfer_operation_flag,
2752 uint32_t data_transfer_handle,
2753 uint16_t event_id_to_acknowledge,
2754 struct pldm_msg *msg,
2755 size_t payload_length)
2756 {
2757 PLDM_MSGBUF_DEFINE_P(buf);
2758 int rc;
2759
2760 if (msg == NULL) {
2761 return PLDM_ERROR_INVALID_DATA;
2762 }
2763
2764 rc = pldm_platform_poll_for_platform_event_message_validate(
2765 transfer_operation_flag, event_id_to_acknowledge);
2766 if (rc < 0) {
2767 return PLDM_ERROR_INVALID_DATA;
2768 }
2769
2770 struct pldm_header_info header = { 0 };
2771 header.msg_type = PLDM_REQUEST;
2772 header.instance = instance_id;
2773 header.pldm_type = PLDM_PLATFORM;
2774 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
2775
2776 rc = pack_pldm_header(&header, &(msg->hdr));
2777 if (rc != PLDM_SUCCESS) {
2778 return rc;
2779 }
2780
2781 rc = pldm_msgbuf_init_errno(
2782 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2783 msg->payload, payload_length);
2784 if (rc) {
2785 return pldm_xlate_errno(rc);
2786 }
2787
2788 pldm_msgbuf_insert(buf, format_version);
2789 pldm_msgbuf_insert(buf, transfer_operation_flag);
2790 pldm_msgbuf_insert(buf, data_transfer_handle);
2791 pldm_msgbuf_insert(buf, event_id_to_acknowledge);
2792
2793 rc = pldm_msgbuf_complete(buf);
2794 if (rc) {
2795 return pldm_xlate_errno(rc);
2796 }
2797
2798 return PLDM_SUCCESS;
2799 }
2800
2801 LIBPLDM_ABI_STABLE
decode_poll_for_platform_event_message_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint8_t * tid,uint16_t * event_id,uint32_t * next_data_transfer_handle,uint8_t * transfer_flag,uint8_t * event_class,uint32_t * event_data_size,void ** event_data,uint32_t * event_data_integrity_checksum)2802 int decode_poll_for_platform_event_message_resp(
2803 const struct pldm_msg *msg, size_t payload_length,
2804 uint8_t *completion_code, uint8_t *tid, uint16_t *event_id,
2805 uint32_t *next_data_transfer_handle, uint8_t *transfer_flag,
2806 uint8_t *event_class, uint32_t *event_data_size, void **event_data,
2807 uint32_t *event_data_integrity_checksum)
2808 {
2809 PLDM_MSGBUF_DEFINE_P(buf);
2810 int rc;
2811
2812 if (msg == NULL || completion_code == NULL || tid == NULL ||
2813 event_id == NULL || next_data_transfer_handle == NULL ||
2814 transfer_flag == NULL || event_class == NULL ||
2815 event_data_size == NULL || event_data == NULL ||
2816 event_data_integrity_checksum == NULL) {
2817 return PLDM_ERROR_INVALID_DATA;
2818 }
2819
2820 rc = pldm_msgbuf_init_errno(
2821 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2822 msg->payload, payload_length);
2823 if (rc) {
2824 return pldm_xlate_errno(rc);
2825 }
2826
2827 rc = pldm_msgbuf_extract_p(buf, completion_code);
2828 if (rc) {
2829 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
2830 }
2831 if (PLDM_SUCCESS != *completion_code) {
2832 return pldm_msgbuf_discard(buf, *completion_code);
2833 }
2834
2835 pldm_msgbuf_extract_p(buf, tid);
2836 rc = pldm_msgbuf_extract_p(buf, event_id);
2837 if (rc) {
2838 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
2839 }
2840 if ((*event_id == 0) || (*event_id == 0xffff)) {
2841 return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
2842 }
2843
2844 pldm_msgbuf_extract_p(buf, next_data_transfer_handle);
2845 rc = pldm_msgbuf_extract_p(buf, transfer_flag);
2846 if (rc) {
2847 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
2848 }
2849
2850 pldm_msgbuf_extract_p(buf, event_class);
2851 rc = pldm_msgbuf_extract_p(buf, event_data_size);
2852 if (rc) {
2853 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
2854 }
2855 if (*event_data_size > payload_length) {
2856 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
2857 }
2858
2859 if (*event_data_size > 0) {
2860 pldm_msgbuf_span_required(buf, *event_data_size, event_data);
2861 }
2862
2863 if (*transfer_flag == PLDM_END ||
2864 *transfer_flag == PLDM_START_AND_END) {
2865 pldm_msgbuf_extract_p(buf, event_data_integrity_checksum);
2866 }
2867
2868 rc = pldm_msgbuf_complete_consumed(buf);
2869 if (rc) {
2870 return pldm_xlate_errno(rc);
2871 }
2872
2873 return PLDM_SUCCESS;
2874 }
2875
2876 LIBPLDM_ABI_TESTING
decode_numeric_effecter_pdr_data(const void * pdr_data,size_t pdr_data_length,struct pldm_numeric_effecter_value_pdr * pdr_value)2877 int decode_numeric_effecter_pdr_data(
2878 const void *pdr_data, size_t pdr_data_length,
2879 struct pldm_numeric_effecter_value_pdr *pdr_value)
2880 {
2881 PLDM_MSGBUF_DEFINE_P(buf);
2882 struct pldm_value_pdr_hdr hdr;
2883 int rc;
2884
2885 if (!pdr_data || !pdr_value) {
2886 return PLDM_ERROR_INVALID_DATA;
2887 }
2888
2889 rc = pldm_msgbuf_init_errno(buf,
2890 PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
2891 pdr_data, pdr_data_length);
2892 if (rc) {
2893 return pldm_xlate_errno(rc);
2894 }
2895
2896 rc = pldm_msgbuf_extract_value_pdr_hdr(
2897 buf, &hdr, PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
2898 pdr_data_length);
2899 if (rc) {
2900 return pldm_xlate_errno(rc);
2901 }
2902
2903 memcpy(&pdr_value->hdr, &hdr, sizeof(hdr));
2904
2905 pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
2906 pldm_msgbuf_extract(buf, pdr_value->effecter_id);
2907 pldm_msgbuf_extract(buf, pdr_value->entity_type);
2908 pldm_msgbuf_extract(buf, pdr_value->entity_instance);
2909 pldm_msgbuf_extract(buf, pdr_value->container_id);
2910 pldm_msgbuf_extract(buf, pdr_value->effecter_semantic_id);
2911 pldm_msgbuf_extract(buf, pdr_value->effecter_init);
2912 pldm_msgbuf_extract(buf, pdr_value->effecter_auxiliary_names);
2913 pldm_msgbuf_extract(buf, pdr_value->base_unit);
2914 pldm_msgbuf_extract(buf, pdr_value->unit_modifier);
2915 pldm_msgbuf_extract(buf, pdr_value->rate_unit);
2916 pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle);
2917 pldm_msgbuf_extract(buf, pdr_value->aux_unit);
2918 pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier);
2919 pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit);
2920 pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle);
2921 pldm_msgbuf_extract(buf, pdr_value->is_linear);
2922
2923 rc = pldm_msgbuf_extract(buf, pdr_value->effecter_data_size);
2924 if (rc) {
2925 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
2926 }
2927 if (pdr_value->effecter_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
2928 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
2929 }
2930
2931 pldm_msgbuf_extract(buf, pdr_value->resolution);
2932 pldm_msgbuf_extract(buf, pdr_value->offset);
2933 pldm_msgbuf_extract(buf, pdr_value->accuracy);
2934 pldm_msgbuf_extract(buf, pdr_value->plus_tolerance);
2935 pldm_msgbuf_extract(buf, pdr_value->minus_tolerance);
2936 pldm_msgbuf_extract(buf, pdr_value->state_transition_interval);
2937 pldm_msgbuf_extract(buf, pdr_value->transition_interval);
2938 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size,
2939 pdr_value->max_settable);
2940 pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size,
2941 pdr_value->min_settable);
2942
2943 rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
2944 if (rc) {
2945 return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
2946 }
2947 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
2948 return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
2949 }
2950
2951 pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
2952 pldm_msgbuf_extract_range_field_format(
2953 buf, pdr_value->range_field_format, pdr_value->nominal_value);
2954 pldm_msgbuf_extract_range_field_format(
2955 buf, pdr_value->range_field_format, pdr_value->normal_max);
2956 pldm_msgbuf_extract_range_field_format(
2957 buf, pdr_value->range_field_format, pdr_value->normal_min);
2958 pldm_msgbuf_extract_range_field_format(
2959 buf, pdr_value->range_field_format, pdr_value->rated_max);
2960 pldm_msgbuf_extract_range_field_format(
2961 buf, pdr_value->range_field_format, pdr_value->rated_min);
2962
2963 rc = pldm_msgbuf_complete_consumed(buf);
2964 if (rc) {
2965 return pldm_xlate_errno(rc);
2966 }
2967
2968 return PLDM_SUCCESS;
2969 }
2970
2971 LIBPLDM_ABI_STABLE
encode_get_state_effecter_states_req(uint8_t instance_id,uint16_t effecter_id,struct pldm_msg * msg,size_t payload_length)2972 int encode_get_state_effecter_states_req(uint8_t instance_id,
2973 uint16_t effecter_id,
2974 struct pldm_msg *msg,
2975 size_t payload_length)
2976 {
2977 PLDM_MSGBUF_DEFINE_P(buf);
2978 int rc;
2979
2980 if (msg == NULL) {
2981 return -EINVAL;
2982 }
2983
2984 struct pldm_header_info header = { 0 };
2985 header.msg_type = PLDM_REQUEST;
2986 header.instance = instance_id;
2987 header.pldm_type = PLDM_PLATFORM;
2988 header.command = PLDM_GET_STATE_EFFECTER_STATES;
2989
2990 rc = pack_pldm_header_errno(&header, &msg->hdr);
2991 if (rc < 0) {
2992 return rc;
2993 }
2994
2995 rc = pldm_msgbuf_init_errno(buf,
2996 PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES,
2997 msg->payload, payload_length);
2998 if (rc) {
2999 return rc;
3000 }
3001
3002 pldm_msgbuf_insert(buf, effecter_id);
3003
3004 return pldm_msgbuf_complete_consumed(buf);
3005 }
3006
3007 LIBPLDM_ABI_STABLE
decode_get_state_effecter_states_req(const struct pldm_msg * msg,size_t payload_length,uint16_t * effecter_id)3008 int decode_get_state_effecter_states_req(const struct pldm_msg *msg,
3009 size_t payload_length,
3010 uint16_t *effecter_id)
3011 {
3012 PLDM_MSGBUF_DEFINE_P(buf);
3013 int rc;
3014
3015 if (msg == NULL || effecter_id == NULL) {
3016 return -EINVAL;
3017 }
3018
3019 rc = pldm_msgbuf_init_errno(
3020 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
3021 msg->payload, payload_length);
3022 if (rc) {
3023 return rc;
3024 }
3025
3026 pldm_msgbuf_extract_p(buf, effecter_id);
3027
3028 return pldm_msgbuf_complete_consumed(buf);
3029 }
3030
3031 LIBPLDM_ABI_STABLE
decode_get_state_effecter_states_resp(const struct pldm_msg * msg,size_t payload_length,struct pldm_get_state_effecter_states_resp * resp)3032 int decode_get_state_effecter_states_resp(
3033 const struct pldm_msg *msg, size_t payload_length,
3034 struct pldm_get_state_effecter_states_resp *resp)
3035 {
3036 PLDM_MSGBUF_DEFINE_P(buf);
3037 get_effecter_state_field *field;
3038 int rc;
3039 int i;
3040
3041 if (msg == NULL || resp == NULL) {
3042 return -EINVAL;
3043 }
3044
3045 rc = pldm_msgbuf_init_errno(
3046 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
3047 msg->payload, payload_length);
3048 if (rc) {
3049 return rc;
3050 }
3051
3052 rc = pldm_msgbuf_extract(buf, resp->completion_code);
3053 if (rc) {
3054 return pldm_msgbuf_discard(buf, rc);
3055 }
3056
3057 if (PLDM_SUCCESS != resp->completion_code) {
3058 return pldm_msgbuf_complete(buf);
3059 }
3060
3061 rc = pldm_msgbuf_extract(buf, resp->comp_effecter_count);
3062 if (rc) {
3063 return pldm_msgbuf_discard(buf, rc);
3064 }
3065
3066 uint8_t comp_effecter_count = resp->comp_effecter_count;
3067
3068 if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN ||
3069 comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) {
3070 return pldm_msgbuf_discard(buf, -EBADMSG);
3071 }
3072
3073 for (i = 0, field = resp->field; i < comp_effecter_count;
3074 i++, field++) {
3075 pldm_msgbuf_extract(buf, field->effecter_op_state);
3076 pldm_msgbuf_extract(buf, field->pending_state);
3077 pldm_msgbuf_extract(buf, field->present_state);
3078 }
3079
3080 return pldm_msgbuf_complete_consumed(buf);
3081 }
3082
3083 LIBPLDM_ABI_STABLE
encode_get_state_effecter_states_resp(uint8_t instance_id,struct pldm_get_state_effecter_states_resp * resp,struct pldm_msg * msg,size_t payload_length)3084 int encode_get_state_effecter_states_resp(
3085 uint8_t instance_id, struct pldm_get_state_effecter_states_resp *resp,
3086 struct pldm_msg *msg, size_t payload_length)
3087 {
3088 PLDM_MSGBUF_DEFINE_P(buf);
3089 get_effecter_state_field *field;
3090 int rc;
3091 int i;
3092
3093 if (msg == NULL || resp == NULL) {
3094 return -EINVAL;
3095 }
3096
3097 uint8_t comp_effecter_count = resp->comp_effecter_count;
3098
3099 if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN ||
3100 comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) {
3101 return -EBADMSG;
3102 }
3103
3104 struct pldm_header_info header = { 0 };
3105 header.msg_type = PLDM_RESPONSE;
3106 header.instance = instance_id;
3107 header.pldm_type = PLDM_PLATFORM;
3108 header.command = PLDM_GET_STATE_EFFECTER_STATES;
3109
3110 rc = pack_pldm_header_errno(&header, &msg->hdr);
3111 if (rc < 0) {
3112 return rc;
3113 }
3114
3115 rc = pldm_msgbuf_init_errno(
3116 buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
3117 msg->payload, payload_length);
3118 if (rc) {
3119 return rc;
3120 }
3121
3122 pldm_msgbuf_insert(buf, resp->completion_code);
3123 pldm_msgbuf_insert(buf, comp_effecter_count);
3124
3125 for (i = 0, field = resp->field; i < comp_effecter_count;
3126 i++, field++) {
3127 pldm_msgbuf_insert(buf, field->effecter_op_state);
3128 pldm_msgbuf_insert(buf, field->pending_state);
3129 pldm_msgbuf_insert(buf, field->present_state);
3130 }
3131
3132 return pldm_msgbuf_complete_consumed(buf);
3133 }
3134
3135 LIBPLDM_ABI_STABLE
decode_entity_auxiliary_names_pdr(const void * data,size_t data_length,struct pldm_entity_auxiliary_names_pdr * pdr,size_t pdr_length)3136 int decode_entity_auxiliary_names_pdr(
3137 const void *data, size_t data_length,
3138 struct pldm_entity_auxiliary_names_pdr *pdr, size_t pdr_length)
3139 {
3140 PLDM_MSGBUF_DEFINE_P(buf);
3141 PLDM_MSGBUF_DEFINE_P(src);
3142 PLDM_MSGBUF_DEFINE_P(dst);
3143 size_t names_len = 0;
3144 void *names = NULL;
3145 int rc;
3146 int i;
3147
3148 if (!data || !pdr) {
3149 return -EINVAL;
3150 }
3151
3152 /*
3153 * Alignment of auxiliary_name_data is an invariant as we statically assert
3154 * its behaviour in the header.
3155 */
3156 assert(!((uintptr_t)pdr->auxiliary_name_data &
3157 (alignof(pldm_utf16be) - 1)));
3158
3159 /* Reject any lengths that are obviously invalid */
3160 if (pdr_length < data_length || pdr_length < sizeof(*pdr)) {
3161 return -EINVAL;
3162 }
3163
3164 rc = pldm_msgbuf_init_errno(
3165 buf, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH, data,
3166 data_length);
3167 if (rc) {
3168 return rc;
3169 }
3170
3171 rc = pldm_msgbuf_extract_value_pdr_hdr(
3172 buf, &pdr->hdr, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH,
3173 data_length);
3174 if (rc) {
3175 return pldm_msgbuf_discard(buf, rc);
3176 }
3177
3178 pldm_msgbuf_extract(buf, pdr->container.entity_type);
3179 pldm_msgbuf_extract(buf, pdr->container.entity_instance_num);
3180 pldm_msgbuf_extract(buf, pdr->container.entity_container_id);
3181 pldm_msgbuf_extract(buf, pdr->shared_name_count);
3182 rc = pldm_msgbuf_extract(buf, pdr->name_string_count);
3183 if (rc < 0) {
3184 return pldm_msgbuf_discard(buf, rc);
3185 }
3186
3187 rc = pldm_msgbuf_span_remaining(buf, &names, &names_len);
3188 if (rc < 0) {
3189 return rc;
3190 }
3191 assert(names);
3192
3193 rc = pldm_msgbuf_complete_consumed(buf);
3194 if (rc) {
3195 return rc;
3196 }
3197
3198 pdr->auxiliary_name_data_size = pdr_length - sizeof(*pdr);
3199
3200 rc = pldm_msgbuf_init_errno(dst, pdr->auxiliary_name_data_size,
3201 pdr->auxiliary_name_data,
3202 pdr->auxiliary_name_data_size);
3203 if (rc < 0) {
3204 return rc;
3205 }
3206
3207 /*
3208 * Below we do two passes over the same region. This is to first pack the
3209 * UTF16-BE strings into auxiliary_name_data, followed by the ASCII strings,
3210 * to maintain appropriate alignment.
3211 */
3212
3213 /* Initialise for the first pass to extract the UTF16-BE name strings */
3214 rc = pldm_msgbuf_init_errno(src, names_len, names, names_len);
3215 if (rc < 0) {
3216 goto cleanup_msgbuf_dst;
3217 }
3218
3219 for (i = 0; i < pdr->name_string_count; i++) {
3220 pldm_msgbuf_span_string_ascii(src, NULL, NULL);
3221 rc = pldm_msgbuf_copy_string_utf16(dst, src);
3222 if (rc) {
3223 goto cleanup_msgbuf_src;
3224 }
3225 }
3226
3227 rc = pldm_msgbuf_complete_consumed(src);
3228 if (rc < 0) {
3229 goto cleanup_msgbuf_dst;
3230 }
3231
3232 /* Reinitialise for the second pass to extract the ASCII tag strings */
3233 rc = pldm_msgbuf_init_errno(src, names_len, names, names_len);
3234 if (rc < 0) {
3235 goto cleanup_msgbuf_dst;
3236 }
3237
3238 for (i = 0; i < pdr->name_string_count; i++) {
3239 rc = pldm_msgbuf_copy_string_ascii(dst, src);
3240 if (rc) {
3241 goto cleanup_msgbuf_src;
3242 }
3243 pldm_msgbuf_span_string_utf16(src, NULL, NULL);
3244 }
3245
3246 rc = pldm_msgbuf_complete(src);
3247 if (rc) {
3248 goto cleanup_msgbuf_dst;
3249 }
3250
3251 return pldm_msgbuf_complete(dst);
3252
3253 cleanup_msgbuf_src:
3254 rc = pldm_msgbuf_discard(src, rc);
3255 cleanup_msgbuf_dst:
3256 return pldm_msgbuf_discard(dst, rc);
3257 }
3258
3259 LIBPLDM_ABI_STABLE
decode_pldm_entity_auxiliary_names_pdr_index(struct pldm_entity_auxiliary_names_pdr * pdr)3260 int decode_pldm_entity_auxiliary_names_pdr_index(
3261 struct pldm_entity_auxiliary_names_pdr *pdr)
3262 {
3263 PLDM_MSGBUF_DEFINE_P(buf);
3264 int rc;
3265 int i;
3266
3267 if (!pdr) {
3268 return -EINVAL;
3269 }
3270
3271 if (pdr->name_string_count == 0 && pdr->names) {
3272 return -EINVAL;
3273 }
3274
3275 if (pdr->name_string_count > 0 && !pdr->names) {
3276 return -EINVAL;
3277 }
3278
3279 if (pdr->name_string_count == 0) {
3280 return 0;
3281 }
3282
3283 /*
3284 * Minimum size is one NUL for each member of each entry
3285 *
3286 * Note that the definition of nameLanguageTag in DSP0248 v1.2.2
3287 * states the following:
3288 *
3289 * > A null-terminated ISO646 ASCII string ...
3290 * >
3291 * > special value: null string = 0x0000 = unspecified.
3292 *
3293 * Until proven otherwise we will assume the "0x0000" is a
3294 * misrepresentation of an ASCII NUL, and that ASCII NUL is
3295 * represented by a single byte.
3296 */
3297 rc = pldm_msgbuf_init_errno(
3298 buf, pdr->name_string_count * (sizeof(char) + sizeof(char16_t)),
3299 pdr->auxiliary_name_data, pdr->auxiliary_name_data_size);
3300 if (rc) {
3301 return rc;
3302 }
3303
3304 for (i = 0; i < pdr->name_string_count; i++) {
3305 void *loc = NULL;
3306 pldm_msgbuf_span_string_utf16(buf, &loc, NULL);
3307 pdr->names[i].name = loc;
3308 }
3309
3310 for (i = 0; i < pdr->name_string_count; i++) {
3311 void *loc = NULL;
3312 pldm_msgbuf_span_string_ascii(buf, &loc, NULL);
3313 pdr->names[i].tag = loc;
3314 }
3315
3316 return pldm_msgbuf_complete_consumed(buf);
3317 }
3318
3319 LIBPLDM_ABI_STABLE
decode_pldm_platform_cper_event(const void * event_data,size_t event_data_length,struct pldm_platform_cper_event * cper_event,size_t cper_event_length)3320 int decode_pldm_platform_cper_event(const void *event_data,
3321 size_t event_data_length,
3322 struct pldm_platform_cper_event *cper_event,
3323 size_t cper_event_length)
3324 {
3325 PLDM_MSGBUF_DEFINE_P(buf);
3326 int rc;
3327
3328 if (!cper_event || !event_data) {
3329 return -EINVAL;
3330 }
3331
3332 if (cper_event_length < sizeof(*cper_event)) {
3333 return -EINVAL;
3334 }
3335
3336 rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_CPER_EVENT_MIN_LENGTH,
3337 event_data, event_data_length);
3338 if (rc) {
3339 return rc;
3340 }
3341
3342 pldm_msgbuf_extract(buf, cper_event->format_version);
3343 rc = pldm_msgbuf_extract(buf, cper_event->format_type);
3344 if (rc) {
3345 return pldm_msgbuf_discard(buf, rc);
3346 }
3347 if (cper_event->format_type != PLDM_PLATFORM_CPER_EVENT_WITH_HEADER &&
3348 cper_event->format_type !=
3349 PLDM_PLATFORM_CPER_EVENT_WITHOUT_HEADER) {
3350 return pldm_msgbuf_discard(buf, -EPROTO);
3351 }
3352
3353 rc = pldm_msgbuf_extract(buf, cper_event->event_data_length);
3354 if (rc) {
3355 return pldm_msgbuf_discard(buf, rc);
3356 }
3357
3358 if (cper_event->event_data_length >
3359 (cper_event_length - sizeof(*cper_event))) {
3360 return pldm_msgbuf_discard(buf, -EOVERFLOW);
3361 }
3362
3363 rc = pldm_msgbuf_extract_array_uint8(
3364 buf, cper_event->event_data_length, cper_event->event_data,
3365 cper_event_length - sizeof(*cper_event));
3366 if (rc) {
3367 return pldm_msgbuf_discard(buf, rc);
3368 }
3369
3370 return pldm_msgbuf_complete_consumed(buf);
3371 }
3372
3373 LIBPLDM_ABI_STABLE
3374 uint8_t *
pldm_platform_cper_event_event_data(struct pldm_platform_cper_event * event)3375 pldm_platform_cper_event_event_data(struct pldm_platform_cper_event *event)
3376 {
3377 return event->event_data;
3378 }
3379
3380 LIBPLDM_ABI_TESTING
decode_pldm_file_descriptor_pdr(const void * data,size_t data_length,struct pldm_file_descriptor_pdr * pdr)3381 int decode_pldm_file_descriptor_pdr(const void *data, size_t data_length,
3382 struct pldm_file_descriptor_pdr *pdr)
3383 {
3384 PLDM_MSGBUF_DEFINE_P(buf);
3385 int rc;
3386
3387 if (!data || !pdr) {
3388 return -EINVAL;
3389 }
3390
3391 rc = pldm_msgbuf_init_errno(buf,
3392 PLDM_PDR_FILE_DESCRIPTOR_PDR_MIN_LENGTH,
3393 data, data_length);
3394 if (rc) {
3395 return rc;
3396 }
3397
3398 rc = pldm_msgbuf_extract_value_pdr_hdr(
3399 buf, &pdr->hdr, PLDM_PDR_FILE_DESCRIPTOR_PDR_MIN_LENGTH,
3400 data_length);
3401 if (rc) {
3402 return pldm_msgbuf_discard(buf, rc);
3403 }
3404
3405 pldm_msgbuf_extract(buf, pdr->terminus_handle);
3406 pldm_msgbuf_extract(buf, pdr->file_identifier);
3407 pldm_msgbuf_extract(buf, pdr->container.entity_type);
3408 pldm_msgbuf_extract(buf, pdr->container.entity_instance_num);
3409 pldm_msgbuf_extract(buf, pdr->container.entity_container_id);
3410 pldm_msgbuf_extract(buf, pdr->superior_directory_file_identifier);
3411 pldm_msgbuf_extract(buf, pdr->file_classification);
3412 pldm_msgbuf_extract(buf, pdr->oem_file_classification);
3413 pldm_msgbuf_extract(buf, pdr->file_capabilities.value);
3414 pldm_msgbuf_extract(buf, pdr->file_version.alpha);
3415 pldm_msgbuf_extract(buf, pdr->file_version.update);
3416 pldm_msgbuf_extract(buf, pdr->file_version.minor);
3417 pldm_msgbuf_extract(buf, pdr->file_version.major);
3418 pldm_msgbuf_extract(buf, pdr->file_maximum_size);
3419 pldm_msgbuf_extract(buf, pdr->file_maximum_file_descriptor_count);
3420 rc = pldm_msgbuf_extract_uint8_to_size(buf, pdr->file_name.length);
3421 if (rc) {
3422 return pldm_msgbuf_discard(buf, rc);
3423 }
3424
3425 pldm_msgbuf_span_required(buf, pdr->file_name.length,
3426 (void **)&pdr->file_name.ptr);
3427
3428 pdr->oem_file_classification_name.length = 0;
3429
3430 if (pdr->oem_file_classification) {
3431 rc = pldm_msgbuf_extract_uint8_to_size(
3432 buf, pdr->oem_file_classification_name.length);
3433 if (rc) {
3434 return pldm_msgbuf_discard(buf, rc);
3435 }
3436
3437 pldm_msgbuf_span_required(
3438 buf, pdr->oem_file_classification_name.length,
3439 (void **)&pdr->oem_file_classification_name.ptr);
3440 }
3441
3442 return pldm_msgbuf_complete_consumed(buf);
3443 }
3444