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