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