xref: /openbmc/libpldm/src/dsp/platform.c (revision 225530ab4827d0b10ecb51d027a51a3eb909960e)
148761c62SAndrew Jeffery /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
2830c1eb4SAndrew Jeffery #include "api.h"
3830c1eb4SAndrew Jeffery #include "compiler.h"
4f490a38fSTal Yacobi #include "dsp/base.h"
548761c62SAndrew Jeffery #include "msgbuf.h"
648761c62SAndrew Jeffery #include "msgbuf/platform.h"
748761c62SAndrew Jeffery 
848761c62SAndrew Jeffery #include <libpldm/base.h>
948761c62SAndrew Jeffery #include <libpldm/platform.h>
1048761c62SAndrew Jeffery #include <libpldm/pldm_types.h>
1148761c62SAndrew Jeffery 
1248761c62SAndrew Jeffery #include <endian.h>
1348761c62SAndrew Jeffery #include <stdint.h>
1448761c62SAndrew Jeffery #include <stdlib.h>
1548761c62SAndrew Jeffery #include <string.h>
16dacfa354SThu Nguyen #include <uchar.h>
1748761c62SAndrew Jeffery 
1848761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
1948761c62SAndrew Jeffery int encode_state_effecter_pdr(
2048761c62SAndrew Jeffery 	struct pldm_state_effecter_pdr *const effecter,
2148761c62SAndrew Jeffery 	const size_t allocation_size,
2248761c62SAndrew Jeffery 	const struct state_effecter_possible_states *const possible_states,
2348761c62SAndrew Jeffery 	const size_t possible_states_size, size_t *const actual_size)
2448761c62SAndrew Jeffery {
2548761c62SAndrew Jeffery 	// Encode possible states
2648761c62SAndrew Jeffery 
2748761c62SAndrew Jeffery 	size_t calculated_possible_states_size = 0;
2848761c62SAndrew Jeffery 
2948761c62SAndrew Jeffery 	{
3048761c62SAndrew Jeffery 		char *states_ptr = (char *)possible_states;
3148761c62SAndrew Jeffery 		char *const begin_states_ptr = states_ptr;
3248761c62SAndrew Jeffery 
3348761c62SAndrew Jeffery 		for (int i = 0; i < effecter->composite_effecter_count; ++i) {
3448761c62SAndrew Jeffery 			struct state_effecter_possible_states *states =
3548761c62SAndrew Jeffery 				(struct state_effecter_possible_states *)
3648761c62SAndrew Jeffery 					states_ptr;
3748761c62SAndrew Jeffery 
3848761c62SAndrew Jeffery 			HTOLE16(states->state_set_id);
3948761c62SAndrew Jeffery 
4048761c62SAndrew Jeffery 			states_ptr +=
4148761c62SAndrew Jeffery 				(sizeof(*states) - sizeof(states->states) +
4248761c62SAndrew Jeffery 				 states->possible_states_size);
4348761c62SAndrew Jeffery 		}
4448761c62SAndrew Jeffery 
4548761c62SAndrew Jeffery 		calculated_possible_states_size = states_ptr - begin_states_ptr;
4648761c62SAndrew Jeffery 	}
4748761c62SAndrew Jeffery 
4848761c62SAndrew Jeffery 	// Check lengths
4948761c62SAndrew Jeffery 
5048761c62SAndrew Jeffery 	if (possible_states_size != calculated_possible_states_size) {
5148761c62SAndrew Jeffery 		*actual_size = 0;
5248761c62SAndrew Jeffery 		return PLDM_ERROR;
5348761c62SAndrew Jeffery 	}
5448761c62SAndrew Jeffery 
5548761c62SAndrew Jeffery 	*actual_size =
5648761c62SAndrew Jeffery 		(sizeof(struct pldm_state_effecter_pdr) + possible_states_size -
5748761c62SAndrew Jeffery 		 sizeof(effecter->possible_states));
5848761c62SAndrew Jeffery 
5948761c62SAndrew Jeffery 	if (allocation_size < *actual_size) {
6048761c62SAndrew Jeffery 		*actual_size = 0;
6148761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
6248761c62SAndrew Jeffery 	}
6348761c62SAndrew Jeffery 
6448761c62SAndrew Jeffery 	// Encode rest of PDR
6548761c62SAndrew Jeffery 
6648761c62SAndrew Jeffery 	effecter->hdr.version = 1;
6748761c62SAndrew Jeffery 	effecter->hdr.type = PLDM_STATE_EFFECTER_PDR;
6848761c62SAndrew Jeffery 	effecter->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
6948761c62SAndrew Jeffery 
7048761c62SAndrew Jeffery 	memcpy(effecter->possible_states, possible_states,
7148761c62SAndrew Jeffery 	       possible_states_size);
7248761c62SAndrew Jeffery 
7348761c62SAndrew Jeffery 	// Convert effecter PDR body
7448761c62SAndrew Jeffery 	HTOLE16(effecter->terminus_handle);
7548761c62SAndrew Jeffery 	HTOLE16(effecter->effecter_id);
7648761c62SAndrew Jeffery 	HTOLE16(effecter->entity_type);
7748761c62SAndrew Jeffery 	HTOLE16(effecter->entity_instance);
7848761c62SAndrew Jeffery 	HTOLE16(effecter->container_id);
7948761c62SAndrew Jeffery 	HTOLE16(effecter->effecter_semantic_id);
8048761c62SAndrew Jeffery 
8148761c62SAndrew Jeffery 	// Convert header
8248761c62SAndrew Jeffery 	HTOLE32(effecter->hdr.record_handle);
8348761c62SAndrew Jeffery 	HTOLE16(effecter->hdr.record_change_num);
8448761c62SAndrew Jeffery 	HTOLE16(effecter->hdr.length);
8548761c62SAndrew Jeffery 
8648761c62SAndrew Jeffery 	return PLDM_SUCCESS;
8748761c62SAndrew Jeffery }
8848761c62SAndrew Jeffery 
8948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
9048761c62SAndrew Jeffery int encode_state_sensor_pdr(
9148761c62SAndrew Jeffery 	struct pldm_state_sensor_pdr *const sensor,
9248761c62SAndrew Jeffery 	const size_t allocation_size,
9348761c62SAndrew Jeffery 	const struct state_sensor_possible_states *const possible_states,
9448761c62SAndrew Jeffery 	const size_t possible_states_size, size_t *const actual_size)
9548761c62SAndrew Jeffery {
9648761c62SAndrew Jeffery 	// Encode possible states
9748761c62SAndrew Jeffery 
9848761c62SAndrew Jeffery 	size_t calculated_possible_states_size = 0;
9948761c62SAndrew Jeffery 
10048761c62SAndrew Jeffery 	{
10148761c62SAndrew Jeffery 		char *states_ptr = (char *)possible_states;
10248761c62SAndrew Jeffery 		char *const begin_states_ptr = states_ptr;
10348761c62SAndrew Jeffery 
10448761c62SAndrew Jeffery 		for (int i = 0; i < sensor->composite_sensor_count; ++i) {
10548761c62SAndrew Jeffery 			struct state_sensor_possible_states *states =
10648761c62SAndrew Jeffery 				(struct state_sensor_possible_states *)
10748761c62SAndrew Jeffery 					states_ptr;
10848761c62SAndrew Jeffery 
10948761c62SAndrew Jeffery 			HTOLE16(states->state_set_id);
11048761c62SAndrew Jeffery 
11148761c62SAndrew Jeffery 			states_ptr +=
11248761c62SAndrew Jeffery 				(sizeof(*states) - sizeof(states->states) +
11348761c62SAndrew Jeffery 				 states->possible_states_size);
11448761c62SAndrew Jeffery 		}
11548761c62SAndrew Jeffery 
11648761c62SAndrew Jeffery 		calculated_possible_states_size = states_ptr - begin_states_ptr;
11748761c62SAndrew Jeffery 	}
11848761c62SAndrew Jeffery 
11948761c62SAndrew Jeffery 	// Check lengths
12048761c62SAndrew Jeffery 
12148761c62SAndrew Jeffery 	if (possible_states_size != calculated_possible_states_size) {
12248761c62SAndrew Jeffery 		*actual_size = 0;
12348761c62SAndrew Jeffery 		return PLDM_ERROR;
12448761c62SAndrew Jeffery 	}
12548761c62SAndrew Jeffery 
12648761c62SAndrew Jeffery 	*actual_size = (sizeof(struct pldm_state_sensor_pdr) +
12748761c62SAndrew Jeffery 			possible_states_size - sizeof(sensor->possible_states));
12848761c62SAndrew Jeffery 
12948761c62SAndrew Jeffery 	if (allocation_size < *actual_size) {
13048761c62SAndrew Jeffery 		*actual_size = 0;
13148761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
13248761c62SAndrew Jeffery 	}
13348761c62SAndrew Jeffery 
13448761c62SAndrew Jeffery 	// Encode rest of PDR
13548761c62SAndrew Jeffery 
13648761c62SAndrew Jeffery 	sensor->hdr.version = 1;
13748761c62SAndrew Jeffery 	sensor->hdr.type = PLDM_STATE_SENSOR_PDR;
13848761c62SAndrew Jeffery 	sensor->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
13948761c62SAndrew Jeffery 
14048761c62SAndrew Jeffery 	memcpy(sensor->possible_states, possible_states, possible_states_size);
14148761c62SAndrew Jeffery 
14248761c62SAndrew Jeffery 	// Convert sensor PDR body
14348761c62SAndrew Jeffery 	HTOLE16(sensor->terminus_handle);
14448761c62SAndrew Jeffery 	HTOLE16(sensor->sensor_id);
14548761c62SAndrew Jeffery 	HTOLE16(sensor->entity_type);
14648761c62SAndrew Jeffery 	HTOLE16(sensor->entity_instance);
14748761c62SAndrew Jeffery 	HTOLE16(sensor->container_id);
14848761c62SAndrew Jeffery 
14948761c62SAndrew Jeffery 	// Convert header
15048761c62SAndrew Jeffery 	HTOLE32(sensor->hdr.record_handle);
15148761c62SAndrew Jeffery 	HTOLE16(sensor->hdr.record_change_num);
15248761c62SAndrew Jeffery 	HTOLE16(sensor->hdr.length);
15348761c62SAndrew Jeffery 
15448761c62SAndrew Jeffery 	return PLDM_SUCCESS;
15548761c62SAndrew Jeffery }
15648761c62SAndrew Jeffery 
15748761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
15848761c62SAndrew Jeffery int encode_set_state_effecter_states_resp(uint8_t instance_id,
15948761c62SAndrew Jeffery 					  uint8_t completion_code,
16048761c62SAndrew Jeffery 					  struct pldm_msg *msg)
16148761c62SAndrew Jeffery {
16248761c62SAndrew Jeffery 	if (msg == NULL) {
16348761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
16448761c62SAndrew Jeffery 	}
16548761c62SAndrew Jeffery 
16648761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
16748761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
16848761c62SAndrew Jeffery 	header.instance = instance_id;
16948761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
17048761c62SAndrew Jeffery 	header.command = PLDM_SET_STATE_EFFECTER_STATES;
17148761c62SAndrew Jeffery 
17248761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
17348761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
17448761c62SAndrew Jeffery 		return rc;
17548761c62SAndrew Jeffery 	}
17648761c62SAndrew Jeffery 
17748761c62SAndrew Jeffery 	msg->payload[0] = completion_code;
17848761c62SAndrew Jeffery 
17948761c62SAndrew Jeffery 	return PLDM_SUCCESS;
18048761c62SAndrew Jeffery }
18148761c62SAndrew Jeffery 
18248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
18348761c62SAndrew Jeffery int encode_set_state_effecter_states_req(uint8_t instance_id,
18448761c62SAndrew Jeffery 					 uint16_t effecter_id,
18548761c62SAndrew Jeffery 					 uint8_t comp_effecter_count,
18648761c62SAndrew Jeffery 					 set_effecter_state_field *field,
18748761c62SAndrew Jeffery 					 struct pldm_msg *msg)
18848761c62SAndrew Jeffery {
18948761c62SAndrew Jeffery 	if (msg == NULL) {
19048761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
19148761c62SAndrew Jeffery 	}
19248761c62SAndrew Jeffery 
19348761c62SAndrew Jeffery 	if (comp_effecter_count < 0x1 || comp_effecter_count > 0x8 ||
19448761c62SAndrew Jeffery 	    field == NULL) {
19548761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
19648761c62SAndrew Jeffery 	}
19748761c62SAndrew Jeffery 
19848761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
19948761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
20048761c62SAndrew Jeffery 	header.instance = instance_id;
20148761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
20248761c62SAndrew Jeffery 	header.command = PLDM_SET_STATE_EFFECTER_STATES;
20348761c62SAndrew Jeffery 
20448761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
20548761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
20648761c62SAndrew Jeffery 		return rc;
20748761c62SAndrew Jeffery 	}
20848761c62SAndrew Jeffery 
20948761c62SAndrew Jeffery 	struct pldm_set_state_effecter_states_req *request =
21048761c62SAndrew Jeffery 		(struct pldm_set_state_effecter_states_req *)msg->payload;
21148761c62SAndrew Jeffery 	effecter_id = htole16(effecter_id);
21248761c62SAndrew Jeffery 	request->effecter_id = effecter_id;
21348761c62SAndrew Jeffery 	request->comp_effecter_count = comp_effecter_count;
21448761c62SAndrew Jeffery 	memcpy(request->field, field,
21548761c62SAndrew Jeffery 	       (sizeof(set_effecter_state_field) * comp_effecter_count));
21648761c62SAndrew Jeffery 
21748761c62SAndrew Jeffery 	return PLDM_SUCCESS;
21848761c62SAndrew Jeffery }
21948761c62SAndrew Jeffery 
22048761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
22148761c62SAndrew Jeffery int decode_set_state_effecter_states_resp(const struct pldm_msg *msg,
22248761c62SAndrew Jeffery 					  size_t payload_length,
22348761c62SAndrew Jeffery 					  uint8_t *completion_code)
22448761c62SAndrew Jeffery {
22548761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL) {
22648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
22748761c62SAndrew Jeffery 	}
22848761c62SAndrew Jeffery 
22948761c62SAndrew Jeffery 	*completion_code = msg->payload[0];
23048761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
23148761c62SAndrew Jeffery 		return PLDM_SUCCESS;
23248761c62SAndrew Jeffery 	}
23348761c62SAndrew Jeffery 
23448761c62SAndrew Jeffery 	if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES) {
23548761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
23648761c62SAndrew Jeffery 	}
23748761c62SAndrew Jeffery 
23848761c62SAndrew Jeffery 	return PLDM_SUCCESS;
23948761c62SAndrew Jeffery }
24048761c62SAndrew Jeffery 
24148761c62SAndrew Jeffery #define PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE 3
24248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
24348761c62SAndrew Jeffery int decode_set_state_effecter_states_req(const struct pldm_msg *msg,
24448761c62SAndrew Jeffery 					 size_t payload_length,
24548761c62SAndrew Jeffery 					 uint16_t *effecter_id,
24648761c62SAndrew Jeffery 					 uint8_t *comp_effecter_count,
24748761c62SAndrew Jeffery 					 set_effecter_state_field *field)
24848761c62SAndrew Jeffery {
24948761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
25048761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
25148761c62SAndrew Jeffery 	int rc;
25248761c62SAndrew Jeffery 	int i;
25348761c62SAndrew Jeffery 
25448761c62SAndrew Jeffery 	if (msg == NULL || effecter_id == NULL || comp_effecter_count == NULL ||
25548761c62SAndrew Jeffery 	    field == NULL) {
25648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
25748761c62SAndrew Jeffery 	}
25848761c62SAndrew Jeffery 
25948761c62SAndrew Jeffery 	if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) {
26048761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
26148761c62SAndrew Jeffery 	}
26248761c62SAndrew Jeffery 
263830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf,
264830c1eb4SAndrew Jeffery 				    PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE,
26548761c62SAndrew Jeffery 				    msg->payload, payload_length);
26648761c62SAndrew Jeffery 	if (rc) {
267830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
26848761c62SAndrew Jeffery 	}
26948761c62SAndrew Jeffery 
27048761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, effecter_id);
27148761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, comp_effecter_count);
27248761c62SAndrew Jeffery 
27348761c62SAndrew Jeffery 	if (*comp_effecter_count > 8) {
27448761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
27548761c62SAndrew Jeffery 	}
27648761c62SAndrew Jeffery 
27748761c62SAndrew Jeffery 	for (i = 0; i < *comp_effecter_count; i++) {
27848761c62SAndrew Jeffery 		pldm_msgbuf_extract(buf, field[i].set_request);
27948761c62SAndrew Jeffery 		pldm_msgbuf_extract(buf, field[i].effecter_state);
28048761c62SAndrew Jeffery 	}
28148761c62SAndrew Jeffery 
282830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
283830c1eb4SAndrew Jeffery 	if (rc) {
284830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
285830c1eb4SAndrew Jeffery 	}
286830c1eb4SAndrew Jeffery 
287830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
28848761c62SAndrew Jeffery }
28948761c62SAndrew Jeffery 
29048761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
29148761c62SAndrew Jeffery int decode_get_pdr_req(const struct pldm_msg *msg, size_t payload_length,
29248761c62SAndrew Jeffery 		       uint32_t *record_hndl, uint32_t *data_transfer_hndl,
29348761c62SAndrew Jeffery 		       uint8_t *transfer_op_flag, uint16_t *request_cnt,
29448761c62SAndrew Jeffery 		       uint16_t *record_chg_num)
29548761c62SAndrew Jeffery {
29648761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
29748761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
29848761c62SAndrew Jeffery 	int rc;
29948761c62SAndrew Jeffery 
30048761c62SAndrew Jeffery 	if (msg == NULL || record_hndl == NULL || data_transfer_hndl == NULL ||
30148761c62SAndrew Jeffery 	    transfer_op_flag == NULL || request_cnt == NULL ||
30248761c62SAndrew Jeffery 	    record_chg_num == NULL) {
30348761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
30448761c62SAndrew Jeffery 	}
30548761c62SAndrew Jeffery 
30648761c62SAndrew Jeffery 	if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
30748761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
30848761c62SAndrew Jeffery 	}
30948761c62SAndrew Jeffery 
310830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_REQ_BYTES, msg->payload,
31148761c62SAndrew Jeffery 				    payload_length);
31248761c62SAndrew Jeffery 	if (rc) {
313830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
31448761c62SAndrew Jeffery 	}
31548761c62SAndrew Jeffery 
31648761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, record_hndl);
31748761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, data_transfer_hndl);
31848761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, transfer_op_flag);
31948761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, request_cnt);
32048761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, record_chg_num);
32148761c62SAndrew Jeffery 
322830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
323830c1eb4SAndrew Jeffery 	if (rc) {
324830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
325830c1eb4SAndrew Jeffery 	}
326830c1eb4SAndrew Jeffery 
327830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
32848761c62SAndrew Jeffery }
32948761c62SAndrew Jeffery 
33048761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
33148761c62SAndrew Jeffery int encode_get_pdr_resp(uint8_t instance_id, uint8_t completion_code,
33248761c62SAndrew Jeffery 			uint32_t next_record_hndl,
33348761c62SAndrew Jeffery 			uint32_t next_data_transfer_hndl, uint8_t transfer_flag,
33448761c62SAndrew Jeffery 			uint16_t resp_cnt, const uint8_t *record_data,
33548761c62SAndrew Jeffery 			uint8_t transfer_crc, struct pldm_msg *msg)
33648761c62SAndrew Jeffery {
33748761c62SAndrew Jeffery 	if (msg == NULL) {
33848761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
33948761c62SAndrew Jeffery 	}
34048761c62SAndrew Jeffery 
34148761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
34248761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
34348761c62SAndrew Jeffery 	header.instance = instance_id;
34448761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
34548761c62SAndrew Jeffery 	header.command = PLDM_GET_PDR;
34648761c62SAndrew Jeffery 
34748761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
34848761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
34948761c62SAndrew Jeffery 		return rc;
35048761c62SAndrew Jeffery 	}
35148761c62SAndrew Jeffery 
35248761c62SAndrew Jeffery 	struct pldm_get_pdr_resp *response =
35348761c62SAndrew Jeffery 		(struct pldm_get_pdr_resp *)msg->payload;
35448761c62SAndrew Jeffery 	response->completion_code = completion_code;
35548761c62SAndrew Jeffery 
35648761c62SAndrew Jeffery 	if (response->completion_code == PLDM_SUCCESS) {
35748761c62SAndrew Jeffery 		response->next_record_handle = htole32(next_record_hndl);
35848761c62SAndrew Jeffery 		response->next_data_transfer_handle =
35948761c62SAndrew Jeffery 			htole32(next_data_transfer_hndl);
36048761c62SAndrew Jeffery 		response->transfer_flag = transfer_flag;
36148761c62SAndrew Jeffery 		response->response_count = htole16(resp_cnt);
36248761c62SAndrew Jeffery 		if (record_data != NULL && resp_cnt > 0) {
36348761c62SAndrew Jeffery 			memcpy(response->record_data, record_data, resp_cnt);
36448761c62SAndrew Jeffery 		}
36548761c62SAndrew Jeffery 		if (transfer_flag == PLDM_END) {
36648761c62SAndrew Jeffery 			uint8_t *dst = msg->payload;
36748761c62SAndrew Jeffery 			dst += (sizeof(struct pldm_get_pdr_resp) - 1) +
36848761c62SAndrew Jeffery 			       resp_cnt;
36948761c62SAndrew Jeffery 			*dst = transfer_crc;
37048761c62SAndrew Jeffery 		}
37148761c62SAndrew Jeffery 	}
37248761c62SAndrew Jeffery 
37348761c62SAndrew Jeffery 	return PLDM_SUCCESS;
37448761c62SAndrew Jeffery }
37548761c62SAndrew Jeffery 
37648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
37748761c62SAndrew Jeffery int encode_get_pdr_repository_info_resp(
37848761c62SAndrew Jeffery 	uint8_t instance_id, uint8_t completion_code, uint8_t repository_state,
37948761c62SAndrew Jeffery 	const uint8_t *update_time, const uint8_t *oem_update_time,
38048761c62SAndrew Jeffery 	uint32_t record_count, uint32_t repository_size,
38148761c62SAndrew Jeffery 	uint32_t largest_record_size, uint8_t data_transfer_handle_timeout,
38248761c62SAndrew Jeffery 	struct pldm_msg *msg)
38348761c62SAndrew Jeffery {
38448761c62SAndrew Jeffery 	if (msg == NULL) {
38548761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
38648761c62SAndrew Jeffery 	}
38748761c62SAndrew Jeffery 
38848761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
38948761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
39048761c62SAndrew Jeffery 	header.instance = instance_id;
39148761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
39248761c62SAndrew Jeffery 	header.command = PLDM_GET_PDR_REPOSITORY_INFO;
39348761c62SAndrew Jeffery 
39448761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
39548761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
39648761c62SAndrew Jeffery 		return rc;
39748761c62SAndrew Jeffery 	}
39848761c62SAndrew Jeffery 
39948761c62SAndrew Jeffery 	struct pldm_pdr_repository_info_resp *response =
40048761c62SAndrew Jeffery 		(struct pldm_pdr_repository_info_resp *)msg->payload;
40148761c62SAndrew Jeffery 	response->completion_code = completion_code;
40248761c62SAndrew Jeffery 
40348761c62SAndrew Jeffery 	if (response->completion_code == PLDM_SUCCESS) {
40448761c62SAndrew Jeffery 		response->repository_state = repository_state;
40548761c62SAndrew Jeffery 		if (update_time != NULL) {
40648761c62SAndrew Jeffery 			memcpy(response->update_time, update_time,
40748761c62SAndrew Jeffery 			       PLDM_TIMESTAMP104_SIZE);
40848761c62SAndrew Jeffery 		}
40948761c62SAndrew Jeffery 		if (oem_update_time != NULL) {
41048761c62SAndrew Jeffery 			memcpy(response->oem_update_time, oem_update_time,
41148761c62SAndrew Jeffery 			       PLDM_TIMESTAMP104_SIZE);
41248761c62SAndrew Jeffery 		}
41348761c62SAndrew Jeffery 		response->record_count = htole32(record_count);
41448761c62SAndrew Jeffery 		response->repository_size = htole32(repository_size);
41548761c62SAndrew Jeffery 		response->largest_record_size = htole32(largest_record_size);
41648761c62SAndrew Jeffery 		response->data_transfer_handle_timeout =
41748761c62SAndrew Jeffery 			data_transfer_handle_timeout;
41848761c62SAndrew Jeffery 	}
41948761c62SAndrew Jeffery 
42048761c62SAndrew Jeffery 	return PLDM_SUCCESS;
42148761c62SAndrew Jeffery }
42248761c62SAndrew Jeffery 
4230a1be3cbSAndrew Jeffery LIBPLDM_ABI_DEPRECATED
42448761c62SAndrew Jeffery int decode_get_pdr_repository_info_resp(
42548761c62SAndrew Jeffery 	const struct pldm_msg *msg, size_t payload_length,
42648761c62SAndrew Jeffery 	uint8_t *completion_code, uint8_t *repository_state,
42748761c62SAndrew Jeffery 	uint8_t *update_time, uint8_t *oem_update_time, uint32_t *record_count,
42848761c62SAndrew Jeffery 	uint32_t *repository_size, uint32_t *largest_record_size,
42948761c62SAndrew Jeffery 	uint8_t *data_transfer_handle_timeout)
43048761c62SAndrew Jeffery {
43148761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
43248761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
43348761c62SAndrew Jeffery 	int rc;
43448761c62SAndrew Jeffery 
43548761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL ||
43648761c62SAndrew Jeffery 	    repository_state == NULL || update_time == NULL ||
43748761c62SAndrew Jeffery 	    oem_update_time == NULL || record_count == NULL ||
43848761c62SAndrew Jeffery 	    repository_size == NULL || largest_record_size == NULL ||
43948761c62SAndrew Jeffery 	    data_transfer_handle_timeout == NULL) {
44048761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
44148761c62SAndrew Jeffery 	}
44248761c62SAndrew Jeffery 
443830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf,
444830c1eb4SAndrew Jeffery 				    PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
44548761c62SAndrew Jeffery 				    msg->payload, payload_length);
44648761c62SAndrew Jeffery 	if (rc) {
447830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
44848761c62SAndrew Jeffery 	}
44948761c62SAndrew Jeffery 
45048761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, completion_code);
45148761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
45248761c62SAndrew Jeffery 		return PLDM_SUCCESS;
45348761c62SAndrew Jeffery 	}
45448761c62SAndrew Jeffery 
455830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, repository_state);
456830c1eb4SAndrew Jeffery 	if (rc) {
457830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
458830c1eb4SAndrew Jeffery 	}
459830c1eb4SAndrew Jeffery 
46048761c62SAndrew Jeffery 	if (*repository_state > PLDM_FAILED) {
46148761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
46248761c62SAndrew Jeffery 	}
46348761c62SAndrew Jeffery 
4640a1be3cbSAndrew Jeffery 	/* NOTE: Memory safety */
4650a1be3cbSAndrew Jeffery 	rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE, update_time,
4660a1be3cbSAndrew Jeffery 				       PLDM_TIMESTAMP104_SIZE);
4670a1be3cbSAndrew Jeffery 	if (rc) {
468830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
4690a1be3cbSAndrew Jeffery 	}
4700a1be3cbSAndrew Jeffery 
4710a1be3cbSAndrew Jeffery 	/* NOTE: Memory safety */
4720a1be3cbSAndrew Jeffery 	rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE,
4730a1be3cbSAndrew Jeffery 				       oem_update_time, PLDM_TIMESTAMP104_SIZE);
4740a1be3cbSAndrew Jeffery 	if (rc) {
475830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
4760a1be3cbSAndrew Jeffery 	}
4770a1be3cbSAndrew Jeffery 
47848761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, record_count);
47948761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, repository_size);
48048761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, largest_record_size);
48148761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, data_transfer_handle_timeout);
48248761c62SAndrew Jeffery 
483830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
484830c1eb4SAndrew Jeffery 	if (rc) {
485830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
486830c1eb4SAndrew Jeffery 	}
487830c1eb4SAndrew Jeffery 
488830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
48948761c62SAndrew Jeffery }
49048761c62SAndrew Jeffery 
4910a1be3cbSAndrew Jeffery LIBPLDM_ABI_TESTING
4920a1be3cbSAndrew Jeffery int decode_get_pdr_repository_info_resp_safe(
4930a1be3cbSAndrew Jeffery 	const struct pldm_msg *msg, size_t payload_length,
4940a1be3cbSAndrew Jeffery 	struct pldm_pdr_repository_info_resp *resp)
4950a1be3cbSAndrew Jeffery {
4960a1be3cbSAndrew Jeffery 	struct pldm_msgbuf _buf;
4970a1be3cbSAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
4980a1be3cbSAndrew Jeffery 	int rc;
4990a1be3cbSAndrew Jeffery 
5000a1be3cbSAndrew Jeffery 	if (msg == NULL || resp == NULL) {
5010a1be3cbSAndrew Jeffery 		return -EINVAL;
5020a1be3cbSAndrew Jeffery 	}
5030a1be3cbSAndrew Jeffery 
5040a1be3cbSAndrew Jeffery 	rc = pldm_msg_has_error(msg, payload_length);
5050a1be3cbSAndrew Jeffery 	if (rc) {
5060a1be3cbSAndrew Jeffery 		resp->completion_code = rc;
5070a1be3cbSAndrew Jeffery 		return 0;
5080a1be3cbSAndrew Jeffery 	}
5090a1be3cbSAndrew Jeffery 
5100a1be3cbSAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf,
5110a1be3cbSAndrew Jeffery 				    PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
5120a1be3cbSAndrew Jeffery 				    msg->payload, payload_length);
5130a1be3cbSAndrew Jeffery 	if (rc) {
5140a1be3cbSAndrew Jeffery 		return rc;
5150a1be3cbSAndrew Jeffery 	}
5160a1be3cbSAndrew Jeffery 
5170a1be3cbSAndrew Jeffery 	rc = pldm_msgbuf_extract(buf, resp->completion_code);
5180a1be3cbSAndrew Jeffery 	if (rc) {
5190a1be3cbSAndrew Jeffery 		return rc;
5200a1be3cbSAndrew Jeffery 	}
5210a1be3cbSAndrew Jeffery 
5220a1be3cbSAndrew Jeffery 	pldm_msgbuf_extract(buf, resp->repository_state);
5230a1be3cbSAndrew Jeffery 
5240a1be3cbSAndrew Jeffery 	rc = pldm_msgbuf_extract_array(buf, sizeof(resp->update_time),
5250a1be3cbSAndrew Jeffery 				       resp->update_time,
5260a1be3cbSAndrew Jeffery 				       sizeof(resp->update_time));
5270a1be3cbSAndrew Jeffery 	if (rc) {
5280a1be3cbSAndrew Jeffery 		return rc;
5290a1be3cbSAndrew Jeffery 	}
5300a1be3cbSAndrew Jeffery 
5310a1be3cbSAndrew Jeffery 	rc = pldm_msgbuf_extract_array(buf, sizeof(resp->oem_update_time),
5320a1be3cbSAndrew Jeffery 				       resp->oem_update_time,
5330a1be3cbSAndrew Jeffery 				       sizeof(resp->oem_update_time));
5340a1be3cbSAndrew Jeffery 	if (rc) {
5350a1be3cbSAndrew Jeffery 		return rc;
5360a1be3cbSAndrew Jeffery 	}
5370a1be3cbSAndrew Jeffery 
5380a1be3cbSAndrew Jeffery 	pldm_msgbuf_extract(buf, resp->record_count);
5390a1be3cbSAndrew Jeffery 	pldm_msgbuf_extract(buf, resp->repository_size);
5400a1be3cbSAndrew Jeffery 	pldm_msgbuf_extract(buf, resp->largest_record_size);
5410a1be3cbSAndrew Jeffery 	pldm_msgbuf_extract(buf, resp->data_transfer_handle_timeout);
5420a1be3cbSAndrew Jeffery 
5430a1be3cbSAndrew Jeffery 	return pldm_msgbuf_destroy_consumed(buf);
5440a1be3cbSAndrew Jeffery }
5450a1be3cbSAndrew Jeffery 
54648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
54748761c62SAndrew Jeffery int encode_get_pdr_req(uint8_t instance_id, uint32_t record_hndl,
54848761c62SAndrew Jeffery 		       uint32_t data_transfer_hndl, uint8_t transfer_op_flag,
54948761c62SAndrew Jeffery 		       uint16_t request_cnt, uint16_t record_chg_num,
55048761c62SAndrew Jeffery 		       struct pldm_msg *msg, size_t payload_length)
55148761c62SAndrew Jeffery {
55248761c62SAndrew Jeffery 	if (msg == NULL) {
55348761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
55448761c62SAndrew Jeffery 	}
55548761c62SAndrew Jeffery 
55648761c62SAndrew Jeffery 	if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
55748761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
55848761c62SAndrew Jeffery 	}
55948761c62SAndrew Jeffery 
56048761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
56148761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
56248761c62SAndrew Jeffery 	header.instance = instance_id;
56348761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
56448761c62SAndrew Jeffery 	header.command = PLDM_GET_PDR;
56548761c62SAndrew Jeffery 
56648761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
56748761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
56848761c62SAndrew Jeffery 		return rc;
56948761c62SAndrew Jeffery 	}
57048761c62SAndrew Jeffery 
57148761c62SAndrew Jeffery 	struct pldm_get_pdr_req *request =
57248761c62SAndrew Jeffery 		(struct pldm_get_pdr_req *)msg->payload;
57348761c62SAndrew Jeffery 	request->record_handle = htole32(record_hndl);
57448761c62SAndrew Jeffery 	request->data_transfer_handle = htole32(data_transfer_hndl);
57548761c62SAndrew Jeffery 	request->transfer_op_flag = transfer_op_flag;
57648761c62SAndrew Jeffery 	request->request_count = htole16(request_cnt);
57748761c62SAndrew Jeffery 	request->record_change_number = htole16(record_chg_num);
57848761c62SAndrew Jeffery 
57948761c62SAndrew Jeffery 	return PLDM_SUCCESS;
58048761c62SAndrew Jeffery }
58148761c62SAndrew Jeffery 
5820a1be3cbSAndrew Jeffery LIBPLDM_ABI_DEPRECATED
58348761c62SAndrew Jeffery int decode_get_pdr_resp(const struct pldm_msg *msg, size_t payload_length,
58448761c62SAndrew Jeffery 			uint8_t *completion_code, uint32_t *next_record_hndl,
58548761c62SAndrew Jeffery 			uint32_t *next_data_transfer_hndl,
58648761c62SAndrew Jeffery 			uint8_t *transfer_flag, uint16_t *resp_cnt,
58748761c62SAndrew Jeffery 			uint8_t *record_data, size_t record_data_length,
58848761c62SAndrew Jeffery 			uint8_t *transfer_crc)
58948761c62SAndrew Jeffery {
59048761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
59148761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
59248761c62SAndrew Jeffery 	int rc;
59348761c62SAndrew Jeffery 
59448761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL ||
59548761c62SAndrew Jeffery 	    next_record_hndl == NULL || next_data_transfer_hndl == NULL ||
59648761c62SAndrew Jeffery 	    transfer_flag == NULL || resp_cnt == NULL || transfer_crc == NULL) {
59748761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
59848761c62SAndrew Jeffery 	}
59948761c62SAndrew Jeffery 
600830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES,
601830c1eb4SAndrew Jeffery 				    msg->payload, payload_length);
60248761c62SAndrew Jeffery 	if (rc) {
603830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
60448761c62SAndrew Jeffery 	}
60548761c62SAndrew Jeffery 
606830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, completion_code);
607830c1eb4SAndrew Jeffery 	if (rc) {
608830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
609830c1eb4SAndrew Jeffery 	}
610830c1eb4SAndrew Jeffery 
61148761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
61248761c62SAndrew Jeffery 		return PLDM_SUCCESS;
61348761c62SAndrew Jeffery 	}
61448761c62SAndrew Jeffery 
61548761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, next_record_hndl);
61648761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, next_data_transfer_hndl);
61748761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, transfer_flag);
61848761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, resp_cnt);
61948761c62SAndrew Jeffery 	if (rc) {
620830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
62148761c62SAndrew Jeffery 	}
62248761c62SAndrew Jeffery 
62348761c62SAndrew Jeffery 	if (*resp_cnt > 0 && record_data != NULL) {
62448761c62SAndrew Jeffery 		if (record_data_length < *resp_cnt) {
62548761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
62648761c62SAndrew Jeffery 		}
6270a1be3cbSAndrew Jeffery 		/* NOTE: Memory safety */
6280a1be3cbSAndrew Jeffery 		rc = pldm_msgbuf_extract_array(buf, *resp_cnt, record_data,
6290a1be3cbSAndrew Jeffery 					       *resp_cnt);
6300a1be3cbSAndrew Jeffery 		if (rc) {
631830c1eb4SAndrew Jeffery 			return pldm_xlate_errno(rc);
6320a1be3cbSAndrew Jeffery 		}
63348761c62SAndrew Jeffery 	}
63448761c62SAndrew Jeffery 
63548761c62SAndrew Jeffery 	if (*transfer_flag == PLDM_END) {
63648761c62SAndrew Jeffery 		pldm_msgbuf_extract_p(buf, transfer_crc);
63748761c62SAndrew Jeffery 	}
63848761c62SAndrew Jeffery 
639830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
640830c1eb4SAndrew Jeffery 	if (rc) {
641830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
642830c1eb4SAndrew Jeffery 	}
643830c1eb4SAndrew Jeffery 
644830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
64548761c62SAndrew Jeffery }
64648761c62SAndrew Jeffery 
6470a1be3cbSAndrew Jeffery LIBPLDM_ABI_TESTING
6480a1be3cbSAndrew Jeffery int decode_get_pdr_resp_safe(const struct pldm_msg *msg, size_t payload_length,
6490a1be3cbSAndrew Jeffery 			     struct pldm_get_pdr_resp *resp, size_t resp_len,
6500a1be3cbSAndrew Jeffery 			     uint8_t *transfer_crc)
6510a1be3cbSAndrew Jeffery {
6520a1be3cbSAndrew Jeffery 	struct pldm_msgbuf _buf;
6530a1be3cbSAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
6540a1be3cbSAndrew Jeffery 	int rc;
6550a1be3cbSAndrew Jeffery 
6560a1be3cbSAndrew Jeffery 	if (msg == NULL || resp == NULL || transfer_crc == NULL) {
6570a1be3cbSAndrew Jeffery 		return -EINVAL;
6580a1be3cbSAndrew Jeffery 	}
6590a1be3cbSAndrew Jeffery 
6600a1be3cbSAndrew Jeffery 	rc = pldm_msg_has_error(msg, payload_length);
6610a1be3cbSAndrew Jeffery 	if (rc) {
6620a1be3cbSAndrew Jeffery 		resp->completion_code = rc;
6630a1be3cbSAndrew Jeffery 		return 0;
6640a1be3cbSAndrew Jeffery 	}
6650a1be3cbSAndrew Jeffery 
6660a1be3cbSAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES,
6670a1be3cbSAndrew Jeffery 				    msg->payload, payload_length);
6680a1be3cbSAndrew Jeffery 	if (rc) {
6690a1be3cbSAndrew Jeffery 		return rc;
6700a1be3cbSAndrew Jeffery 	}
6710a1be3cbSAndrew Jeffery 
6720a1be3cbSAndrew Jeffery 	pldm_msgbuf_extract(buf, resp->completion_code);
6730a1be3cbSAndrew Jeffery 	pldm_msgbuf_extract(buf, resp->next_record_handle);
6740a1be3cbSAndrew Jeffery 	pldm_msgbuf_extract(buf, resp->next_data_transfer_handle);
6750a1be3cbSAndrew Jeffery 
6760a1be3cbSAndrew Jeffery 	rc = pldm_msgbuf_extract(buf, resp->transfer_flag);
6770a1be3cbSAndrew Jeffery 	if (rc) {
6780a1be3cbSAndrew Jeffery 		return rc;
6790a1be3cbSAndrew Jeffery 	}
6800a1be3cbSAndrew Jeffery 
6810a1be3cbSAndrew Jeffery 	rc = pldm_msgbuf_extract(buf, resp->response_count);
6820a1be3cbSAndrew Jeffery 	if (rc) {
6830a1be3cbSAndrew Jeffery 		return rc;
6840a1be3cbSAndrew Jeffery 	}
6850a1be3cbSAndrew Jeffery 
6860a1be3cbSAndrew Jeffery 	rc = pldm_msgbuf_extract_array(
6870a1be3cbSAndrew Jeffery 		buf, resp->response_count, resp->record_data,
6880a1be3cbSAndrew Jeffery 		resp_len - (sizeof(*resp) - sizeof(resp->record_data)));
6890a1be3cbSAndrew Jeffery 	if (rc) {
6900a1be3cbSAndrew Jeffery 		return rc;
6910a1be3cbSAndrew Jeffery 	}
6920a1be3cbSAndrew Jeffery 
6930a1be3cbSAndrew Jeffery 	if (resp->transfer_flag == PLDM_END) {
6940a1be3cbSAndrew Jeffery 		pldm_msgbuf_extract_p(buf, transfer_crc);
6950a1be3cbSAndrew Jeffery 	}
6960a1be3cbSAndrew Jeffery 
6970a1be3cbSAndrew Jeffery 	return pldm_msgbuf_destroy_consumed(buf);
6980a1be3cbSAndrew Jeffery }
6990a1be3cbSAndrew Jeffery 
70048761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
70148761c62SAndrew Jeffery int decode_set_numeric_effecter_value_req(const struct pldm_msg *msg,
70248761c62SAndrew Jeffery 					  size_t payload_length,
70348761c62SAndrew Jeffery 					  uint16_t *effecter_id,
70448761c62SAndrew Jeffery 					  uint8_t *effecter_data_size,
70548761c62SAndrew Jeffery 					  uint8_t effecter_value[4])
70648761c62SAndrew Jeffery {
70748761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
70848761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
70948761c62SAndrew Jeffery 	int rc;
71048761c62SAndrew Jeffery 
71148761c62SAndrew Jeffery 	if (msg == NULL || effecter_id == NULL || effecter_data_size == NULL ||
71248761c62SAndrew Jeffery 	    effecter_value == NULL) {
71348761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
71448761c62SAndrew Jeffery 	}
71548761c62SAndrew Jeffery 
716830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(
717830c1eb4SAndrew Jeffery 		buf, PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES,
71848761c62SAndrew Jeffery 		msg->payload, payload_length);
71948761c62SAndrew Jeffery 	if (rc) {
720830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
72148761c62SAndrew Jeffery 	}
72248761c62SAndrew Jeffery 
72348761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, effecter_id);
72448761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
72548761c62SAndrew Jeffery 	if (rc) {
72648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
72748761c62SAndrew Jeffery 	}
72848761c62SAndrew Jeffery 
72948761c62SAndrew Jeffery 	if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
73048761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
73148761c62SAndrew Jeffery 	}
73248761c62SAndrew Jeffery 
73348761c62SAndrew Jeffery 	pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
73448761c62SAndrew Jeffery 					   effecter_value);
73548761c62SAndrew Jeffery 
736830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
737830c1eb4SAndrew Jeffery 	if (rc) {
738830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
739830c1eb4SAndrew Jeffery 	}
740830c1eb4SAndrew Jeffery 
741830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
74248761c62SAndrew Jeffery }
74348761c62SAndrew Jeffery 
74448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
74548761c62SAndrew Jeffery int encode_set_numeric_effecter_value_resp(uint8_t instance_id,
74648761c62SAndrew Jeffery 					   uint8_t completion_code,
74748761c62SAndrew Jeffery 					   struct pldm_msg *msg,
74848761c62SAndrew Jeffery 					   size_t payload_length)
74948761c62SAndrew Jeffery {
75048761c62SAndrew Jeffery 	if (msg == NULL) {
75148761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
75248761c62SAndrew Jeffery 	}
75348761c62SAndrew Jeffery 
75448761c62SAndrew Jeffery 	if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
75548761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
75648761c62SAndrew Jeffery 	}
75748761c62SAndrew Jeffery 
75848761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
75948761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
76048761c62SAndrew Jeffery 	header.instance = instance_id;
76148761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
76248761c62SAndrew Jeffery 	header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
76348761c62SAndrew Jeffery 
76448761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
76548761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
76648761c62SAndrew Jeffery 		return rc;
76748761c62SAndrew Jeffery 	}
76848761c62SAndrew Jeffery 
76948761c62SAndrew Jeffery 	msg->payload[0] = completion_code;
77048761c62SAndrew Jeffery 
77148761c62SAndrew Jeffery 	return rc;
77248761c62SAndrew Jeffery }
77348761c62SAndrew Jeffery 
77448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
77548761c62SAndrew Jeffery int encode_set_numeric_effecter_value_req(uint8_t instance_id,
77648761c62SAndrew Jeffery 					  uint16_t effecter_id,
77748761c62SAndrew Jeffery 					  uint8_t effecter_data_size,
77848761c62SAndrew Jeffery 					  const uint8_t *effecter_value,
77948761c62SAndrew Jeffery 					  struct pldm_msg *msg,
78048761c62SAndrew Jeffery 					  size_t payload_length)
78148761c62SAndrew Jeffery {
78248761c62SAndrew Jeffery 	if (msg == NULL || effecter_value == NULL) {
78348761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
78448761c62SAndrew Jeffery 	}
78548761c62SAndrew Jeffery 
78648761c62SAndrew Jeffery 	if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
78748761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
78848761c62SAndrew Jeffery 	}
78948761c62SAndrew Jeffery 
79048761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
79148761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
79248761c62SAndrew Jeffery 	header.instance = instance_id;
79348761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
79448761c62SAndrew Jeffery 	header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
79548761c62SAndrew Jeffery 
79648761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
79748761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
79848761c62SAndrew Jeffery 		return rc;
79948761c62SAndrew Jeffery 	}
80048761c62SAndrew Jeffery 
80148761c62SAndrew Jeffery 	struct pldm_set_numeric_effecter_value_req *request =
80248761c62SAndrew Jeffery 		(struct pldm_set_numeric_effecter_value_req *)msg->payload;
80348761c62SAndrew Jeffery 	if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
80448761c62SAndrew Jeffery 	    effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
80548761c62SAndrew Jeffery 		if (payload_length !=
80648761c62SAndrew Jeffery 		    PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) {
80748761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
80848761c62SAndrew Jeffery 		}
80948761c62SAndrew Jeffery 		request->effecter_value[0] = *effecter_value;
81048761c62SAndrew Jeffery 	} else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
81148761c62SAndrew Jeffery 		   effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
81248761c62SAndrew Jeffery 		if (payload_length !=
81348761c62SAndrew Jeffery 		    PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1) {
81448761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
81548761c62SAndrew Jeffery 		}
81648761c62SAndrew Jeffery 
81748761c62SAndrew Jeffery 		uint16_t val = *(uint16_t *)(effecter_value);
81848761c62SAndrew Jeffery 		val = htole16(val);
81948761c62SAndrew Jeffery 		memcpy(request->effecter_value, &val, sizeof(uint16_t));
82048761c62SAndrew Jeffery 
82148761c62SAndrew Jeffery 	} else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
82248761c62SAndrew Jeffery 		   effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
82348761c62SAndrew Jeffery 		if (payload_length !=
82448761c62SAndrew Jeffery 		    PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3) {
82548761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
82648761c62SAndrew Jeffery 		}
82748761c62SAndrew Jeffery 
82848761c62SAndrew Jeffery 		uint32_t val = *(uint32_t *)(effecter_value);
82948761c62SAndrew Jeffery 		val = htole32(val);
83048761c62SAndrew Jeffery 		memcpy(request->effecter_value, &val, sizeof(uint32_t));
83148761c62SAndrew Jeffery 	}
83248761c62SAndrew Jeffery 
83348761c62SAndrew Jeffery 	request->effecter_id = htole16(effecter_id);
83448761c62SAndrew Jeffery 	request->effecter_data_size = effecter_data_size;
83548761c62SAndrew Jeffery 
83648761c62SAndrew Jeffery 	return PLDM_SUCCESS;
83748761c62SAndrew Jeffery }
83848761c62SAndrew Jeffery 
83948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
84048761c62SAndrew Jeffery int decode_set_numeric_effecter_value_resp(const struct pldm_msg *msg,
84148761c62SAndrew Jeffery 					   size_t payload_length,
84248761c62SAndrew Jeffery 					   uint8_t *completion_code)
84348761c62SAndrew Jeffery {
84448761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL) {
84548761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
84648761c62SAndrew Jeffery 	}
84748761c62SAndrew Jeffery 
84848761c62SAndrew Jeffery 	if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
84948761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
85048761c62SAndrew Jeffery 	}
85148761c62SAndrew Jeffery 
85248761c62SAndrew Jeffery 	*completion_code = msg->payload[0];
85348761c62SAndrew Jeffery 
85448761c62SAndrew Jeffery 	return PLDM_SUCCESS;
85548761c62SAndrew Jeffery }
85648761c62SAndrew Jeffery 
85748761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
85848761c62SAndrew Jeffery int encode_get_state_sensor_readings_resp(uint8_t instance_id,
85948761c62SAndrew Jeffery 					  uint8_t completion_code,
86048761c62SAndrew Jeffery 					  uint8_t comp_sensor_count,
86148761c62SAndrew Jeffery 					  get_sensor_state_field *field,
86248761c62SAndrew Jeffery 					  struct pldm_msg *msg)
86348761c62SAndrew Jeffery {
86448761c62SAndrew Jeffery 	if (msg == NULL) {
86548761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
86648761c62SAndrew Jeffery 	}
86748761c62SAndrew Jeffery 
86848761c62SAndrew Jeffery 	if (comp_sensor_count < 0x1 || comp_sensor_count > 0x8) {
86948761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
87048761c62SAndrew Jeffery 	}
87148761c62SAndrew Jeffery 
87248761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
87348761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
87448761c62SAndrew Jeffery 	header.instance = instance_id;
87548761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
87648761c62SAndrew Jeffery 	header.command = PLDM_GET_STATE_SENSOR_READINGS;
87748761c62SAndrew Jeffery 
87848761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
87948761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
88048761c62SAndrew Jeffery 		return rc;
88148761c62SAndrew Jeffery 	}
88248761c62SAndrew Jeffery 
88348761c62SAndrew Jeffery 	struct pldm_get_state_sensor_readings_resp *response =
88448761c62SAndrew Jeffery 		(struct pldm_get_state_sensor_readings_resp *)msg->payload;
88548761c62SAndrew Jeffery 
88648761c62SAndrew Jeffery 	response->completion_code = completion_code;
88748761c62SAndrew Jeffery 	response->comp_sensor_count = comp_sensor_count;
88848761c62SAndrew Jeffery 	memcpy(response->field, field,
88948761c62SAndrew Jeffery 	       (sizeof(get_sensor_state_field) * comp_sensor_count));
89048761c62SAndrew Jeffery 
89148761c62SAndrew Jeffery 	return PLDM_SUCCESS;
89248761c62SAndrew Jeffery }
89348761c62SAndrew Jeffery 
89448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
89548761c62SAndrew Jeffery int encode_get_state_sensor_readings_req(uint8_t instance_id,
89648761c62SAndrew Jeffery 					 uint16_t sensor_id,
89748761c62SAndrew Jeffery 					 bitfield8_t sensor_rearm,
89848761c62SAndrew Jeffery 					 uint8_t reserved, struct pldm_msg *msg)
89948761c62SAndrew Jeffery {
90048761c62SAndrew Jeffery 	if (msg == NULL) {
90148761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
90248761c62SAndrew Jeffery 	}
90348761c62SAndrew Jeffery 
90448761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
90548761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
90648761c62SAndrew Jeffery 	header.instance = instance_id;
90748761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
90848761c62SAndrew Jeffery 	header.command = PLDM_GET_STATE_SENSOR_READINGS;
90948761c62SAndrew Jeffery 
91048761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
91148761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
91248761c62SAndrew Jeffery 		return rc;
91348761c62SAndrew Jeffery 	}
91448761c62SAndrew Jeffery 
91548761c62SAndrew Jeffery 	struct pldm_get_state_sensor_readings_req *request =
91648761c62SAndrew Jeffery 		(struct pldm_get_state_sensor_readings_req *)msg->payload;
91748761c62SAndrew Jeffery 
91848761c62SAndrew Jeffery 	request->sensor_id = htole16(sensor_id);
91948761c62SAndrew Jeffery 	request->reserved = reserved;
92048761c62SAndrew Jeffery 	request->sensor_rearm = sensor_rearm;
92148761c62SAndrew Jeffery 
92248761c62SAndrew Jeffery 	return PLDM_SUCCESS;
92348761c62SAndrew Jeffery }
92448761c62SAndrew Jeffery 
92548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
92648761c62SAndrew Jeffery int decode_get_state_sensor_readings_resp(const struct pldm_msg *msg,
92748761c62SAndrew Jeffery 					  size_t payload_length,
92848761c62SAndrew Jeffery 					  uint8_t *completion_code,
92948761c62SAndrew Jeffery 					  uint8_t *comp_sensor_count,
93048761c62SAndrew Jeffery 					  get_sensor_state_field *field)
93148761c62SAndrew Jeffery {
93248761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
93348761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
93448761c62SAndrew Jeffery 	uint8_t i;
93548761c62SAndrew Jeffery 	int rc;
93648761c62SAndrew Jeffery 
93748761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL ||
93848761c62SAndrew Jeffery 	    comp_sensor_count == NULL || field == NULL) {
93948761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
94048761c62SAndrew Jeffery 	}
94148761c62SAndrew Jeffery 
942830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(
943830c1eb4SAndrew Jeffery 		buf, PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES,
94448761c62SAndrew Jeffery 		msg->payload, payload_length);
94548761c62SAndrew Jeffery 	if (rc) {
946830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
94748761c62SAndrew Jeffery 	}
94848761c62SAndrew Jeffery 
94948761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, completion_code);
95048761c62SAndrew Jeffery 	if (rc) {
951830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
95248761c62SAndrew Jeffery 	}
95348761c62SAndrew Jeffery 
95448761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
95548761c62SAndrew Jeffery 		return PLDM_SUCCESS;
95648761c62SAndrew Jeffery 	}
95748761c62SAndrew Jeffery 
95848761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, comp_sensor_count);
95948761c62SAndrew Jeffery 	if (rc) {
960830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
96148761c62SAndrew Jeffery 	}
96248761c62SAndrew Jeffery 
96348761c62SAndrew Jeffery 	if (*comp_sensor_count < 0x1 || *comp_sensor_count > 0x8) {
96448761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
96548761c62SAndrew Jeffery 	}
96648761c62SAndrew Jeffery 
96748761c62SAndrew Jeffery 	for (i = 0; i < *comp_sensor_count; i++) {
96848761c62SAndrew Jeffery 		pldm_msgbuf_extract(buf, field[i].sensor_op_state);
96948761c62SAndrew Jeffery 		pldm_msgbuf_extract(buf, field[i].present_state);
97048761c62SAndrew Jeffery 		pldm_msgbuf_extract(buf, field[i].previous_state);
97148761c62SAndrew Jeffery 		pldm_msgbuf_extract(buf, field[i].event_state);
97248761c62SAndrew Jeffery 	}
97348761c62SAndrew Jeffery 
974830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy_consumed(buf);
975830c1eb4SAndrew Jeffery 	if (rc) {
976830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
977830c1eb4SAndrew Jeffery 	}
978830c1eb4SAndrew Jeffery 
979830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
98048761c62SAndrew Jeffery }
98148761c62SAndrew Jeffery 
98248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
98348761c62SAndrew Jeffery int decode_get_state_sensor_readings_req(const struct pldm_msg *msg,
98448761c62SAndrew Jeffery 					 size_t payload_length,
98548761c62SAndrew Jeffery 					 uint16_t *sensor_id,
98648761c62SAndrew Jeffery 					 bitfield8_t *sensor_rearm,
98748761c62SAndrew Jeffery 					 uint8_t *reserved)
98848761c62SAndrew Jeffery {
98948761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
99048761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
99148761c62SAndrew Jeffery 	int rc;
99248761c62SAndrew Jeffery 
99348761c62SAndrew Jeffery 	if (msg == NULL || sensor_id == NULL || sensor_rearm == NULL) {
99448761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
99548761c62SAndrew Jeffery 	}
99648761c62SAndrew Jeffery 
997830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf,
998830c1eb4SAndrew Jeffery 				    PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES,
99948761c62SAndrew Jeffery 				    msg->payload, payload_length);
100048761c62SAndrew Jeffery 	if (rc) {
1001830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
100248761c62SAndrew Jeffery 	}
100348761c62SAndrew Jeffery 
100448761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, sensor_id);
100548761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, sensor_rearm->byte);
100648761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, reserved);
100748761c62SAndrew Jeffery 
1008830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
1009830c1eb4SAndrew Jeffery 	if (rc) {
1010830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1011830c1eb4SAndrew Jeffery 	}
1012830c1eb4SAndrew Jeffery 
1013830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
101448761c62SAndrew Jeffery }
101548761c62SAndrew Jeffery 
101648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
101748761c62SAndrew Jeffery int encode_sensor_event_data(
101848761c62SAndrew Jeffery 	struct pldm_sensor_event_data *const event_data,
101948761c62SAndrew Jeffery 	const size_t event_data_size, const uint16_t sensor_id,
102048761c62SAndrew Jeffery 	const enum sensor_event_class_states sensor_event_class,
102148761c62SAndrew Jeffery 	const uint8_t sensor_offset, const uint8_t event_state,
102248761c62SAndrew Jeffery 	const uint8_t previous_event_state,
102348761c62SAndrew Jeffery 	size_t *const actual_event_data_size)
102448761c62SAndrew Jeffery {
102548761c62SAndrew Jeffery 	*actual_event_data_size =
102648761c62SAndrew Jeffery 		(sizeof(*event_data) - sizeof(event_data->event_class) +
102748761c62SAndrew Jeffery 		 sizeof(struct pldm_sensor_event_state_sensor_state));
102848761c62SAndrew Jeffery 
102948761c62SAndrew Jeffery 	if (!event_data) {
103048761c62SAndrew Jeffery 		return PLDM_SUCCESS;
103148761c62SAndrew Jeffery 	}
103248761c62SAndrew Jeffery 
103348761c62SAndrew Jeffery 	if (event_data_size < *actual_event_data_size) {
103448761c62SAndrew Jeffery 		*actual_event_data_size = 0;
103548761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
103648761c62SAndrew Jeffery 	}
103748761c62SAndrew Jeffery 
103848761c62SAndrew Jeffery 	event_data->sensor_id = htole16(sensor_id);
103948761c62SAndrew Jeffery 	event_data->sensor_event_class_type = sensor_event_class;
104048761c62SAndrew Jeffery 
104148761c62SAndrew Jeffery 	struct pldm_sensor_event_state_sensor_state *const state_data =
104248761c62SAndrew Jeffery 		(struct pldm_sensor_event_state_sensor_state *)
104348761c62SAndrew Jeffery 			event_data->event_class;
104448761c62SAndrew Jeffery 
104548761c62SAndrew Jeffery 	state_data->sensor_offset = sensor_offset;
104648761c62SAndrew Jeffery 	state_data->event_state = event_state;
104748761c62SAndrew Jeffery 	state_data->previous_event_state = previous_event_state;
104848761c62SAndrew Jeffery 
104948761c62SAndrew Jeffery 	return PLDM_SUCCESS;
105048761c62SAndrew Jeffery }
105148761c62SAndrew Jeffery 
105248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
105348761c62SAndrew Jeffery int decode_platform_event_message_req(const struct pldm_msg *msg,
105448761c62SAndrew Jeffery 				      size_t payload_length,
105548761c62SAndrew Jeffery 				      uint8_t *format_version, uint8_t *tid,
105648761c62SAndrew Jeffery 				      uint8_t *event_class,
105748761c62SAndrew Jeffery 				      size_t *event_data_offset)
105848761c62SAndrew Jeffery {
105948761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
106048761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
106148761c62SAndrew Jeffery 	int rc;
106248761c62SAndrew Jeffery 
106348761c62SAndrew Jeffery 	if (msg == NULL || format_version == NULL || tid == NULL ||
106448761c62SAndrew Jeffery 	    event_class == NULL || event_data_offset == NULL) {
106548761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
106648761c62SAndrew Jeffery 	}
106748761c62SAndrew Jeffery 
1068830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf,
1069830c1eb4SAndrew Jeffery 				    PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES,
107048761c62SAndrew Jeffery 				    msg->payload, payload_length);
107148761c62SAndrew Jeffery 	if (rc) {
1072830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
107348761c62SAndrew Jeffery 	}
107448761c62SAndrew Jeffery 
107548761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, format_version);
107648761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, tid);
107748761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, event_class);
1078830c1eb4SAndrew Jeffery 
1079830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
1080830c1eb4SAndrew Jeffery 	if (rc) {
1081830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1082830c1eb4SAndrew Jeffery 	}
1083830c1eb4SAndrew Jeffery 
108448761c62SAndrew Jeffery 	*event_data_offset =
108548761c62SAndrew Jeffery 		sizeof(*format_version) + sizeof(*tid) + sizeof(*event_class);
108648761c62SAndrew Jeffery 
1087830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
108848761c62SAndrew Jeffery }
108948761c62SAndrew Jeffery 
1090387b10f6SThu Nguyen static int pldm_platform_poll_for_platform_event_message_validate(
1091387b10f6SThu Nguyen 	uint8_t transfer_operation_flag, uint16_t event_id_to_acknowledge)
1092387b10f6SThu Nguyen {
1093387b10f6SThu Nguyen 	if (((transfer_operation_flag == PLDM_GET_FIRSTPART) &&
1094387b10f6SThu Nguyen 	     (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_NULL)) ||
1095387b10f6SThu Nguyen 	    ((transfer_operation_flag == PLDM_GET_NEXTPART) &&
1096387b10f6SThu Nguyen 	     (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_FRAGMENT)) ||
1097387b10f6SThu Nguyen 	    ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) &&
10989e16b18bSThu Nguyen 	     (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_FRAGMENT)) ||
10999e16b18bSThu Nguyen 	    ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) &&
11009e16b18bSThu Nguyen 	     (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_NULL)) ||
1101387b10f6SThu Nguyen 	    (transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY)) {
1102387b10f6SThu Nguyen 		return -EPROTO;
1103387b10f6SThu Nguyen 	}
1104387b10f6SThu Nguyen 
1105387b10f6SThu Nguyen 	return 0;
1106387b10f6SThu Nguyen }
1107387b10f6SThu Nguyen 
110848761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
110948761c62SAndrew Jeffery int decode_poll_for_platform_event_message_req(
111048761c62SAndrew Jeffery 	const struct pldm_msg *msg, size_t payload_length,
111148761c62SAndrew Jeffery 	uint8_t *format_version, uint8_t *transfer_operation_flag,
111248761c62SAndrew Jeffery 	uint32_t *data_transfer_handle, uint16_t *event_id_to_acknowledge)
111348761c62SAndrew Jeffery {
111448761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
111548761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
111648761c62SAndrew Jeffery 	int rc;
111748761c62SAndrew Jeffery 
111890bbe6c0SAndrew Jeffery 	if (msg == NULL || format_version == NULL ||
111990bbe6c0SAndrew Jeffery 	    transfer_operation_flag == NULL || data_transfer_handle == NULL ||
112090bbe6c0SAndrew Jeffery 	    event_id_to_acknowledge == NULL) {
112148761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
112248761c62SAndrew Jeffery 	}
112348761c62SAndrew Jeffery 
1124830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(
1125830c1eb4SAndrew Jeffery 		buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES,
112648761c62SAndrew Jeffery 		msg->payload, payload_length);
112748761c62SAndrew Jeffery 	if (rc) {
1128830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
112948761c62SAndrew Jeffery 	}
113048761c62SAndrew Jeffery 
113148761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, format_version);
113248761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, transfer_operation_flag);
113348761c62SAndrew Jeffery 	if (rc) {
1134830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
113548761c62SAndrew Jeffery 	}
113648761c62SAndrew Jeffery 	if (*transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY) {
113748761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
113848761c62SAndrew Jeffery 	}
113948761c62SAndrew Jeffery 
114048761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, data_transfer_handle);
114148761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, event_id_to_acknowledge);
114248761c62SAndrew Jeffery 	if (rc) {
1143830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
114448761c62SAndrew Jeffery 	}
114548761c62SAndrew Jeffery 
1146387b10f6SThu Nguyen 	rc = pldm_platform_poll_for_platform_event_message_validate(
1147387b10f6SThu Nguyen 		*transfer_operation_flag, *event_id_to_acknowledge);
1148387b10f6SThu Nguyen 	if (rc < 0) {
114948761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
115048761c62SAndrew Jeffery 	}
115148761c62SAndrew Jeffery 
1152830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
1153830c1eb4SAndrew Jeffery 	if (rc) {
1154830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1155830c1eb4SAndrew Jeffery 	}
1156830c1eb4SAndrew Jeffery 
1157830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
115848761c62SAndrew Jeffery }
115948761c62SAndrew Jeffery 
116048761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
116148761c62SAndrew Jeffery int encode_platform_event_message_resp(uint8_t instance_id,
116248761c62SAndrew Jeffery 				       uint8_t completion_code,
116348761c62SAndrew Jeffery 				       uint8_t platform_event_status,
116448761c62SAndrew Jeffery 				       struct pldm_msg *msg)
116548761c62SAndrew Jeffery {
116648761c62SAndrew Jeffery 	if (msg == NULL) {
116748761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
116848761c62SAndrew Jeffery 	}
116948761c62SAndrew Jeffery 
117048761c62SAndrew Jeffery 	if (platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
117148761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
117248761c62SAndrew Jeffery 	}
117348761c62SAndrew Jeffery 
117448761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
117548761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
117648761c62SAndrew Jeffery 	header.instance = instance_id;
117748761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
117848761c62SAndrew Jeffery 	header.command = PLDM_PLATFORM_EVENT_MESSAGE;
117948761c62SAndrew Jeffery 
118048761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
118148761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
118248761c62SAndrew Jeffery 		return rc;
118348761c62SAndrew Jeffery 	}
118448761c62SAndrew Jeffery 
118548761c62SAndrew Jeffery 	struct pldm_platform_event_message_resp *response =
118648761c62SAndrew Jeffery 		(struct pldm_platform_event_message_resp *)msg->payload;
118748761c62SAndrew Jeffery 	response->completion_code = completion_code;
118848761c62SAndrew Jeffery 	response->platform_event_status = platform_event_status;
118948761c62SAndrew Jeffery 
119048761c62SAndrew Jeffery 	return PLDM_SUCCESS;
119148761c62SAndrew Jeffery }
119248761c62SAndrew Jeffery 
119348761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
119448761c62SAndrew Jeffery int encode_poll_for_platform_event_message_resp(
119548761c62SAndrew Jeffery 	uint8_t instance_id, uint8_t completion_code, uint8_t tid,
119648761c62SAndrew Jeffery 	uint16_t event_id, uint32_t next_data_transfer_handle,
119748761c62SAndrew Jeffery 	uint8_t transfer_flag, uint8_t event_class, uint32_t event_data_size,
119848761c62SAndrew Jeffery 	uint8_t *event_data, uint32_t checksum, struct pldm_msg *msg,
119948761c62SAndrew Jeffery 	size_t payload_length)
120048761c62SAndrew Jeffery {
120148761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
120248761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
120348761c62SAndrew Jeffery 	int rc;
120448761c62SAndrew Jeffery 
120548761c62SAndrew Jeffery 	if (!msg) {
120648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
120748761c62SAndrew Jeffery 	}
120848761c62SAndrew Jeffery 
120948761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
121048761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
121148761c62SAndrew Jeffery 	header.instance = instance_id;
121248761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
121348761c62SAndrew Jeffery 	header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
121448761c62SAndrew Jeffery 
121548761c62SAndrew Jeffery 	rc = pack_pldm_header(&header, &(msg->hdr));
121648761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
121748761c62SAndrew Jeffery 		return rc;
121848761c62SAndrew Jeffery 	}
121948761c62SAndrew Jeffery 
1220830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(
122148761c62SAndrew Jeffery 		buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
122248761c62SAndrew Jeffery 		msg->payload, payload_length);
122348761c62SAndrew Jeffery 	if (rc) {
1224830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
122548761c62SAndrew Jeffery 	}
122648761c62SAndrew Jeffery 
122748761c62SAndrew Jeffery 	pldm_msgbuf_insert(buf, completion_code);
122848761c62SAndrew Jeffery 	pldm_msgbuf_insert(buf, tid);
1229830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_insert(buf, event_id);
1230830c1eb4SAndrew Jeffery 	if (rc) {
1231830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1232830c1eb4SAndrew Jeffery 	}
123348761c62SAndrew Jeffery 
123448761c62SAndrew Jeffery 	if (event_id == 0xffff || event_id == 0x0000) {
123548761c62SAndrew Jeffery 		if (PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES !=
123648761c62SAndrew Jeffery 		    payload_length) {
123748761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
123848761c62SAndrew Jeffery 		}
1239830c1eb4SAndrew Jeffery 
1240830c1eb4SAndrew Jeffery 		rc = pldm_msgbuf_destroy(buf);
1241830c1eb4SAndrew Jeffery 		if (rc) {
1242830c1eb4SAndrew Jeffery 			return pldm_xlate_errno(rc);
1243830c1eb4SAndrew Jeffery 		}
1244830c1eb4SAndrew Jeffery 
1245830c1eb4SAndrew Jeffery 		return PLDM_SUCCESS;
124648761c62SAndrew Jeffery 	}
124748761c62SAndrew Jeffery 
124848761c62SAndrew Jeffery 	if ((event_data == NULL) && (event_data_size > 0)) {
124948761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
125048761c62SAndrew Jeffery 	}
125148761c62SAndrew Jeffery 
125248761c62SAndrew Jeffery 	pldm_msgbuf_insert(buf, next_data_transfer_handle);
125348761c62SAndrew Jeffery 	pldm_msgbuf_insert(buf, transfer_flag);
125448761c62SAndrew Jeffery 	pldm_msgbuf_insert(buf, event_class);
1255830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_insert(buf, event_data_size);
1256830c1eb4SAndrew Jeffery 	if (rc) {
1257830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1258830c1eb4SAndrew Jeffery 	}
125948761c62SAndrew Jeffery 
126048761c62SAndrew Jeffery 	if ((event_data_size > 0) && event_data) {
12610a1be3cbSAndrew Jeffery 		rc = pldm_msgbuf_insert_array(buf, event_data_size, event_data,
12620a1be3cbSAndrew Jeffery 					      event_data_size);
12630a1be3cbSAndrew Jeffery 		if (rc) {
1264830c1eb4SAndrew Jeffery 			return pldm_xlate_errno(rc);
12650a1be3cbSAndrew Jeffery 		}
126648761c62SAndrew Jeffery 	}
126748761c62SAndrew Jeffery 
126848761c62SAndrew Jeffery 	if (transfer_flag == PLDM_END || transfer_flag == PLDM_START_AND_END) {
126948761c62SAndrew Jeffery 		pldm_msgbuf_insert(buf, checksum);
127048761c62SAndrew Jeffery 	}
127148761c62SAndrew Jeffery 
1272830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
1273830c1eb4SAndrew Jeffery 	if (rc) {
1274830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1275830c1eb4SAndrew Jeffery 	}
1276830c1eb4SAndrew Jeffery 
1277830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
127848761c62SAndrew Jeffery }
127948761c62SAndrew Jeffery 
128048761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
128148761c62SAndrew Jeffery int encode_platform_event_message_req(
128248761c62SAndrew Jeffery 	uint8_t instance_id, uint8_t format_version, uint8_t tid,
128348761c62SAndrew Jeffery 	uint8_t event_class, const uint8_t *event_data,
128448761c62SAndrew Jeffery 	size_t event_data_length, struct pldm_msg *msg, size_t payload_length)
128548761c62SAndrew Jeffery 
128648761c62SAndrew Jeffery {
128748761c62SAndrew Jeffery 	if (format_version != 1) {
128848761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
128948761c62SAndrew Jeffery 	}
129048761c62SAndrew Jeffery 
129148761c62SAndrew Jeffery 	if (msg == NULL || event_data == NULL) {
129248761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
129348761c62SAndrew Jeffery 	}
129448761c62SAndrew Jeffery 
129548761c62SAndrew Jeffery 	if (event_data_length == 0) {
129648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
129748761c62SAndrew Jeffery 	}
129848761c62SAndrew Jeffery 
1299*225530abSAndrew Jeffery 	if ((SIZE_MAX - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) <
1300*225530abSAndrew Jeffery 	    event_data_length) {
1301*225530abSAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
1302*225530abSAndrew Jeffery 	}
1303*225530abSAndrew Jeffery 
130448761c62SAndrew Jeffery 	if (payload_length !=
130548761c62SAndrew Jeffery 	    PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) {
130648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
130748761c62SAndrew Jeffery 	}
130848761c62SAndrew Jeffery 
1309b43a7787SJohn Chung 	if (event_class > PLDM_CPER_EVENT &&
131048761c62SAndrew Jeffery 	    !(event_class >= 0xf0 && event_class <= 0xfe)) {
131148761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
131248761c62SAndrew Jeffery 	}
131348761c62SAndrew Jeffery 
131448761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
131548761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
131648761c62SAndrew Jeffery 	header.instance = instance_id;
131748761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
131848761c62SAndrew Jeffery 	header.command = PLDM_PLATFORM_EVENT_MESSAGE;
131948761c62SAndrew Jeffery 
132048761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
132148761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
132248761c62SAndrew Jeffery 		return rc;
132348761c62SAndrew Jeffery 	}
132448761c62SAndrew Jeffery 
132548761c62SAndrew Jeffery 	struct pldm_platform_event_message_req *request =
132648761c62SAndrew Jeffery 		(struct pldm_platform_event_message_req *)msg->payload;
132748761c62SAndrew Jeffery 	request->format_version = format_version;
132848761c62SAndrew Jeffery 	request->tid = tid;
132948761c62SAndrew Jeffery 	request->event_class = event_class;
133048761c62SAndrew Jeffery 	memcpy(request->event_data, event_data, event_data_length);
133148761c62SAndrew Jeffery 
133248761c62SAndrew Jeffery 	return PLDM_SUCCESS;
133348761c62SAndrew Jeffery }
133448761c62SAndrew Jeffery 
133548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
133648761c62SAndrew Jeffery int decode_platform_event_message_resp(const struct pldm_msg *msg,
133748761c62SAndrew Jeffery 				       size_t payload_length,
133848761c62SAndrew Jeffery 				       uint8_t *completion_code,
133948761c62SAndrew Jeffery 				       uint8_t *platform_event_status)
134048761c62SAndrew Jeffery {
134148761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
134248761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
134348761c62SAndrew Jeffery 	int rc;
134448761c62SAndrew Jeffery 
134548761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL ||
134648761c62SAndrew Jeffery 	    platform_event_status == NULL) {
134748761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
134848761c62SAndrew Jeffery 	}
134948761c62SAndrew Jeffery 
1350830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES,
135148761c62SAndrew Jeffery 				    msg->payload, payload_length);
135248761c62SAndrew Jeffery 	if (rc) {
1353830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
135448761c62SAndrew Jeffery 	}
135548761c62SAndrew Jeffery 
135648761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, completion_code);
135748761c62SAndrew Jeffery 	if (rc) {
1358830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
135948761c62SAndrew Jeffery 	}
136048761c62SAndrew Jeffery 
136148761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
136248761c62SAndrew Jeffery 		return PLDM_SUCCESS;
136348761c62SAndrew Jeffery 	}
136448761c62SAndrew Jeffery 
136548761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, platform_event_status);
136648761c62SAndrew Jeffery 	if (rc) {
1367830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
136848761c62SAndrew Jeffery 	}
136948761c62SAndrew Jeffery 
137048761c62SAndrew Jeffery 	if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
137148761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
137248761c62SAndrew Jeffery 	}
137348761c62SAndrew Jeffery 
1374830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
1375830c1eb4SAndrew Jeffery 	if (rc) {
1376830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1377830c1eb4SAndrew Jeffery 	}
1378830c1eb4SAndrew Jeffery 
1379830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
138048761c62SAndrew Jeffery }
138148761c62SAndrew Jeffery 
138248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
138348761c62SAndrew Jeffery int encode_event_message_buffer_size_req(uint8_t instance_id,
138448761c62SAndrew Jeffery 					 uint16_t event_receiver_max_buffer_size,
138548761c62SAndrew Jeffery 					 struct pldm_msg *msg)
138648761c62SAndrew Jeffery {
138748761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
138848761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
138948761c62SAndrew Jeffery 	header.instance = instance_id;
139048761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
139148761c62SAndrew Jeffery 	header.command = PLDM_EVENT_MESSAGE_BUFFER_SIZE;
139248761c62SAndrew Jeffery 
139348761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
139448761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
139548761c62SAndrew Jeffery 		return rc;
139648761c62SAndrew Jeffery 	}
139748761c62SAndrew Jeffery 
139848761c62SAndrew Jeffery 	struct pldm_event_message_buffer_size_req *request =
139948761c62SAndrew Jeffery 		(struct pldm_event_message_buffer_size_req *)msg->payload;
140048761c62SAndrew Jeffery 	request->event_receiver_max_buffer_size =
140148761c62SAndrew Jeffery 		event_receiver_max_buffer_size;
140248761c62SAndrew Jeffery 
140348761c62SAndrew Jeffery 	return PLDM_SUCCESS;
140448761c62SAndrew Jeffery }
140548761c62SAndrew Jeffery 
140648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
140748761c62SAndrew Jeffery int decode_event_message_buffer_size_resp(const struct pldm_msg *msg,
140848761c62SAndrew Jeffery 					  size_t payload_length,
140948761c62SAndrew Jeffery 					  uint8_t *completion_code,
141048761c62SAndrew Jeffery 					  uint16_t *terminus_max_buffer_size)
141148761c62SAndrew Jeffery {
141248761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
141348761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
141448761c62SAndrew Jeffery 	int rc;
141548761c62SAndrew Jeffery 
141648761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL ||
141748761c62SAndrew Jeffery 	    terminus_max_buffer_size == NULL) {
141848761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
141948761c62SAndrew Jeffery 	}
142048761c62SAndrew Jeffery 
1421830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf,
1422830c1eb4SAndrew Jeffery 				    PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES,
142348761c62SAndrew Jeffery 				    msg->payload, payload_length);
142448761c62SAndrew Jeffery 	if (rc) {
1425830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
142648761c62SAndrew Jeffery 	}
142748761c62SAndrew Jeffery 
142848761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, completion_code);
142948761c62SAndrew Jeffery 	if (rc) {
1430830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
143148761c62SAndrew Jeffery 	}
143248761c62SAndrew Jeffery 
143348761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
143448761c62SAndrew Jeffery 		return PLDM_SUCCESS;
143548761c62SAndrew Jeffery 	}
143648761c62SAndrew Jeffery 
143748761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, terminus_max_buffer_size);
143848761c62SAndrew Jeffery 
1439830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy_consumed(buf);
1440830c1eb4SAndrew Jeffery 	if (rc) {
1441830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1442830c1eb4SAndrew Jeffery 	}
1443830c1eb4SAndrew Jeffery 
1444830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
144548761c62SAndrew Jeffery }
144648761c62SAndrew Jeffery 
144748761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
144848761c62SAndrew Jeffery int encode_event_message_supported_req(uint8_t instance_id,
144948761c62SAndrew Jeffery 				       uint8_t format_version,
145048761c62SAndrew Jeffery 				       struct pldm_msg *msg)
145148761c62SAndrew Jeffery {
145248761c62SAndrew Jeffery 	if (format_version != 1) {
145348761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
145448761c62SAndrew Jeffery 	}
145548761c62SAndrew Jeffery 
145648761c62SAndrew Jeffery 	if (msg == NULL) {
145748761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
145848761c62SAndrew Jeffery 	}
145948761c62SAndrew Jeffery 
146048761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
146148761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
146248761c62SAndrew Jeffery 	header.instance = instance_id;
146348761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
146448761c62SAndrew Jeffery 	header.command = PLDM_EVENT_MESSAGE_SUPPORTED;
146548761c62SAndrew Jeffery 
146648761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
146748761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
146848761c62SAndrew Jeffery 		return rc;
146948761c62SAndrew Jeffery 	}
147048761c62SAndrew Jeffery 
147148761c62SAndrew Jeffery 	struct pldm_event_message_supported_req *request =
147248761c62SAndrew Jeffery 		(struct pldm_event_message_supported_req *)msg->payload;
147348761c62SAndrew Jeffery 	request->format_version = format_version;
147448761c62SAndrew Jeffery 
147548761c62SAndrew Jeffery 	return PLDM_SUCCESS;
147648761c62SAndrew Jeffery }
147748761c62SAndrew Jeffery 
147848761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
147948761c62SAndrew Jeffery int decode_event_message_supported_resp(const struct pldm_msg *msg,
148048761c62SAndrew Jeffery 					size_t payload_length,
148148761c62SAndrew Jeffery 					uint8_t *completion_code,
148248761c62SAndrew Jeffery 					uint8_t *synchrony_config,
148348761c62SAndrew Jeffery 					bitfield8_t *synchrony_config_support,
148448761c62SAndrew Jeffery 					uint8_t *number_event_class_returned,
148548761c62SAndrew Jeffery 					uint8_t *event_class,
148648761c62SAndrew Jeffery 					uint8_t event_class_count)
148748761c62SAndrew Jeffery {
148848761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
148948761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
149048761c62SAndrew Jeffery 	int i;
149148761c62SAndrew Jeffery 	int rc;
149248761c62SAndrew Jeffery 
149348761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL ||
149448761c62SAndrew Jeffery 	    synchrony_config == NULL || synchrony_config_support == NULL ||
149548761c62SAndrew Jeffery 	    number_event_class_returned == NULL || event_class == NULL) {
149648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
149748761c62SAndrew Jeffery 	}
149848761c62SAndrew Jeffery 
1499830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf,
150048761c62SAndrew Jeffery 				    PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES,
150148761c62SAndrew Jeffery 				    msg->payload, payload_length);
150248761c62SAndrew Jeffery 	if (rc) {
1503830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
150448761c62SAndrew Jeffery 	}
150548761c62SAndrew Jeffery 
150648761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, completion_code);
150748761c62SAndrew Jeffery 	if (rc) {
1508830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
150948761c62SAndrew Jeffery 	}
151048761c62SAndrew Jeffery 
151148761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
151248761c62SAndrew Jeffery 		return PLDM_SUCCESS;
151348761c62SAndrew Jeffery 	}
151448761c62SAndrew Jeffery 
151548761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, synchrony_config);
151648761c62SAndrew Jeffery 	if (rc) {
1517830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
151848761c62SAndrew Jeffery 	}
151948761c62SAndrew Jeffery 
152048761c62SAndrew Jeffery 	if (*synchrony_config > PLDM_MESSAGE_TYPE_ASYNCHRONOUS_WITH_HEARTBEAT) {
152148761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
152248761c62SAndrew Jeffery 	}
152348761c62SAndrew Jeffery 
152448761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, &synchrony_config_support->byte);
152548761c62SAndrew Jeffery 
152648761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, number_event_class_returned);
152748761c62SAndrew Jeffery 	if (rc) {
1528830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
152948761c62SAndrew Jeffery 	}
153048761c62SAndrew Jeffery 
153148761c62SAndrew Jeffery 	if (*number_event_class_returned == 0) {
1532830c1eb4SAndrew Jeffery 		rc = pldm_msgbuf_destroy(buf);
1533830c1eb4SAndrew Jeffery 		if (rc) {
1534830c1eb4SAndrew Jeffery 			return pldm_xlate_errno(rc);
1535830c1eb4SAndrew Jeffery 		}
1536830c1eb4SAndrew Jeffery 
1537830c1eb4SAndrew Jeffery 		return PLDM_SUCCESS;
153848761c62SAndrew Jeffery 	}
153948761c62SAndrew Jeffery 
154048761c62SAndrew Jeffery 	if (event_class_count < *number_event_class_returned) {
154148761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
154248761c62SAndrew Jeffery 	}
154348761c62SAndrew Jeffery 
154448761c62SAndrew Jeffery 	for (i = 0; i < *number_event_class_returned; i++) {
154548761c62SAndrew Jeffery 		pldm_msgbuf_extract(buf, event_class[i]);
154648761c62SAndrew Jeffery 	}
154748761c62SAndrew Jeffery 
1548830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy_consumed(buf);
1549830c1eb4SAndrew Jeffery 	if (rc) {
1550830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1551830c1eb4SAndrew Jeffery 	}
1552830c1eb4SAndrew Jeffery 
1553830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
155448761c62SAndrew Jeffery }
155548761c62SAndrew Jeffery 
155648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
155748761c62SAndrew Jeffery int decode_sensor_event_data(const uint8_t *event_data,
155848761c62SAndrew Jeffery 			     size_t event_data_length, uint16_t *sensor_id,
155948761c62SAndrew Jeffery 			     uint8_t *sensor_event_class_type,
156048761c62SAndrew Jeffery 			     size_t *event_class_data_offset)
156148761c62SAndrew Jeffery {
156248761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
156348761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
156448761c62SAndrew Jeffery 	int rc;
156548761c62SAndrew Jeffery 
156690bbe6c0SAndrew Jeffery 	if (event_data == NULL || sensor_id == NULL ||
156790bbe6c0SAndrew Jeffery 	    sensor_event_class_type == NULL ||
156890bbe6c0SAndrew Jeffery 	    event_class_data_offset == NULL) {
156990bbe6c0SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
157090bbe6c0SAndrew Jeffery 	}
157190bbe6c0SAndrew Jeffery 
1572830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf, PLDM_SENSOR_EVENT_DATA_MIN_LENGTH,
157348761c62SAndrew Jeffery 				    event_data, event_data_length);
157448761c62SAndrew Jeffery 	if (rc) {
1575830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1576830c1eb4SAndrew Jeffery 	}
1577830c1eb4SAndrew Jeffery 
1578830c1eb4SAndrew Jeffery 	if (event_data_length < PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) {
1579830c1eb4SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
158048761c62SAndrew Jeffery 	}
158148761c62SAndrew Jeffery 
158248761c62SAndrew Jeffery 	size_t event_class_data_length =
158348761c62SAndrew Jeffery 		event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES;
158448761c62SAndrew Jeffery 
158548761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, sensor_id);
158648761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, sensor_event_class_type);
158748761c62SAndrew Jeffery 	if (rc) {
1588830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
158948761c62SAndrew Jeffery 	}
159048761c62SAndrew Jeffery 
159148761c62SAndrew Jeffery 	if (*sensor_event_class_type == PLDM_SENSOR_OP_STATE) {
159248761c62SAndrew Jeffery 		if (event_class_data_length !=
159348761c62SAndrew Jeffery 		    PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
159448761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
159548761c62SAndrew Jeffery 		}
159648761c62SAndrew Jeffery 	} else if (*sensor_event_class_type == PLDM_STATE_SENSOR_STATE) {
159748761c62SAndrew Jeffery 		if (event_class_data_length !=
159848761c62SAndrew Jeffery 		    PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
159948761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
160048761c62SAndrew Jeffery 		}
160148761c62SAndrew Jeffery 	} else if (*sensor_event_class_type == PLDM_NUMERIC_SENSOR_STATE) {
160248761c62SAndrew Jeffery 		if (event_class_data_length <
160348761c62SAndrew Jeffery 			    PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
160448761c62SAndrew Jeffery 		    event_class_data_length >
160548761c62SAndrew Jeffery 			    PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
160648761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
160748761c62SAndrew Jeffery 		}
160848761c62SAndrew Jeffery 	} else {
160948761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
161048761c62SAndrew Jeffery 	}
161148761c62SAndrew Jeffery 
161248761c62SAndrew Jeffery 	*event_class_data_offset =
161348761c62SAndrew Jeffery 		sizeof(*sensor_id) + sizeof(*sensor_event_class_type);
161448761c62SAndrew Jeffery 
1615830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
1616830c1eb4SAndrew Jeffery 	if (rc) {
1617830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1618830c1eb4SAndrew Jeffery 	}
1619830c1eb4SAndrew Jeffery 
1620830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
162148761c62SAndrew Jeffery }
162248761c62SAndrew Jeffery 
162348761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
162448761c62SAndrew Jeffery int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length,
162548761c62SAndrew Jeffery 			  uint8_t *present_op_state, uint8_t *previous_op_state)
162648761c62SAndrew Jeffery {
162748761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
162848761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
162948761c62SAndrew Jeffery 	int rc;
163048761c62SAndrew Jeffery 
163190bbe6c0SAndrew Jeffery 	if (sensor_data == NULL || present_op_state == NULL ||
163290bbe6c0SAndrew Jeffery 	    previous_op_state == NULL) {
163348761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
163448761c62SAndrew Jeffery 	}
163548761c62SAndrew Jeffery 
1636830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(
1637830c1eb4SAndrew Jeffery 		buf, PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH, sensor_data,
1638830c1eb4SAndrew Jeffery 		sensor_data_length);
163948761c62SAndrew Jeffery 	if (rc) {
1640830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
164148761c62SAndrew Jeffery 	}
164248761c62SAndrew Jeffery 
164348761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, present_op_state);
164448761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, previous_op_state);
164548761c62SAndrew Jeffery 
1646830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy_consumed(buf);
1647830c1eb4SAndrew Jeffery 	if (rc) {
1648830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1649830c1eb4SAndrew Jeffery 	}
1650830c1eb4SAndrew Jeffery 
1651830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
165248761c62SAndrew Jeffery }
165348761c62SAndrew Jeffery 
165448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
165548761c62SAndrew Jeffery int decode_state_sensor_data(const uint8_t *sensor_data,
165648761c62SAndrew Jeffery 			     size_t sensor_data_length, uint8_t *sensor_offset,
165748761c62SAndrew Jeffery 			     uint8_t *event_state,
165848761c62SAndrew Jeffery 			     uint8_t *previous_event_state)
165948761c62SAndrew Jeffery {
166048761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
166148761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
166248761c62SAndrew Jeffery 	int rc;
166348761c62SAndrew Jeffery 
166490bbe6c0SAndrew Jeffery 	if (sensor_data == NULL || sensor_offset == NULL ||
166590bbe6c0SAndrew Jeffery 	    event_state == NULL || previous_event_state == NULL) {
166648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
166748761c62SAndrew Jeffery 	}
166848761c62SAndrew Jeffery 
1669830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(
167048761c62SAndrew Jeffery 		buf, PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH,
167148761c62SAndrew Jeffery 		sensor_data, sensor_data_length);
167248761c62SAndrew Jeffery 	if (rc) {
1673830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
167448761c62SAndrew Jeffery 	}
167548761c62SAndrew Jeffery 
167648761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, sensor_offset);
167748761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, event_state);
167848761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, previous_event_state);
167948761c62SAndrew Jeffery 
1680830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy_consumed(buf);
1681830c1eb4SAndrew Jeffery 	if (rc) {
1682830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1683830c1eb4SAndrew Jeffery 	}
1684830c1eb4SAndrew Jeffery 
1685830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
168648761c62SAndrew Jeffery }
168748761c62SAndrew Jeffery 
168848761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
168948761c62SAndrew Jeffery int decode_numeric_sensor_data(const uint8_t *sensor_data,
169048761c62SAndrew Jeffery 			       size_t sensor_data_length, uint8_t *event_state,
169148761c62SAndrew Jeffery 			       uint8_t *previous_event_state,
169248761c62SAndrew Jeffery 			       uint8_t *sensor_data_size,
169348761c62SAndrew Jeffery 			       uint32_t *present_reading)
169448761c62SAndrew Jeffery {
169548761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
169648761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
169748761c62SAndrew Jeffery 	int rc;
169848761c62SAndrew Jeffery 
169990bbe6c0SAndrew Jeffery 	if (sensor_data == NULL || sensor_data_size == NULL ||
170090bbe6c0SAndrew Jeffery 	    event_state == NULL || previous_event_state == NULL ||
170190bbe6c0SAndrew Jeffery 	    present_reading == NULL) {
170248761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
170348761c62SAndrew Jeffery 	}
170448761c62SAndrew Jeffery 
170548761c62SAndrew Jeffery 	if (sensor_data_length >
170648761c62SAndrew Jeffery 	    PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
170748761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
170848761c62SAndrew Jeffery 	}
170948761c62SAndrew Jeffery 
1710830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(
171148761c62SAndrew Jeffery 		buf, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH,
171248761c62SAndrew Jeffery 		sensor_data, sensor_data_length);
171348761c62SAndrew Jeffery 	if (rc) {
1714830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
171548761c62SAndrew Jeffery 	}
171648761c62SAndrew Jeffery 
171748761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, event_state);
171848761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, previous_event_state);
171948761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
172048761c62SAndrew Jeffery 	if (rc) {
1721830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
172248761c62SAndrew Jeffery 	}
172348761c62SAndrew Jeffery 
172448761c62SAndrew Jeffery 	/*
172548761c62SAndrew Jeffery 	 * The implementation below is bonkers, but it's because the function
172648761c62SAndrew Jeffery 	 * prototype is bonkers. The `present_reading` argument should have been
172748761c62SAndrew Jeffery 	 * a tagged union.
172848761c62SAndrew Jeffery 	 */
172948761c62SAndrew Jeffery 	switch (*sensor_data_size) {
173048761c62SAndrew Jeffery 	case PLDM_SENSOR_DATA_SIZE_UINT8: {
173148761c62SAndrew Jeffery 		uint8_t val;
173248761c62SAndrew Jeffery 		if (!pldm_msgbuf_extract(buf, val)) {
173348761c62SAndrew Jeffery 			*present_reading = (uint32_t)val;
173448761c62SAndrew Jeffery 		}
173548761c62SAndrew Jeffery 		break;
173648761c62SAndrew Jeffery 	}
173748761c62SAndrew Jeffery 	case PLDM_SENSOR_DATA_SIZE_SINT8: {
173848761c62SAndrew Jeffery 		int8_t val;
173948761c62SAndrew Jeffery 		if (!pldm_msgbuf_extract(buf, val)) {
174048761c62SAndrew Jeffery 			*present_reading = (uint32_t)(int32_t)val;
174148761c62SAndrew Jeffery 		}
174248761c62SAndrew Jeffery 		break;
174348761c62SAndrew Jeffery 	}
174448761c62SAndrew Jeffery 	case PLDM_SENSOR_DATA_SIZE_UINT16: {
174548761c62SAndrew Jeffery 		uint16_t val;
174648761c62SAndrew Jeffery 		if (!pldm_msgbuf_extract(buf, val)) {
174748761c62SAndrew Jeffery 			*present_reading = (uint32_t)val;
174848761c62SAndrew Jeffery 		}
174948761c62SAndrew Jeffery 		break;
175048761c62SAndrew Jeffery 	}
175148761c62SAndrew Jeffery 	case PLDM_SENSOR_DATA_SIZE_SINT16: {
175248761c62SAndrew Jeffery 		int16_t val;
175348761c62SAndrew Jeffery 		if (!pldm_msgbuf_extract(buf, val)) {
175448761c62SAndrew Jeffery 			*present_reading = (uint32_t)(int32_t)val;
175548761c62SAndrew Jeffery 		}
175648761c62SAndrew Jeffery 		break;
175748761c62SAndrew Jeffery 	}
175848761c62SAndrew Jeffery 	case PLDM_SENSOR_DATA_SIZE_UINT32: {
175948761c62SAndrew Jeffery 		uint32_t val;
176048761c62SAndrew Jeffery 		if (!pldm_msgbuf_extract(buf, val)) {
176148761c62SAndrew Jeffery 			*present_reading = (uint32_t)val;
176248761c62SAndrew Jeffery 		}
176348761c62SAndrew Jeffery 		break;
176448761c62SAndrew Jeffery 	}
176548761c62SAndrew Jeffery 	case PLDM_SENSOR_DATA_SIZE_SINT32: {
176648761c62SAndrew Jeffery 		int32_t val;
176748761c62SAndrew Jeffery 		if (!pldm_msgbuf_extract(buf, val)) {
176848761c62SAndrew Jeffery 			*present_reading = (uint32_t)val;
176948761c62SAndrew Jeffery 		}
177048761c62SAndrew Jeffery 		break;
177148761c62SAndrew Jeffery 	}
177248761c62SAndrew Jeffery 	default:
177348761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
177448761c62SAndrew Jeffery 	}
177548761c62SAndrew Jeffery 
1776830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy_consumed(buf);
1777830c1eb4SAndrew Jeffery 	if (rc) {
1778830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1779830c1eb4SAndrew Jeffery 	}
1780830c1eb4SAndrew Jeffery 
1781830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
178248761c62SAndrew Jeffery }
178348761c62SAndrew Jeffery 
178448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
178548761c62SAndrew Jeffery int decode_numeric_sensor_pdr_data(
178648761c62SAndrew Jeffery 	const void *pdr_data, size_t pdr_data_length,
178748761c62SAndrew Jeffery 	struct pldm_numeric_sensor_value_pdr *pdr_value)
178848761c62SAndrew Jeffery {
178948761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
179048761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
179148761c62SAndrew Jeffery 	int rc;
179248761c62SAndrew Jeffery 
1793830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
179448761c62SAndrew Jeffery 				    pdr_data, pdr_data_length);
179548761c62SAndrew Jeffery 	if (rc) {
1796830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
179748761c62SAndrew Jeffery 	}
179848761c62SAndrew Jeffery 
1799329176a8SAndrew Jeffery 	rc = pldm_msgbuf_extract_value_pdr_hdr(
1800329176a8SAndrew Jeffery 		buf, &pdr_value->hdr, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
180148761c62SAndrew Jeffery 		pdr_data_length);
180248761c62SAndrew Jeffery 	if (rc) {
1803329176a8SAndrew Jeffery 		return pldm_xlate_errno(rc);
180448761c62SAndrew Jeffery 	}
180548761c62SAndrew Jeffery 
180648761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
180748761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->sensor_id);
180848761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->entity_type);
180948761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->entity_instance_num);
181048761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->container_id);
181148761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->sensor_init);
181248761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->sensor_auxiliary_names_pdr);
181348761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->base_unit);
181448761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->unit_modifier);
181548761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->rate_unit);
181648761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle);
181748761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->aux_unit);
181848761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier);
181948761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit);
182048761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->rel);
182148761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle);
182248761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->is_linear);
182348761c62SAndrew Jeffery 
182448761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract(buf, pdr_value->sensor_data_size);
182548761c62SAndrew Jeffery 	if (rc) {
1826830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
182748761c62SAndrew Jeffery 	}
182848761c62SAndrew Jeffery 	if (pdr_value->sensor_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
182948761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
183048761c62SAndrew Jeffery 	}
183148761c62SAndrew Jeffery 
183248761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->resolution);
183348761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->offset);
183448761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->accuracy);
183548761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->plus_tolerance);
183648761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->minus_tolerance);
183748761c62SAndrew Jeffery 	pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
183848761c62SAndrew Jeffery 					&pdr_value->hysteresis);
183948761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->supported_thresholds.byte);
184048761c62SAndrew Jeffery 	pldm_msgbuf_extract(
184148761c62SAndrew Jeffery 		buf, pdr_value->threshold_and_hysteresis_volatility.byte);
184248761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->state_transition_interval);
184348761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->update_interval);
184448761c62SAndrew Jeffery 	pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
184548761c62SAndrew Jeffery 					&pdr_value->max_readable);
184648761c62SAndrew Jeffery 	pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
184748761c62SAndrew Jeffery 					&pdr_value->min_readable);
184848761c62SAndrew Jeffery 
184948761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
185048761c62SAndrew Jeffery 	if (rc) {
1851830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
185248761c62SAndrew Jeffery 	}
185348761c62SAndrew Jeffery 	if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
185448761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
185548761c62SAndrew Jeffery 	}
185648761c62SAndrew Jeffery 
185748761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
185848761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
185948761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->nominal_value);
186048761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
186148761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->normal_max);
186248761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
186348761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->normal_min);
186448761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
186548761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->warning_high);
186648761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
186748761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->warning_low);
186848761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
186948761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->critical_high);
187048761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
187148761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->critical_low);
187248761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
187348761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->fatal_high);
187448761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
187548761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->fatal_low);
187648761c62SAndrew Jeffery 
1877830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
1878830c1eb4SAndrew Jeffery 	if (rc) {
1879830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1880830c1eb4SAndrew Jeffery 	}
1881830c1eb4SAndrew Jeffery 
1882830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
188348761c62SAndrew Jeffery }
188448761c62SAndrew Jeffery 
188548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
188648761c62SAndrew Jeffery int encode_get_numeric_effecter_value_req(uint8_t instance_id,
188748761c62SAndrew Jeffery 					  uint16_t effecter_id,
188848761c62SAndrew Jeffery 					  struct pldm_msg *msg)
188948761c62SAndrew Jeffery {
189048761c62SAndrew Jeffery 	if (msg == NULL) {
189148761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
189248761c62SAndrew Jeffery 	}
189348761c62SAndrew Jeffery 
189448761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
189548761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
189648761c62SAndrew Jeffery 	header.instance = instance_id;
189748761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
189848761c62SAndrew Jeffery 	header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
189948761c62SAndrew Jeffery 
190048761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
190148761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
190248761c62SAndrew Jeffery 		return rc;
190348761c62SAndrew Jeffery 	}
190448761c62SAndrew Jeffery 
190548761c62SAndrew Jeffery 	struct pldm_get_numeric_effecter_value_req *request =
190648761c62SAndrew Jeffery 		(struct pldm_get_numeric_effecter_value_req *)msg->payload;
190748761c62SAndrew Jeffery 	request->effecter_id = htole16(effecter_id);
190848761c62SAndrew Jeffery 
190948761c62SAndrew Jeffery 	return PLDM_SUCCESS;
191048761c62SAndrew Jeffery }
191148761c62SAndrew Jeffery 
191248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
191348761c62SAndrew Jeffery int encode_get_numeric_effecter_value_resp(
191448761c62SAndrew Jeffery 	uint8_t instance_id, uint8_t completion_code,
191548761c62SAndrew Jeffery 	uint8_t effecter_data_size, uint8_t effecter_oper_state,
191648761c62SAndrew Jeffery 	const uint8_t *pending_value, const uint8_t *present_value,
191748761c62SAndrew Jeffery 	struct pldm_msg *msg, size_t payload_length)
191848761c62SAndrew Jeffery {
191948761c62SAndrew Jeffery 	if (msg == NULL || pending_value == NULL || present_value == NULL) {
192048761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
192148761c62SAndrew Jeffery 	}
192248761c62SAndrew Jeffery 
192348761c62SAndrew Jeffery 	if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
192448761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
192548761c62SAndrew Jeffery 	}
192648761c62SAndrew Jeffery 
192748761c62SAndrew Jeffery 	if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
192848761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
192948761c62SAndrew Jeffery 	}
193048761c62SAndrew Jeffery 
193148761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
193248761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
193348761c62SAndrew Jeffery 	header.instance = instance_id;
193448761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
193548761c62SAndrew Jeffery 	header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
193648761c62SAndrew Jeffery 
193748761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
193848761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
193948761c62SAndrew Jeffery 		return rc;
194048761c62SAndrew Jeffery 	}
194148761c62SAndrew Jeffery 
194248761c62SAndrew Jeffery 	struct pldm_get_numeric_effecter_value_resp *response =
194348761c62SAndrew Jeffery 		(struct pldm_get_numeric_effecter_value_resp *)msg->payload;
194448761c62SAndrew Jeffery 
194548761c62SAndrew Jeffery 	response->completion_code = completion_code;
194648761c62SAndrew Jeffery 	response->effecter_data_size = effecter_data_size;
194748761c62SAndrew Jeffery 	response->effecter_oper_state = effecter_oper_state;
194848761c62SAndrew Jeffery 
194948761c62SAndrew Jeffery 	if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
195048761c62SAndrew Jeffery 	    effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
195148761c62SAndrew Jeffery 		if (payload_length !=
195248761c62SAndrew Jeffery 		    PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
195348761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
195448761c62SAndrew Jeffery 		}
195548761c62SAndrew Jeffery 		response->pending_and_present_values[0] = *pending_value;
195648761c62SAndrew Jeffery 		response->pending_and_present_values[1] = *present_value;
195748761c62SAndrew Jeffery 
195848761c62SAndrew Jeffery 	} else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
195948761c62SAndrew Jeffery 		   effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
196048761c62SAndrew Jeffery 		if (payload_length !=
196148761c62SAndrew Jeffery 		    PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
196248761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
196348761c62SAndrew Jeffery 		}
196448761c62SAndrew Jeffery 		uint16_t val_pending = *(uint16_t *)pending_value;
196548761c62SAndrew Jeffery 		val_pending = htole16(val_pending);
196648761c62SAndrew Jeffery 		memcpy(response->pending_and_present_values, &val_pending,
196748761c62SAndrew Jeffery 		       sizeof(uint16_t));
196848761c62SAndrew Jeffery 		uint16_t val_present = *(uint16_t *)present_value;
196948761c62SAndrew Jeffery 		val_present = htole16(val_present);
197048761c62SAndrew Jeffery 		memcpy((response->pending_and_present_values +
197148761c62SAndrew Jeffery 			sizeof(uint16_t)),
197248761c62SAndrew Jeffery 		       &val_present, sizeof(uint16_t));
197348761c62SAndrew Jeffery 
197448761c62SAndrew Jeffery 	} else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
197548761c62SAndrew Jeffery 		   effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
197648761c62SAndrew Jeffery 		if (payload_length !=
197748761c62SAndrew Jeffery 		    PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
197848761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
197948761c62SAndrew Jeffery 		}
198048761c62SAndrew Jeffery 		uint32_t val_pending = *(uint32_t *)pending_value;
198148761c62SAndrew Jeffery 		val_pending = htole32(val_pending);
198248761c62SAndrew Jeffery 		memcpy(response->pending_and_present_values, &val_pending,
198348761c62SAndrew Jeffery 		       sizeof(uint32_t));
198448761c62SAndrew Jeffery 		uint32_t val_present = *(uint32_t *)present_value;
198548761c62SAndrew Jeffery 		val_present = htole32(val_present);
198648761c62SAndrew Jeffery 		memcpy((response->pending_and_present_values +
198748761c62SAndrew Jeffery 			sizeof(uint32_t)),
198848761c62SAndrew Jeffery 		       &val_present, sizeof(uint32_t));
198948761c62SAndrew Jeffery 	}
199048761c62SAndrew Jeffery 	return PLDM_SUCCESS;
199148761c62SAndrew Jeffery }
199248761c62SAndrew Jeffery 
199348761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
199448761c62SAndrew Jeffery int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg,
199548761c62SAndrew Jeffery 					  size_t payload_length,
199648761c62SAndrew Jeffery 					  uint16_t *effecter_id)
199748761c62SAndrew Jeffery {
199848761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
199948761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
200048761c62SAndrew Jeffery 	int rc;
200148761c62SAndrew Jeffery 
200248761c62SAndrew Jeffery 	if (msg == NULL || effecter_id == NULL) {
200348761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
200448761c62SAndrew Jeffery 	}
200548761c62SAndrew Jeffery 
2006830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf,
2007830c1eb4SAndrew Jeffery 				    PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES,
200848761c62SAndrew Jeffery 				    msg->payload, payload_length);
200948761c62SAndrew Jeffery 	if (rc) {
2010830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
201148761c62SAndrew Jeffery 	}
201248761c62SAndrew Jeffery 
201348761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, effecter_id);
201448761c62SAndrew Jeffery 
2015830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy_consumed(buf);
2016830c1eb4SAndrew Jeffery 	if (rc) {
2017830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
2018830c1eb4SAndrew Jeffery 	}
2019830c1eb4SAndrew Jeffery 
2020830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
202148761c62SAndrew Jeffery }
202248761c62SAndrew Jeffery 
202348761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
202448761c62SAndrew Jeffery int decode_get_numeric_effecter_value_resp(const struct pldm_msg *msg,
202548761c62SAndrew Jeffery 					   size_t payload_length,
202648761c62SAndrew Jeffery 					   uint8_t *completion_code,
202748761c62SAndrew Jeffery 					   uint8_t *effecter_data_size,
202848761c62SAndrew Jeffery 					   uint8_t *effecter_oper_state,
202948761c62SAndrew Jeffery 					   uint8_t *pending_value,
203048761c62SAndrew Jeffery 					   uint8_t *present_value)
203148761c62SAndrew Jeffery {
203248761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
203348761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
203448761c62SAndrew Jeffery 	int rc;
203548761c62SAndrew Jeffery 
203648761c62SAndrew Jeffery 	if (msg == NULL || effecter_data_size == NULL ||
203748761c62SAndrew Jeffery 	    effecter_oper_state == NULL || pending_value == NULL ||
203848761c62SAndrew Jeffery 	    present_value == NULL) {
203948761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
204048761c62SAndrew Jeffery 	}
204148761c62SAndrew Jeffery 
2042830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(
2043830c1eb4SAndrew Jeffery 		buf, PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES,
204448761c62SAndrew Jeffery 		msg->payload, payload_length);
204548761c62SAndrew Jeffery 	if (rc) {
2046830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
204748761c62SAndrew Jeffery 	}
204848761c62SAndrew Jeffery 
204948761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, completion_code);
205048761c62SAndrew Jeffery 	if (rc) {
2051830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
205248761c62SAndrew Jeffery 	}
205348761c62SAndrew Jeffery 
205448761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
205548761c62SAndrew Jeffery 		return PLDM_SUCCESS;
205648761c62SAndrew Jeffery 	}
205748761c62SAndrew Jeffery 
205848761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
205948761c62SAndrew Jeffery 	if (rc) {
2060830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
206148761c62SAndrew Jeffery 	}
206248761c62SAndrew Jeffery 
206348761c62SAndrew Jeffery 	if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
206448761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
206548761c62SAndrew Jeffery 	}
206648761c62SAndrew Jeffery 
206748761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, effecter_oper_state);
206848761c62SAndrew Jeffery 	if (rc) {
2069830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
207048761c62SAndrew Jeffery 	}
207148761c62SAndrew Jeffery 
207248761c62SAndrew Jeffery 	if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
207348761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
207448761c62SAndrew Jeffery 	}
207548761c62SAndrew Jeffery 
207648761c62SAndrew Jeffery 	pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
207748761c62SAndrew Jeffery 					   pending_value);
207848761c62SAndrew Jeffery 	pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
207948761c62SAndrew Jeffery 					   present_value);
208048761c62SAndrew Jeffery 
2081830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy_consumed(buf);
2082830c1eb4SAndrew Jeffery 	if (rc) {
2083830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
2084830c1eb4SAndrew Jeffery 	}
2085830c1eb4SAndrew Jeffery 
2086830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
208748761c62SAndrew Jeffery }
208848761c62SAndrew Jeffery 
208948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
209048761c62SAndrew Jeffery int encode_pldm_pdr_repository_chg_event_data(
209148761c62SAndrew Jeffery 	uint8_t event_data_format, uint8_t number_of_change_records,
209248761c62SAndrew Jeffery 	const uint8_t *event_data_operations,
209348761c62SAndrew Jeffery 	const uint8_t *numbers_of_change_entries,
209448761c62SAndrew Jeffery 	const uint32_t *const *change_entries,
209548761c62SAndrew Jeffery 	struct pldm_pdr_repository_chg_event_data *event_data,
209648761c62SAndrew Jeffery 	size_t *actual_change_records_size, size_t max_change_records_size)
209748761c62SAndrew Jeffery {
209848761c62SAndrew Jeffery 	if (event_data_operations == NULL ||
209948761c62SAndrew Jeffery 	    numbers_of_change_entries == NULL || change_entries == NULL) {
210048761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
210148761c62SAndrew Jeffery 	}
210248761c62SAndrew Jeffery 
210348761c62SAndrew Jeffery 	size_t expected_size =
210448761c62SAndrew Jeffery 		sizeof(event_data_format) + sizeof(number_of_change_records);
210548761c62SAndrew Jeffery 
210648761c62SAndrew Jeffery 	expected_size +=
210748761c62SAndrew Jeffery 		sizeof(*event_data_operations) * number_of_change_records;
210848761c62SAndrew Jeffery 	expected_size +=
210948761c62SAndrew Jeffery 		sizeof(*numbers_of_change_entries) * number_of_change_records;
211048761c62SAndrew Jeffery 
211148761c62SAndrew Jeffery 	for (uint8_t i = 0; i < number_of_change_records; ++i) {
211248761c62SAndrew Jeffery 		expected_size += sizeof(*change_entries[0]) *
211348761c62SAndrew Jeffery 				 numbers_of_change_entries[i];
211448761c62SAndrew Jeffery 	}
211548761c62SAndrew Jeffery 
211648761c62SAndrew Jeffery 	*actual_change_records_size = expected_size;
211748761c62SAndrew Jeffery 
211848761c62SAndrew Jeffery 	if (event_data == NULL) {
211948761c62SAndrew Jeffery 		return PLDM_SUCCESS;
212048761c62SAndrew Jeffery 	}
212148761c62SAndrew Jeffery 
212248761c62SAndrew Jeffery 	if (max_change_records_size < expected_size) {
212348761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
212448761c62SAndrew Jeffery 	}
212548761c62SAndrew Jeffery 
212648761c62SAndrew Jeffery 	event_data->event_data_format = event_data_format;
212748761c62SAndrew Jeffery 	event_data->number_of_change_records = number_of_change_records;
212848761c62SAndrew Jeffery 
212948761c62SAndrew Jeffery 	struct pldm_pdr_repository_change_record_data *record_data =
213048761c62SAndrew Jeffery 		(struct pldm_pdr_repository_change_record_data *)
213148761c62SAndrew Jeffery 			event_data->change_records;
213248761c62SAndrew Jeffery 
213348761c62SAndrew Jeffery 	for (uint8_t i = 0; i < number_of_change_records; ++i) {
213448761c62SAndrew Jeffery 		record_data->event_data_operation = event_data_operations[i];
213548761c62SAndrew Jeffery 		record_data->number_of_change_entries =
213648761c62SAndrew Jeffery 			numbers_of_change_entries[i];
213748761c62SAndrew Jeffery 
213848761c62SAndrew Jeffery 		for (uint8_t j = 0; j < record_data->number_of_change_entries;
213948761c62SAndrew Jeffery 		     ++j) {
214048761c62SAndrew Jeffery 			record_data->change_entry[j] =
214148761c62SAndrew Jeffery 				htole32(change_entries[i][j]);
214248761c62SAndrew Jeffery 		}
214348761c62SAndrew Jeffery 
214448761c62SAndrew Jeffery 		record_data =
214548761c62SAndrew Jeffery 			(struct pldm_pdr_repository_change_record_data
214648761c62SAndrew Jeffery 				 *)(record_data->change_entry +
214748761c62SAndrew Jeffery 				    record_data->number_of_change_entries);
214848761c62SAndrew Jeffery 	}
214948761c62SAndrew Jeffery 
215048761c62SAndrew Jeffery 	return PLDM_SUCCESS;
215148761c62SAndrew Jeffery }
215248761c62SAndrew Jeffery 
215348761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
215448761c62SAndrew Jeffery int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data,
215548761c62SAndrew Jeffery 					      size_t event_data_size,
215648761c62SAndrew Jeffery 					      uint8_t *event_data_format,
215748761c62SAndrew Jeffery 					      uint8_t *number_of_change_records,
215848761c62SAndrew Jeffery 					      size_t *change_record_data_offset)
215948761c62SAndrew Jeffery {
216048761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
216148761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
216248761c62SAndrew Jeffery 	int rc;
216348761c62SAndrew Jeffery 
216490bbe6c0SAndrew Jeffery 	if (event_data == NULL || event_data_format == NULL ||
216590bbe6c0SAndrew Jeffery 	    number_of_change_records == NULL ||
216648761c62SAndrew Jeffery 	    change_record_data_offset == NULL) {
216748761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
216848761c62SAndrew Jeffery 	}
216948761c62SAndrew Jeffery 
2170830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf,
2171830c1eb4SAndrew Jeffery 				    PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH,
217248761c62SAndrew Jeffery 				    event_data, event_data_size);
217348761c62SAndrew Jeffery 	if (rc) {
2174830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
217548761c62SAndrew Jeffery 	}
217648761c62SAndrew Jeffery 
217748761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, event_data_format);
217848761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, number_of_change_records);
217948761c62SAndrew Jeffery 
218048761c62SAndrew Jeffery 	*change_record_data_offset =
218148761c62SAndrew Jeffery 		sizeof(*event_data_format) + sizeof(*number_of_change_records);
218248761c62SAndrew Jeffery 
2183830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
2184830c1eb4SAndrew Jeffery 	if (rc) {
2185830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
2186830c1eb4SAndrew Jeffery 	}
2187830c1eb4SAndrew Jeffery 
2188830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
218948761c62SAndrew Jeffery }
219048761c62SAndrew Jeffery 
2191f874b383SThu Nguyen LIBPLDM_ABI_STABLE
21927739d123SThu Nguyen int decode_pldm_message_poll_event_data(
21937739d123SThu Nguyen 	const void *event_data, size_t event_data_length,
21947739d123SThu Nguyen 	struct pldm_message_poll_event *poll_event)
219548761c62SAndrew Jeffery {
219648761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
219748761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
219848761c62SAndrew Jeffery 	int rc;
219948761c62SAndrew Jeffery 
220090bbe6c0SAndrew Jeffery 	if (!event_data || !poll_event) {
22017739d123SThu Nguyen 		return -EINVAL;
220248761c62SAndrew Jeffery 	}
220348761c62SAndrew Jeffery 
22047739d123SThu Nguyen 	rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
220548761c62SAndrew Jeffery 				    event_data_length);
220648761c62SAndrew Jeffery 	if (rc) {
220748761c62SAndrew Jeffery 		return rc;
220848761c62SAndrew Jeffery 	}
220948761c62SAndrew Jeffery 
22107739d123SThu Nguyen 	pldm_msgbuf_extract(buf, poll_event->format_version);
22117739d123SThu Nguyen 	rc = pldm_msgbuf_extract(buf, poll_event->event_id);
221248761c62SAndrew Jeffery 	if (rc) {
221348761c62SAndrew Jeffery 		return rc;
221448761c62SAndrew Jeffery 	}
221548761c62SAndrew Jeffery 
22167739d123SThu Nguyen 	if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) {
22177739d123SThu Nguyen 		return -EPROTO;
221848761c62SAndrew Jeffery 	}
221948761c62SAndrew Jeffery 
22207739d123SThu Nguyen 	pldm_msgbuf_extract(buf, poll_event->data_transfer_handle);
222148761c62SAndrew Jeffery 
222248761c62SAndrew Jeffery 	return pldm_msgbuf_destroy_consumed(buf);
222348761c62SAndrew Jeffery }
222448761c62SAndrew Jeffery 
222548761c62SAndrew Jeffery LIBPLDM_ABI_TESTING
22267739d123SThu Nguyen int encode_pldm_message_poll_event_data(
22277739d123SThu Nguyen 	const struct pldm_message_poll_event *poll_event, void *event_data,
222848761c62SAndrew Jeffery 	size_t event_data_length)
222948761c62SAndrew Jeffery {
223048761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
223148761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
223248761c62SAndrew Jeffery 	int rc;
223348761c62SAndrew Jeffery 
223490bbe6c0SAndrew Jeffery 	if (poll_event == NULL || event_data == NULL) {
223590bbe6c0SAndrew Jeffery 		return -EINVAL;
223690bbe6c0SAndrew Jeffery 	}
223790bbe6c0SAndrew Jeffery 
22387739d123SThu Nguyen 	if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) {
22397739d123SThu Nguyen 		return -EPROTO;
224048761c62SAndrew Jeffery 	}
224148761c62SAndrew Jeffery 
22427739d123SThu Nguyen 	rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
224348761c62SAndrew Jeffery 				    event_data_length);
224448761c62SAndrew Jeffery 	if (rc) {
224548761c62SAndrew Jeffery 		return rc;
224648761c62SAndrew Jeffery 	}
22477739d123SThu Nguyen 	pldm_msgbuf_insert(buf, poll_event->format_version);
22487739d123SThu Nguyen 	pldm_msgbuf_insert(buf, poll_event->event_id);
22497739d123SThu Nguyen 	pldm_msgbuf_insert(buf, poll_event->data_transfer_handle);
225048761c62SAndrew Jeffery 
22517739d123SThu Nguyen 	return pldm_msgbuf_destroy_consumed(buf);
225248761c62SAndrew Jeffery }
225348761c62SAndrew Jeffery 
225448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
225548761c62SAndrew Jeffery int decode_pldm_pdr_repository_change_record_data(
225648761c62SAndrew Jeffery 	const uint8_t *change_record_data, size_t change_record_data_size,
225748761c62SAndrew Jeffery 	uint8_t *event_data_operation, uint8_t *number_of_change_entries,
225848761c62SAndrew Jeffery 	size_t *change_entry_data_offset)
225948761c62SAndrew Jeffery {
226048761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
226148761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
226248761c62SAndrew Jeffery 	int rc;
226348761c62SAndrew Jeffery 
226490bbe6c0SAndrew Jeffery 	if (change_record_data == NULL || event_data_operation == NULL ||
226590bbe6c0SAndrew Jeffery 	    number_of_change_entries == NULL ||
226648761c62SAndrew Jeffery 	    change_entry_data_offset == NULL) {
226748761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
226848761c62SAndrew Jeffery 	}
226948761c62SAndrew Jeffery 
2270830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(
2271830c1eb4SAndrew Jeffery 		buf, PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH,
227248761c62SAndrew Jeffery 		change_record_data, change_record_data_size);
227348761c62SAndrew Jeffery 	if (rc) {
2274830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
227548761c62SAndrew Jeffery 	}
227648761c62SAndrew Jeffery 
227748761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, event_data_operation);
227848761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, number_of_change_entries);
227948761c62SAndrew Jeffery 
228048761c62SAndrew Jeffery 	*change_entry_data_offset = sizeof(*event_data_operation) +
228148761c62SAndrew Jeffery 				    sizeof(*number_of_change_entries);
228248761c62SAndrew Jeffery 
2283830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
2284830c1eb4SAndrew Jeffery 	if (rc) {
2285830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
2286830c1eb4SAndrew Jeffery 	}
2287830c1eb4SAndrew Jeffery 
2288830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
228948761c62SAndrew Jeffery }
229048761c62SAndrew Jeffery 
229148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
229248761c62SAndrew Jeffery int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id,
229348761c62SAndrew Jeffery 				  uint8_t rearm_event_state,
229448761c62SAndrew Jeffery 				  struct pldm_msg *msg)
229548761c62SAndrew Jeffery {
229648761c62SAndrew Jeffery 	if (msg == NULL) {
229748761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
229848761c62SAndrew Jeffery 	}
229948761c62SAndrew Jeffery 
230048761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
230148761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
230248761c62SAndrew Jeffery 	header.instance = instance_id;
230348761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
230448761c62SAndrew Jeffery 	header.command = PLDM_GET_SENSOR_READING;
230548761c62SAndrew Jeffery 
230648761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
230748761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
230848761c62SAndrew Jeffery 		return rc;
230948761c62SAndrew Jeffery 	}
231048761c62SAndrew Jeffery 
231148761c62SAndrew Jeffery 	struct pldm_get_sensor_reading_req *request =
231248761c62SAndrew Jeffery 		(struct pldm_get_sensor_reading_req *)msg->payload;
231348761c62SAndrew Jeffery 
231448761c62SAndrew Jeffery 	request->sensor_id = htole16(sensor_id);
231548761c62SAndrew Jeffery 	request->rearm_event_state = rearm_event_state;
231648761c62SAndrew Jeffery 
231748761c62SAndrew Jeffery 	return PLDM_SUCCESS;
231848761c62SAndrew Jeffery }
231948761c62SAndrew Jeffery 
232048761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
232148761c62SAndrew Jeffery int decode_get_sensor_reading_resp(
232248761c62SAndrew Jeffery 	const struct pldm_msg *msg, size_t payload_length,
232348761c62SAndrew Jeffery 	uint8_t *completion_code, uint8_t *sensor_data_size,
232448761c62SAndrew Jeffery 	uint8_t *sensor_operational_state, uint8_t *sensor_event_message_enable,
232548761c62SAndrew Jeffery 	uint8_t *present_state, uint8_t *previous_state, uint8_t *event_state,
232648761c62SAndrew Jeffery 	uint8_t *present_reading)
232748761c62SAndrew Jeffery {
232848761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
232948761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
233048761c62SAndrew Jeffery 	int rc;
233148761c62SAndrew Jeffery 
233248761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL ||
233348761c62SAndrew Jeffery 	    sensor_data_size == NULL || sensor_operational_state == NULL ||
233448761c62SAndrew Jeffery 	    sensor_event_message_enable == NULL || present_state == NULL ||
233548761c62SAndrew Jeffery 	    previous_state == NULL || event_state == NULL ||
233648761c62SAndrew Jeffery 	    present_reading == NULL) {
233748761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
233848761c62SAndrew Jeffery 	}
233948761c62SAndrew Jeffery 
2340830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_MIN_RESP_BYTES,
234148761c62SAndrew Jeffery 				    msg->payload, payload_length);
234248761c62SAndrew Jeffery 	if (rc) {
2343830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
234448761c62SAndrew Jeffery 	}
234548761c62SAndrew Jeffery 
234648761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, completion_code);
234748761c62SAndrew Jeffery 	if (rc) {
2348830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
234948761c62SAndrew Jeffery 	}
235048761c62SAndrew Jeffery 
235148761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
235248761c62SAndrew Jeffery 		return PLDM_SUCCESS;
235348761c62SAndrew Jeffery 	}
235448761c62SAndrew Jeffery 
235548761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
235648761c62SAndrew Jeffery 	if (rc) {
2357830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
235848761c62SAndrew Jeffery 	}
235948761c62SAndrew Jeffery 
236048761c62SAndrew Jeffery 	if (*sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) {
236148761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
236248761c62SAndrew Jeffery 	}
236348761c62SAndrew Jeffery 
236448761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, sensor_operational_state);
236548761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, sensor_event_message_enable);
236648761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, present_state);
236748761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, previous_state);
236848761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, event_state);
236948761c62SAndrew Jeffery 
237048761c62SAndrew Jeffery 	pldm_msgbuf_extract_sensor_value(buf, *sensor_data_size,
237148761c62SAndrew Jeffery 					 present_reading);
237248761c62SAndrew Jeffery 
2373830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy_consumed(buf);
2374830c1eb4SAndrew Jeffery 	if (rc) {
2375830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
2376830c1eb4SAndrew Jeffery 	}
2377830c1eb4SAndrew Jeffery 
2378830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
237948761c62SAndrew Jeffery }
238048761c62SAndrew Jeffery 
238148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
238248761c62SAndrew Jeffery int encode_get_sensor_reading_resp(uint8_t instance_id, uint8_t completion_code,
238348761c62SAndrew Jeffery 				   uint8_t sensor_data_size,
238448761c62SAndrew Jeffery 				   uint8_t sensor_operational_state,
238548761c62SAndrew Jeffery 				   uint8_t sensor_event_message_enable,
238648761c62SAndrew Jeffery 				   uint8_t present_state,
238748761c62SAndrew Jeffery 				   uint8_t previous_state, uint8_t event_state,
238848761c62SAndrew Jeffery 				   const uint8_t *present_reading,
238948761c62SAndrew Jeffery 				   struct pldm_msg *msg, size_t payload_length)
239048761c62SAndrew Jeffery {
239148761c62SAndrew Jeffery 	if (msg == NULL || present_reading == NULL) {
239248761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
239348761c62SAndrew Jeffery 	}
239448761c62SAndrew Jeffery 
239548761c62SAndrew Jeffery 	if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
239648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
239748761c62SAndrew Jeffery 	}
239848761c62SAndrew Jeffery 
239948761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
240048761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
240148761c62SAndrew Jeffery 	header.instance = instance_id;
240248761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
240348761c62SAndrew Jeffery 	header.command = PLDM_GET_SENSOR_READING;
240448761c62SAndrew Jeffery 
240548761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
240648761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
240748761c62SAndrew Jeffery 		return rc;
240848761c62SAndrew Jeffery 	}
240948761c62SAndrew Jeffery 
241048761c62SAndrew Jeffery 	struct pldm_get_sensor_reading_resp *response =
241148761c62SAndrew Jeffery 		(struct pldm_get_sensor_reading_resp *)msg->payload;
241248761c62SAndrew Jeffery 
241348761c62SAndrew Jeffery 	response->completion_code = completion_code;
241448761c62SAndrew Jeffery 	response->sensor_data_size = sensor_data_size;
241548761c62SAndrew Jeffery 	response->sensor_operational_state = sensor_operational_state;
241648761c62SAndrew Jeffery 	response->sensor_event_message_enable = sensor_event_message_enable;
241748761c62SAndrew Jeffery 	response->present_state = present_state;
241848761c62SAndrew Jeffery 	response->previous_state = previous_state;
241948761c62SAndrew Jeffery 	response->event_state = event_state;
242048761c62SAndrew Jeffery 
242148761c62SAndrew Jeffery 	if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
242248761c62SAndrew Jeffery 	    sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
242348761c62SAndrew Jeffery 		if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
242448761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
242548761c62SAndrew Jeffery 		}
242648761c62SAndrew Jeffery 		response->present_reading[0] = *present_reading;
242748761c62SAndrew Jeffery 
242848761c62SAndrew Jeffery 	} else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
242948761c62SAndrew Jeffery 		   sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
243048761c62SAndrew Jeffery 		if (payload_length !=
243148761c62SAndrew Jeffery 		    PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
243248761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
243348761c62SAndrew Jeffery 		}
243448761c62SAndrew Jeffery 		uint16_t val = *(uint16_t *)present_reading;
243548761c62SAndrew Jeffery 		val = htole16(val);
243648761c62SAndrew Jeffery 		memcpy(response->present_reading, &val, 2);
243748761c62SAndrew Jeffery 
243848761c62SAndrew Jeffery 	} else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
243948761c62SAndrew Jeffery 		   sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
244048761c62SAndrew Jeffery 		if (payload_length !=
244148761c62SAndrew Jeffery 		    PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
244248761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
244348761c62SAndrew Jeffery 		}
244448761c62SAndrew Jeffery 		uint32_t val = *(uint32_t *)present_reading;
244548761c62SAndrew Jeffery 		val = htole32(val);
244648761c62SAndrew Jeffery 		memcpy(response->present_reading, &val, 4);
244748761c62SAndrew Jeffery 	}
244848761c62SAndrew Jeffery 
244948761c62SAndrew Jeffery 	return PLDM_SUCCESS;
245048761c62SAndrew Jeffery }
245148761c62SAndrew Jeffery 
245248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
245348761c62SAndrew Jeffery int decode_get_sensor_reading_req(const struct pldm_msg *msg,
245448761c62SAndrew Jeffery 				  size_t payload_length, uint16_t *sensor_id,
245548761c62SAndrew Jeffery 				  uint8_t *rearm_event_state)
245648761c62SAndrew Jeffery {
245748761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
245848761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
245948761c62SAndrew Jeffery 	int rc;
246048761c62SAndrew Jeffery 
246148761c62SAndrew Jeffery 	if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) {
246248761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
246348761c62SAndrew Jeffery 	}
246448761c62SAndrew Jeffery 
2465830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_REQ_BYTES,
246648761c62SAndrew Jeffery 				    msg->payload, payload_length);
246748761c62SAndrew Jeffery 	if (rc) {
2468830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
246948761c62SAndrew Jeffery 	}
247048761c62SAndrew Jeffery 
247148761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, sensor_id);
247248761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, rearm_event_state);
247348761c62SAndrew Jeffery 
2474830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
2475830c1eb4SAndrew Jeffery 	if (rc) {
2476830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
2477830c1eb4SAndrew Jeffery 	}
2478830c1eb4SAndrew Jeffery 
2479830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
248048761c62SAndrew Jeffery }
248148761c62SAndrew Jeffery 
248248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
248348761c62SAndrew Jeffery int encode_set_event_receiver_req(uint8_t instance_id,
248448761c62SAndrew Jeffery 				  uint8_t event_message_global_enable,
248548761c62SAndrew Jeffery 				  uint8_t transport_protocol_type,
248648761c62SAndrew Jeffery 				  uint8_t event_receiver_address_info,
248748761c62SAndrew Jeffery 				  uint16_t heartbeat_timer,
248848761c62SAndrew Jeffery 				  struct pldm_msg *msg)
248948761c62SAndrew Jeffery {
249048761c62SAndrew Jeffery 	if (msg == NULL) {
249148761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
249248761c62SAndrew Jeffery 	}
249348761c62SAndrew Jeffery 
249448761c62SAndrew Jeffery 	if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
249548761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
249648761c62SAndrew Jeffery 	}
249748761c62SAndrew Jeffery 
249848761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
249948761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
250048761c62SAndrew Jeffery 	header.instance = instance_id;
250148761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
250248761c62SAndrew Jeffery 	header.command = PLDM_SET_EVENT_RECEIVER;
250348761c62SAndrew Jeffery 
250448761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
250548761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
250648761c62SAndrew Jeffery 		return rc;
250748761c62SAndrew Jeffery 	}
250848761c62SAndrew Jeffery 
250948761c62SAndrew Jeffery 	struct pldm_set_event_receiver_req *request =
251048761c62SAndrew Jeffery 		(struct pldm_set_event_receiver_req *)msg->payload;
251148761c62SAndrew Jeffery 	request->event_message_global_enable = event_message_global_enable;
251248761c62SAndrew Jeffery 
251348761c62SAndrew Jeffery 	request->transport_protocol_type = transport_protocol_type;
251448761c62SAndrew Jeffery 	request->event_receiver_address_info = event_receiver_address_info;
251548761c62SAndrew Jeffery 
251648761c62SAndrew Jeffery 	if (event_message_global_enable ==
251748761c62SAndrew Jeffery 	    PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {
251848761c62SAndrew Jeffery 		if (heartbeat_timer == 0) {
251948761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_DATA;
252048761c62SAndrew Jeffery 		}
252148761c62SAndrew Jeffery 		request->heartbeat_timer = htole16(heartbeat_timer);
252248761c62SAndrew Jeffery 	}
252348761c62SAndrew Jeffery 
252448761c62SAndrew Jeffery 	return PLDM_SUCCESS;
252548761c62SAndrew Jeffery }
252648761c62SAndrew Jeffery 
252748761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
252848761c62SAndrew Jeffery int decode_set_event_receiver_resp(const struct pldm_msg *msg,
252948761c62SAndrew Jeffery 				   size_t payload_length,
253048761c62SAndrew Jeffery 				   uint8_t *completion_code)
253148761c62SAndrew Jeffery {
253248761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
253348761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
253448761c62SAndrew Jeffery 	int rc;
253548761c62SAndrew Jeffery 
253648761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL) {
253748761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
253848761c62SAndrew Jeffery 	}
253948761c62SAndrew Jeffery 
2540830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_RESP_BYTES,
254148761c62SAndrew Jeffery 				    msg->payload, payload_length);
254248761c62SAndrew Jeffery 	if (rc) {
2543830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
254448761c62SAndrew Jeffery 	}
254548761c62SAndrew Jeffery 
254648761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, completion_code);
254748761c62SAndrew Jeffery 
2548830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
2549830c1eb4SAndrew Jeffery 	if (rc) {
2550830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
2551830c1eb4SAndrew Jeffery 	}
2552830c1eb4SAndrew Jeffery 
2553830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
255448761c62SAndrew Jeffery }
255548761c62SAndrew Jeffery 
255648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
255748761c62SAndrew Jeffery int decode_set_event_receiver_req(const struct pldm_msg *msg,
255848761c62SAndrew Jeffery 				  size_t payload_length,
255948761c62SAndrew Jeffery 				  uint8_t *event_message_global_enable,
256048761c62SAndrew Jeffery 				  uint8_t *transport_protocol_type,
256148761c62SAndrew Jeffery 				  uint8_t *event_receiver_address_info,
256248761c62SAndrew Jeffery 				  uint16_t *heartbeat_timer)
256348761c62SAndrew Jeffery 
256448761c62SAndrew Jeffery {
256548761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
256648761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
256748761c62SAndrew Jeffery 	int rc;
256848761c62SAndrew Jeffery 
256948761c62SAndrew Jeffery 	if (msg == NULL || event_message_global_enable == NULL ||
257048761c62SAndrew Jeffery 	    transport_protocol_type == NULL ||
257148761c62SAndrew Jeffery 	    event_receiver_address_info == NULL || heartbeat_timer == NULL) {
257248761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
257348761c62SAndrew Jeffery 	}
257448761c62SAndrew Jeffery 
2575830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_REQ_BYTES,
257648761c62SAndrew Jeffery 				    msg->payload, payload_length);
257748761c62SAndrew Jeffery 	if (rc) {
2578830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
257948761c62SAndrew Jeffery 	}
258048761c62SAndrew Jeffery 
258148761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, event_message_global_enable);
258248761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, transport_protocol_type);
258348761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, event_receiver_address_info);
258448761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, heartbeat_timer);
258548761c62SAndrew Jeffery 
258648761c62SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
258748761c62SAndrew Jeffery 	if (rc) {
2588830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
258948761c62SAndrew Jeffery 	}
259048761c62SAndrew Jeffery 
259148761c62SAndrew Jeffery 	if ((*event_message_global_enable ==
259248761c62SAndrew Jeffery 	     PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) &&
259348761c62SAndrew Jeffery 	    (*heartbeat_timer == 0)) {
259448761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
259548761c62SAndrew Jeffery 	}
259648761c62SAndrew Jeffery 
259748761c62SAndrew Jeffery 	return PLDM_SUCCESS;
259848761c62SAndrew Jeffery }
259948761c62SAndrew Jeffery 
260048761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
260148761c62SAndrew Jeffery int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code,
260248761c62SAndrew Jeffery 				   struct pldm_msg *msg)
260348761c62SAndrew Jeffery 
260448761c62SAndrew Jeffery {
260548761c62SAndrew Jeffery 	if (msg == NULL) {
260648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
260748761c62SAndrew Jeffery 	}
260848761c62SAndrew Jeffery 
260948761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
261048761c62SAndrew Jeffery 	header.instance = instance_id;
261148761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
261248761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
261348761c62SAndrew Jeffery 	header.command = PLDM_SET_EVENT_RECEIVER;
261448761c62SAndrew Jeffery 
261548761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
261648761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
261748761c62SAndrew Jeffery 		return rc;
261848761c62SAndrew Jeffery 	}
261948761c62SAndrew Jeffery 
262048761c62SAndrew Jeffery 	msg->payload[0] = completion_code;
262148761c62SAndrew Jeffery 
262248761c62SAndrew Jeffery 	return PLDM_SUCCESS;
262348761c62SAndrew Jeffery }
262448761c62SAndrew Jeffery 
262548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
262648761c62SAndrew Jeffery int encode_poll_for_platform_event_message_req(uint8_t instance_id,
262748761c62SAndrew Jeffery 					       uint8_t format_version,
262848761c62SAndrew Jeffery 					       uint8_t transfer_operation_flag,
262948761c62SAndrew Jeffery 					       uint32_t data_transfer_handle,
263048761c62SAndrew Jeffery 					       uint16_t event_id_to_acknowledge,
263148761c62SAndrew Jeffery 					       struct pldm_msg *msg,
263248761c62SAndrew Jeffery 					       size_t payload_length)
263348761c62SAndrew Jeffery {
263448761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
263548761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
263648761c62SAndrew Jeffery 	int rc;
263748761c62SAndrew Jeffery 
263848761c62SAndrew Jeffery 	if (msg == NULL) {
263948761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
264048761c62SAndrew Jeffery 	}
264148761c62SAndrew Jeffery 
2642387b10f6SThu Nguyen 	rc = pldm_platform_poll_for_platform_event_message_validate(
2643387b10f6SThu Nguyen 		transfer_operation_flag, event_id_to_acknowledge);
2644387b10f6SThu Nguyen 	if (rc < 0) {
2645387b10f6SThu Nguyen 		return PLDM_ERROR_INVALID_DATA;
2646387b10f6SThu Nguyen 	}
2647387b10f6SThu Nguyen 
264848761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
264948761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
265048761c62SAndrew Jeffery 	header.instance = instance_id;
265148761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
265248761c62SAndrew Jeffery 	header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
265348761c62SAndrew Jeffery 
265448761c62SAndrew Jeffery 	rc = pack_pldm_header(&header, &(msg->hdr));
265548761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
265648761c62SAndrew Jeffery 		return rc;
265748761c62SAndrew Jeffery 	}
265848761c62SAndrew Jeffery 
2659830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(
266048761c62SAndrew Jeffery 		buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
266148761c62SAndrew Jeffery 		msg->payload, payload_length);
266248761c62SAndrew Jeffery 	if (rc) {
2663830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
266448761c62SAndrew Jeffery 	}
266548761c62SAndrew Jeffery 
266648761c62SAndrew Jeffery 	pldm_msgbuf_insert(buf, format_version);
266748761c62SAndrew Jeffery 	pldm_msgbuf_insert(buf, transfer_operation_flag);
266848761c62SAndrew Jeffery 	pldm_msgbuf_insert(buf, data_transfer_handle);
266948761c62SAndrew Jeffery 	pldm_msgbuf_insert(buf, event_id_to_acknowledge);
267048761c62SAndrew Jeffery 
2671830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
2672830c1eb4SAndrew Jeffery 	if (rc) {
2673830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
2674830c1eb4SAndrew Jeffery 	}
2675830c1eb4SAndrew Jeffery 
2676830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
267748761c62SAndrew Jeffery }
267848761c62SAndrew Jeffery 
267948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
268048761c62SAndrew Jeffery int decode_poll_for_platform_event_message_resp(
268148761c62SAndrew Jeffery 	const struct pldm_msg *msg, size_t payload_length,
268248761c62SAndrew Jeffery 	uint8_t *completion_code, uint8_t *tid, uint16_t *event_id,
268348761c62SAndrew Jeffery 	uint32_t *next_data_transfer_handle, uint8_t *transfer_flag,
268448761c62SAndrew Jeffery 	uint8_t *event_class, uint32_t *event_data_size, void **event_data,
268548761c62SAndrew Jeffery 	uint32_t *event_data_integrity_checksum)
268648761c62SAndrew Jeffery {
268748761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
268848761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
268948761c62SAndrew Jeffery 	int rc;
269048761c62SAndrew Jeffery 
269148761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL || tid == NULL ||
269248761c62SAndrew Jeffery 	    event_id == NULL || next_data_transfer_handle == NULL ||
269348761c62SAndrew Jeffery 	    transfer_flag == NULL || event_class == NULL ||
269448761c62SAndrew Jeffery 	    event_data_size == NULL || event_data == NULL ||
269548761c62SAndrew Jeffery 	    event_data_integrity_checksum == NULL) {
269648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
269748761c62SAndrew Jeffery 	}
269848761c62SAndrew Jeffery 
2699830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(
270048761c62SAndrew Jeffery 		buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
270148761c62SAndrew Jeffery 		msg->payload, payload_length);
270248761c62SAndrew Jeffery 	if (rc) {
2703830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
270448761c62SAndrew Jeffery 	}
270548761c62SAndrew Jeffery 
270648761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, completion_code);
270748761c62SAndrew Jeffery 	if (rc) {
2708830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
270948761c62SAndrew Jeffery 	}
271048761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
271148761c62SAndrew Jeffery 		return *completion_code;
271248761c62SAndrew Jeffery 	}
271348761c62SAndrew Jeffery 
271448761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, tid);
271548761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, event_id);
271648761c62SAndrew Jeffery 	if (rc) {
2717830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
271848761c62SAndrew Jeffery 	}
271948761c62SAndrew Jeffery 	if ((*event_id == 0) || (*event_id == 0xffff)) {
272048761c62SAndrew Jeffery 		return PLDM_SUCCESS;
272148761c62SAndrew Jeffery 	}
272248761c62SAndrew Jeffery 
272348761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, next_data_transfer_handle);
272448761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, transfer_flag);
272548761c62SAndrew Jeffery 	if (rc) {
2726830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
272748761c62SAndrew Jeffery 	}
272848761c62SAndrew Jeffery 
272948761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, event_class);
273048761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, event_data_size);
273148761c62SAndrew Jeffery 	if (rc) {
2732830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
273348761c62SAndrew Jeffery 	}
273448761c62SAndrew Jeffery 	if (*event_data_size > payload_length) {
273548761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
273648761c62SAndrew Jeffery 	}
273748761c62SAndrew Jeffery 
273848761c62SAndrew Jeffery 	if (*event_data_size > 0) {
273948761c62SAndrew Jeffery 		pldm_msgbuf_span_required(buf, *event_data_size, event_data);
274048761c62SAndrew Jeffery 	}
274148761c62SAndrew Jeffery 
274248761c62SAndrew Jeffery 	if (*transfer_flag == PLDM_END ||
274348761c62SAndrew Jeffery 	    *transfer_flag == PLDM_START_AND_END) {
274448761c62SAndrew Jeffery 		pldm_msgbuf_extract_p(buf, event_data_integrity_checksum);
274548761c62SAndrew Jeffery 	}
274648761c62SAndrew Jeffery 
2747830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy_consumed(buf);
2748830c1eb4SAndrew Jeffery 	if (rc) {
2749830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
2750830c1eb4SAndrew Jeffery 	}
2751830c1eb4SAndrew Jeffery 
2752830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
275348761c62SAndrew Jeffery }
275448761c62SAndrew Jeffery 
275548761c62SAndrew Jeffery LIBPLDM_ABI_TESTING
275648761c62SAndrew Jeffery int decode_numeric_effecter_pdr_data(
275748761c62SAndrew Jeffery 	const void *pdr_data, size_t pdr_data_length,
275848761c62SAndrew Jeffery 	struct pldm_numeric_effecter_value_pdr *pdr_value)
275948761c62SAndrew Jeffery {
276048761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
276148761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
276248761c62SAndrew Jeffery 	struct pldm_value_pdr_hdr hdr;
276348761c62SAndrew Jeffery 	int rc;
276448761c62SAndrew Jeffery 
276590bbe6c0SAndrew Jeffery 	if (!pdr_data || !pdr_value) {
276690bbe6c0SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
276790bbe6c0SAndrew Jeffery 	}
276890bbe6c0SAndrew Jeffery 
2769830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf,
2770830c1eb4SAndrew Jeffery 				    PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
277148761c62SAndrew Jeffery 				    pdr_data, pdr_data_length);
277248761c62SAndrew Jeffery 	if (rc) {
2773830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
277448761c62SAndrew Jeffery 	}
277548761c62SAndrew Jeffery 
2776329176a8SAndrew Jeffery 	rc = pldm_msgbuf_extract_value_pdr_hdr(
2777329176a8SAndrew Jeffery 		buf, &hdr, PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
277848761c62SAndrew Jeffery 		pdr_data_length);
277948761c62SAndrew Jeffery 	if (rc) {
2780329176a8SAndrew Jeffery 		return pldm_xlate_errno(rc);
278148761c62SAndrew Jeffery 	}
278248761c62SAndrew Jeffery 
278348761c62SAndrew Jeffery 	memcpy(&pdr_value->hdr, &hdr, sizeof(hdr));
278448761c62SAndrew Jeffery 
278548761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
278648761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->effecter_id);
278748761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->entity_type);
278848761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->entity_instance);
278948761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->container_id);
279048761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->effecter_semantic_id);
279148761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->effecter_init);
279248761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->effecter_auxiliary_names);
279348761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->base_unit);
279448761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->unit_modifier);
279548761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->rate_unit);
279648761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle);
279748761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->aux_unit);
279848761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier);
279948761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit);
280048761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle);
280148761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->is_linear);
280248761c62SAndrew Jeffery 
280348761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract(buf, pdr_value->effecter_data_size);
280448761c62SAndrew Jeffery 	if (rc) {
2805830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
280648761c62SAndrew Jeffery 	}
280748761c62SAndrew Jeffery 	if (pdr_value->effecter_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
280848761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
280948761c62SAndrew Jeffery 	}
281048761c62SAndrew Jeffery 
281148761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->resolution);
281248761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->offset);
281348761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->accuracy);
281448761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->plus_tolerance);
281548761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->minus_tolerance);
281648761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->state_transition_interval);
281748761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->transition_interval);
281848761c62SAndrew Jeffery 	pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size,
281948761c62SAndrew Jeffery 					  pdr_value->max_settable);
282048761c62SAndrew Jeffery 	pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size,
282148761c62SAndrew Jeffery 					  pdr_value->min_settable);
282248761c62SAndrew Jeffery 
282348761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
282448761c62SAndrew Jeffery 	if (rc) {
2825830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
282648761c62SAndrew Jeffery 	}
282748761c62SAndrew Jeffery 	if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
282848761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
282948761c62SAndrew Jeffery 	}
283048761c62SAndrew Jeffery 
283148761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
283248761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
283348761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->nominal_value);
283448761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
283548761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->normal_max);
283648761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
283748761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->normal_min);
283848761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
283948761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->rated_max);
284048761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
284148761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->rated_min);
284248761c62SAndrew Jeffery 
2843830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy_consumed(buf);
2844830c1eb4SAndrew Jeffery 	if (rc) {
2845830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
2846830c1eb4SAndrew Jeffery 	}
2847830c1eb4SAndrew Jeffery 
2848830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
284948761c62SAndrew Jeffery }
285048761c62SAndrew Jeffery 
2851de67ab62STal Yacobi LIBPLDM_ABI_STABLE
285248761c62SAndrew Jeffery int encode_get_state_effecter_states_req(uint8_t instance_id,
285348761c62SAndrew Jeffery 					 uint16_t effecter_id,
285448761c62SAndrew Jeffery 					 struct pldm_msg *msg,
285548761c62SAndrew Jeffery 					 size_t payload_length)
285648761c62SAndrew Jeffery {
285748761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
285848761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
285948761c62SAndrew Jeffery 	int rc;
286048761c62SAndrew Jeffery 
286148761c62SAndrew Jeffery 	if (msg == NULL) {
2862f490a38fSTal Yacobi 		return -EINVAL;
286348761c62SAndrew Jeffery 	}
286448761c62SAndrew Jeffery 
286548761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
286648761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
286748761c62SAndrew Jeffery 	header.instance = instance_id;
286848761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
286948761c62SAndrew Jeffery 	header.command = PLDM_GET_STATE_EFFECTER_STATES;
287048761c62SAndrew Jeffery 
2871f490a38fSTal Yacobi 	rc = pack_pldm_header_errno(&header, &msg->hdr);
2872f490a38fSTal Yacobi 	if (rc < 0) {
287348761c62SAndrew Jeffery 		return rc;
287448761c62SAndrew Jeffery 	}
287548761c62SAndrew Jeffery 
2876f490a38fSTal Yacobi 	rc = pldm_msgbuf_init_errno(buf,
2877f490a38fSTal Yacobi 				    PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES,
287848761c62SAndrew Jeffery 				    msg->payload, payload_length);
287948761c62SAndrew Jeffery 	if (rc) {
288048761c62SAndrew Jeffery 		return rc;
288148761c62SAndrew Jeffery 	}
288248761c62SAndrew Jeffery 
288348761c62SAndrew Jeffery 	pldm_msgbuf_insert(buf, effecter_id);
288448761c62SAndrew Jeffery 
288548761c62SAndrew Jeffery 	return pldm_msgbuf_destroy_consumed(buf);
288648761c62SAndrew Jeffery }
288748761c62SAndrew Jeffery 
2888de67ab62STal Yacobi LIBPLDM_ABI_STABLE
288948761c62SAndrew Jeffery int decode_get_state_effecter_states_req(const struct pldm_msg *msg,
289048761c62SAndrew Jeffery 					 size_t payload_length,
289148761c62SAndrew Jeffery 					 uint16_t *effecter_id)
289248761c62SAndrew Jeffery {
289348761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
289448761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
289548761c62SAndrew Jeffery 	int rc;
289648761c62SAndrew Jeffery 
289748761c62SAndrew Jeffery 	if (msg == NULL || effecter_id == NULL) {
2898f490a38fSTal Yacobi 		return -EINVAL;
289948761c62SAndrew Jeffery 	}
290048761c62SAndrew Jeffery 
2901f490a38fSTal Yacobi 	rc = pldm_msgbuf_init_errno(
2902f490a38fSTal Yacobi 		buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
290348761c62SAndrew Jeffery 		msg->payload, payload_length);
290448761c62SAndrew Jeffery 	if (rc) {
290548761c62SAndrew Jeffery 		return rc;
290648761c62SAndrew Jeffery 	}
290748761c62SAndrew Jeffery 
290848761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, effecter_id);
290948761c62SAndrew Jeffery 
291048761c62SAndrew Jeffery 	return pldm_msgbuf_destroy_consumed(buf);
291148761c62SAndrew Jeffery }
291248761c62SAndrew Jeffery 
2913de67ab62STal Yacobi LIBPLDM_ABI_STABLE
291448761c62SAndrew Jeffery int decode_get_state_effecter_states_resp(
291548761c62SAndrew Jeffery 	const struct pldm_msg *msg, size_t payload_length,
291648761c62SAndrew Jeffery 	struct pldm_get_state_effecter_states_resp *resp)
291748761c62SAndrew Jeffery {
291848761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
291948761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
292048761c62SAndrew Jeffery 	get_effecter_state_field *field;
292148761c62SAndrew Jeffery 	int rc;
292248761c62SAndrew Jeffery 	int i;
292348761c62SAndrew Jeffery 
292448761c62SAndrew Jeffery 	if (msg == NULL || resp == NULL) {
2925f490a38fSTal Yacobi 		return -EINVAL;
292648761c62SAndrew Jeffery 	}
292748761c62SAndrew Jeffery 
2928f490a38fSTal Yacobi 	rc = pldm_msgbuf_init_errno(
2929f490a38fSTal Yacobi 		buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
293048761c62SAndrew Jeffery 		msg->payload, payload_length);
293148761c62SAndrew Jeffery 	if (rc) {
293248761c62SAndrew Jeffery 		return rc;
293348761c62SAndrew Jeffery 	}
293448761c62SAndrew Jeffery 
293548761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract(buf, resp->completion_code);
293648761c62SAndrew Jeffery 	if (rc) {
293748761c62SAndrew Jeffery 		return rc;
293848761c62SAndrew Jeffery 	}
293948761c62SAndrew Jeffery 
294048761c62SAndrew Jeffery 	if (PLDM_SUCCESS != resp->completion_code) {
2941f490a38fSTal Yacobi 		return 0;
294248761c62SAndrew Jeffery 	}
294348761c62SAndrew Jeffery 
294448761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract(buf, resp->comp_effecter_count);
294548761c62SAndrew Jeffery 	if (rc) {
294648761c62SAndrew Jeffery 		return rc;
294748761c62SAndrew Jeffery 	}
294848761c62SAndrew Jeffery 
294948761c62SAndrew Jeffery 	uint8_t comp_effecter_count = resp->comp_effecter_count;
295048761c62SAndrew Jeffery 
295148761c62SAndrew Jeffery 	if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN ||
295248761c62SAndrew Jeffery 	    comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) {
2953f490a38fSTal Yacobi 		return -EBADMSG;
295448761c62SAndrew Jeffery 	}
295548761c62SAndrew Jeffery 
295648761c62SAndrew Jeffery 	for (i = 0, field = resp->field; i < comp_effecter_count;
295748761c62SAndrew Jeffery 	     i++, field++) {
295848761c62SAndrew Jeffery 		pldm_msgbuf_extract(buf, field->effecter_op_state);
295948761c62SAndrew Jeffery 		pldm_msgbuf_extract(buf, field->pending_state);
296048761c62SAndrew Jeffery 		pldm_msgbuf_extract(buf, field->present_state);
296148761c62SAndrew Jeffery 	}
296248761c62SAndrew Jeffery 
296348761c62SAndrew Jeffery 	return pldm_msgbuf_destroy_consumed(buf);
296448761c62SAndrew Jeffery }
296548761c62SAndrew Jeffery 
2966de67ab62STal Yacobi LIBPLDM_ABI_STABLE
296748761c62SAndrew Jeffery int encode_get_state_effecter_states_resp(
296848761c62SAndrew Jeffery 	uint8_t instance_id, struct pldm_get_state_effecter_states_resp *resp,
296948761c62SAndrew Jeffery 	struct pldm_msg *msg, size_t payload_length)
297048761c62SAndrew Jeffery {
297148761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
297248761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
297348761c62SAndrew Jeffery 	get_effecter_state_field *field;
297448761c62SAndrew Jeffery 	int rc;
297548761c62SAndrew Jeffery 	int i;
297648761c62SAndrew Jeffery 
297748761c62SAndrew Jeffery 	if (msg == NULL || resp == NULL) {
2978f490a38fSTal Yacobi 		return -EINVAL;
297948761c62SAndrew Jeffery 	}
298048761c62SAndrew Jeffery 
298148761c62SAndrew Jeffery 	uint8_t comp_effecter_count = resp->comp_effecter_count;
298248761c62SAndrew Jeffery 
298348761c62SAndrew Jeffery 	if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN ||
298448761c62SAndrew Jeffery 	    comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) {
2985f490a38fSTal Yacobi 		return -EBADMSG;
298648761c62SAndrew Jeffery 	}
298748761c62SAndrew Jeffery 
298848761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
298948761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
299048761c62SAndrew Jeffery 	header.instance = instance_id;
299148761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
299248761c62SAndrew Jeffery 	header.command = PLDM_GET_STATE_EFFECTER_STATES;
299348761c62SAndrew Jeffery 
2994f490a38fSTal Yacobi 	rc = pack_pldm_header_errno(&header, &msg->hdr);
2995f490a38fSTal Yacobi 	if (rc < 0) {
299648761c62SAndrew Jeffery 		return rc;
299748761c62SAndrew Jeffery 	}
299848761c62SAndrew Jeffery 
2999f490a38fSTal Yacobi 	rc = pldm_msgbuf_init_errno(
3000f490a38fSTal Yacobi 		buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
300148761c62SAndrew Jeffery 		msg->payload, payload_length);
300248761c62SAndrew Jeffery 	if (rc) {
300348761c62SAndrew Jeffery 		return rc;
300448761c62SAndrew Jeffery 	}
300548761c62SAndrew Jeffery 
300648761c62SAndrew Jeffery 	pldm_msgbuf_insert(buf, resp->completion_code);
300748761c62SAndrew Jeffery 	pldm_msgbuf_insert(buf, comp_effecter_count);
300848761c62SAndrew Jeffery 
300948761c62SAndrew Jeffery 	for (i = 0, field = resp->field; i < comp_effecter_count;
301048761c62SAndrew Jeffery 	     i++, field++) {
301148761c62SAndrew Jeffery 		pldm_msgbuf_insert(buf, field->effecter_op_state);
301248761c62SAndrew Jeffery 		pldm_msgbuf_insert(buf, field->pending_state);
301348761c62SAndrew Jeffery 		pldm_msgbuf_insert(buf, field->present_state);
301448761c62SAndrew Jeffery 	}
301548761c62SAndrew Jeffery 
301648761c62SAndrew Jeffery 	return pldm_msgbuf_destroy_consumed(buf);
301748761c62SAndrew Jeffery }
3018dacfa354SThu Nguyen 
301943cb4b5fSThu Nguyen LIBPLDM_ABI_STABLE
3020dacfa354SThu Nguyen int decode_entity_auxiliary_names_pdr(
3021dacfa354SThu Nguyen 	const void *data, size_t data_length,
3022dacfa354SThu Nguyen 	struct pldm_entity_auxiliary_names_pdr *pdr, size_t pdr_length)
3023dacfa354SThu Nguyen {
3024dacfa354SThu Nguyen 	struct pldm_msgbuf _buf;
3025dacfa354SThu Nguyen 	struct pldm_msgbuf *buf = &_buf;
3026dacfa354SThu Nguyen 	struct pldm_msgbuf _src;
3027dacfa354SThu Nguyen 	struct pldm_msgbuf *src = &_src;
3028dacfa354SThu Nguyen 	struct pldm_msgbuf _dst;
3029dacfa354SThu Nguyen 	struct pldm_msgbuf *dst = &_dst;
3030dacfa354SThu Nguyen 	size_t names_len = 0;
3031dacfa354SThu Nguyen 	void *names = NULL;
3032dacfa354SThu Nguyen 	int rc;
3033dacfa354SThu Nguyen 	int i;
3034dacfa354SThu Nguyen 
303590bbe6c0SAndrew Jeffery 	if (!data || !pdr) {
303690bbe6c0SAndrew Jeffery 		return -EINVAL;
303790bbe6c0SAndrew Jeffery 	}
303890bbe6c0SAndrew Jeffery 
3039dacfa354SThu Nguyen 	/*
3040dacfa354SThu Nguyen 	 * Alignment of auxiliary_name_data is an invariant as we statically assert
3041dacfa354SThu Nguyen 	 * its behaviour in the header.
3042dacfa354SThu Nguyen 	 */
3043dacfa354SThu Nguyen 	assert(!((uintptr_t)pdr->auxiliary_name_data &
3044dacfa354SThu Nguyen 		 (alignof(pldm_utf16be) - 1)));
3045dacfa354SThu Nguyen 
3046dacfa354SThu Nguyen 	/* Reject any lengths that are obviously invalid */
3047dacfa354SThu Nguyen 	if (pdr_length < data_length || pdr_length < sizeof(*pdr)) {
3048dacfa354SThu Nguyen 		return -EINVAL;
3049dacfa354SThu Nguyen 	}
3050dacfa354SThu Nguyen 
3051dacfa354SThu Nguyen 	rc = pldm_msgbuf_init_errno(
3052dacfa354SThu Nguyen 		buf, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH, data,
3053dacfa354SThu Nguyen 		data_length);
3054dacfa354SThu Nguyen 	if (rc) {
3055dacfa354SThu Nguyen 		return rc;
3056dacfa354SThu Nguyen 	}
3057dacfa354SThu Nguyen 
3058329176a8SAndrew Jeffery 	rc = pldm_msgbuf_extract_value_pdr_hdr(
3059329176a8SAndrew Jeffery 		buf, &pdr->hdr, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH,
3060dacfa354SThu Nguyen 		data_length);
3061dacfa354SThu Nguyen 	if (rc) {
3062dacfa354SThu Nguyen 		return rc;
3063dacfa354SThu Nguyen 	}
3064dacfa354SThu Nguyen 
3065dacfa354SThu Nguyen 	pldm_msgbuf_extract(buf, pdr->container.entity_type);
3066dacfa354SThu Nguyen 	pldm_msgbuf_extract(buf, pdr->container.entity_instance_num);
3067dacfa354SThu Nguyen 	pldm_msgbuf_extract(buf, pdr->container.entity_container_id);
3068dacfa354SThu Nguyen 	pldm_msgbuf_extract(buf, pdr->shared_name_count);
3069dacfa354SThu Nguyen 	rc = pldm_msgbuf_extract(buf, pdr->name_string_count);
3070dacfa354SThu Nguyen 	if (rc < 0) {
3071dacfa354SThu Nguyen 		return rc;
3072dacfa354SThu Nguyen 	}
3073dacfa354SThu Nguyen 
3074dacfa354SThu Nguyen 	rc = pldm_msgbuf_span_remaining(buf, &names, &names_len);
3075dacfa354SThu Nguyen 	if (rc < 0) {
3076dacfa354SThu Nguyen 		return rc;
3077dacfa354SThu Nguyen 	}
307890bbe6c0SAndrew Jeffery 	assert(names);
3079dacfa354SThu Nguyen 
3080dacfa354SThu Nguyen 	pdr->auxiliary_name_data_size = pdr_length - sizeof(*pdr);
3081dacfa354SThu Nguyen 
3082dacfa354SThu Nguyen 	rc = pldm_msgbuf_init_errno(dst, pdr->auxiliary_name_data_size,
3083dacfa354SThu Nguyen 				    pdr->auxiliary_name_data,
3084dacfa354SThu Nguyen 				    pdr->auxiliary_name_data_size);
3085dacfa354SThu Nguyen 	if (rc < 0) {
3086dacfa354SThu Nguyen 		return rc;
3087dacfa354SThu Nguyen 	}
3088dacfa354SThu Nguyen 
3089dacfa354SThu Nguyen 	/*
3090dacfa354SThu Nguyen 	 * Below we do two passes over the same region. This is to first pack the
3091dacfa354SThu Nguyen 	 * UTF16-BE strings into auxiliary_name_data, followed by the ASCII strings,
3092dacfa354SThu Nguyen 	 * to maintain appropriate alignment.
3093dacfa354SThu Nguyen 	 */
3094dacfa354SThu Nguyen 
3095dacfa354SThu Nguyen 	/* Initialise for the first pass to extract the UTF16-BE name strings */
3096dacfa354SThu Nguyen 	rc = pldm_msgbuf_init_errno(src, names_len, names, names_len);
3097dacfa354SThu Nguyen 	if (rc < 0) {
3098dacfa354SThu Nguyen 		return rc;
3099dacfa354SThu Nguyen 	}
3100dacfa354SThu Nguyen 
3101dacfa354SThu Nguyen 	for (i = 0; i < pdr->name_string_count; i++) {
3102dacfa354SThu Nguyen 		pldm_msgbuf_span_string_ascii(src, NULL, NULL);
31030a1be3cbSAndrew Jeffery 		rc = pldm_msgbuf_copy_string_utf16(dst, src);
31040a1be3cbSAndrew Jeffery 		if (rc) {
31050a1be3cbSAndrew Jeffery 			return rc;
31060a1be3cbSAndrew Jeffery 		}
3107dacfa354SThu Nguyen 	}
3108dacfa354SThu Nguyen 
3109dacfa354SThu Nguyen 	rc = pldm_msgbuf_destroy_consumed(src);
3110dacfa354SThu Nguyen 	if (rc < 0) {
3111dacfa354SThu Nguyen 		return rc;
3112dacfa354SThu Nguyen 	}
3113dacfa354SThu Nguyen 
3114dacfa354SThu Nguyen 	/* Reinitialise for the second pass to extract the ASCII tag strings */
3115dacfa354SThu Nguyen 	rc = pldm_msgbuf_init_errno(src, names_len, names, names_len);
3116dacfa354SThu Nguyen 	if (rc < 0) {
3117dacfa354SThu Nguyen 		return rc;
3118dacfa354SThu Nguyen 	}
3119dacfa354SThu Nguyen 
3120dacfa354SThu Nguyen 	for (i = 0; i < pdr->name_string_count; i++) {
31210a1be3cbSAndrew Jeffery 		rc = pldm_msgbuf_copy_string_ascii(dst, src);
31220a1be3cbSAndrew Jeffery 		if (rc) {
31230a1be3cbSAndrew Jeffery 			return rc;
31240a1be3cbSAndrew Jeffery 		}
3125dacfa354SThu Nguyen 		pldm_msgbuf_span_string_utf16(src, NULL, NULL);
3126dacfa354SThu Nguyen 	}
3127dacfa354SThu Nguyen 
3128dacfa354SThu Nguyen 	if ((rc = pldm_msgbuf_destroy(dst)) ||
3129dacfa354SThu Nguyen 	    (rc = pldm_msgbuf_destroy(src)) ||
3130dacfa354SThu Nguyen 	    (rc = pldm_msgbuf_destroy(buf))) {
3131dacfa354SThu Nguyen 		return rc;
3132dacfa354SThu Nguyen 	}
3133dacfa354SThu Nguyen 
3134dacfa354SThu Nguyen 	return 0;
3135dacfa354SThu Nguyen }
3136dacfa354SThu Nguyen 
313743cb4b5fSThu Nguyen LIBPLDM_ABI_STABLE
3138dacfa354SThu Nguyen int decode_pldm_entity_auxiliary_names_pdr_index(
3139dacfa354SThu Nguyen 	struct pldm_entity_auxiliary_names_pdr *pdr)
3140dacfa354SThu Nguyen {
3141dacfa354SThu Nguyen 	struct pldm_msgbuf _buf;
3142dacfa354SThu Nguyen 	struct pldm_msgbuf *buf = &_buf;
3143dacfa354SThu Nguyen 	int rc;
3144dacfa354SThu Nguyen 	int i;
3145dacfa354SThu Nguyen 
3146dacfa354SThu Nguyen 	if (!pdr) {
3147dacfa354SThu Nguyen 		return -EINVAL;
3148dacfa354SThu Nguyen 	}
3149dacfa354SThu Nguyen 
3150dacfa354SThu Nguyen 	if (pdr->name_string_count == 0 && pdr->names) {
3151dacfa354SThu Nguyen 		return -EINVAL;
3152dacfa354SThu Nguyen 	}
3153dacfa354SThu Nguyen 
3154dacfa354SThu Nguyen 	if (pdr->name_string_count > 0 && !pdr->names) {
3155dacfa354SThu Nguyen 		return -EINVAL;
3156dacfa354SThu Nguyen 	}
3157dacfa354SThu Nguyen 
3158dacfa354SThu Nguyen 	if (pdr->name_string_count == 0) {
3159dacfa354SThu Nguyen 		return 0;
3160dacfa354SThu Nguyen 	}
3161dacfa354SThu Nguyen 
3162dacfa354SThu Nguyen 	/*
3163dacfa354SThu Nguyen 	 * Minimum size is one NUL for each member of each entry
3164dacfa354SThu Nguyen 	 *
3165dacfa354SThu Nguyen 	 * Note that the definition of nameLanguageTag in DSP0248 v1.2.2
3166dacfa354SThu Nguyen 	 * states the following:
3167dacfa354SThu Nguyen 	 *
3168dacfa354SThu Nguyen 	 * > A null-terminated ISO646 ASCII string ...
3169dacfa354SThu Nguyen 	 * >
3170dacfa354SThu Nguyen 	 * > special value: null string = 0x0000 = unspecified.
3171dacfa354SThu Nguyen 	 *
3172dacfa354SThu Nguyen 	 * Until proven otherwise we will assume the "0x0000" is a
3173dacfa354SThu Nguyen 	 * misrepresentation of an ASCII NUL, and that ASCII NUL is
3174dacfa354SThu Nguyen 	 * represented by a single byte.
3175dacfa354SThu Nguyen 	 */
3176dacfa354SThu Nguyen 	rc = pldm_msgbuf_init_errno(
3177dacfa354SThu Nguyen 		buf, pdr->name_string_count * (sizeof(char) + sizeof(char16_t)),
3178dacfa354SThu Nguyen 		pdr->auxiliary_name_data, pdr->auxiliary_name_data_size);
3179dacfa354SThu Nguyen 	if (rc) {
3180dacfa354SThu Nguyen 		return rc;
3181dacfa354SThu Nguyen 	}
3182dacfa354SThu Nguyen 
3183dacfa354SThu Nguyen 	for (i = 0; i < pdr->name_string_count; i++) {
3184dacfa354SThu Nguyen 		void *loc = NULL;
3185dacfa354SThu Nguyen 		pldm_msgbuf_span_string_utf16(buf, &loc, NULL);
3186dacfa354SThu Nguyen 		pdr->names[i].name = loc;
3187dacfa354SThu Nguyen 	}
3188dacfa354SThu Nguyen 
3189dacfa354SThu Nguyen 	for (i = 0; i < pdr->name_string_count; i++) {
3190dacfa354SThu Nguyen 		void *loc = NULL;
3191dacfa354SThu Nguyen 		pldm_msgbuf_span_string_ascii(buf, &loc, NULL);
3192dacfa354SThu Nguyen 		pdr->names[i].tag = loc;
3193dacfa354SThu Nguyen 	}
3194dacfa354SThu Nguyen 
3195dacfa354SThu Nguyen 	return pldm_msgbuf_destroy_consumed(buf);
3196dacfa354SThu Nguyen }
3197a5d18dc7SThu Nguyen 
31983559aa1fSThu Nguyen LIBPLDM_ABI_STABLE
319902903038SThu Nguyen int decode_pldm_platform_cper_event(const void *event_data,
320002903038SThu Nguyen 				    size_t event_data_length,
320102903038SThu Nguyen 				    struct pldm_platform_cper_event *cper_event,
320202903038SThu Nguyen 				    size_t cper_event_length)
3203a5d18dc7SThu Nguyen {
3204a5d18dc7SThu Nguyen 	struct pldm_msgbuf _buf;
3205a5d18dc7SThu Nguyen 	struct pldm_msgbuf *buf = &_buf;
3206a5d18dc7SThu Nguyen 	int rc;
3207a5d18dc7SThu Nguyen 
3208a5d18dc7SThu Nguyen 	if (!cper_event || !event_data) {
3209a5d18dc7SThu Nguyen 		return -EINVAL;
3210a5d18dc7SThu Nguyen 	}
3211a5d18dc7SThu Nguyen 
3212a5d18dc7SThu Nguyen 	if (cper_event_length < sizeof(*cper_event)) {
3213a5d18dc7SThu Nguyen 		return -EINVAL;
3214a5d18dc7SThu Nguyen 	}
3215a5d18dc7SThu Nguyen 
3216a5d18dc7SThu Nguyen 	rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_CPER_EVENT_MIN_LENGTH,
3217a5d18dc7SThu Nguyen 				    event_data, event_data_length);
3218a5d18dc7SThu Nguyen 	if (rc) {
3219a5d18dc7SThu Nguyen 		return rc;
3220a5d18dc7SThu Nguyen 	}
3221a5d18dc7SThu Nguyen 
3222a5d18dc7SThu Nguyen 	pldm_msgbuf_extract(buf, cper_event->format_version);
3223a5d18dc7SThu Nguyen 	rc = pldm_msgbuf_extract(buf, cper_event->format_type);
3224a5d18dc7SThu Nguyen 	if (rc) {
3225a5d18dc7SThu Nguyen 		return rc;
3226a5d18dc7SThu Nguyen 	}
3227a5d18dc7SThu Nguyen 	if (cper_event->format_type != PLDM_PLATFORM_CPER_EVENT_WITH_HEADER &&
3228a5d18dc7SThu Nguyen 	    cper_event->format_type !=
3229a5d18dc7SThu Nguyen 		    PLDM_PLATFORM_CPER_EVENT_WITHOUT_HEADER) {
3230a5d18dc7SThu Nguyen 		return -EPROTO;
3231a5d18dc7SThu Nguyen 	}
3232a5d18dc7SThu Nguyen 
3233a5d18dc7SThu Nguyen 	rc = pldm_msgbuf_extract(buf, cper_event->event_data_length);
3234a5d18dc7SThu Nguyen 	if (rc) {
3235a5d18dc7SThu Nguyen 		return rc;
3236a5d18dc7SThu Nguyen 	}
3237a5d18dc7SThu Nguyen 
3238a5d18dc7SThu Nguyen 	if (cper_event->event_data_length >
3239a5d18dc7SThu Nguyen 	    (cper_event_length - sizeof(*cper_event))) {
3240a5d18dc7SThu Nguyen 		return -EOVERFLOW;
3241a5d18dc7SThu Nguyen 	}
3242a5d18dc7SThu Nguyen 
32430a1be3cbSAndrew Jeffery 	rc = pldm_msgbuf_extract_array_uint8(
32440a1be3cbSAndrew Jeffery 		buf, cper_event->event_data_length, cper_event->event_data,
32450a1be3cbSAndrew Jeffery 		cper_event_length - sizeof(*cper_event));
32460a1be3cbSAndrew Jeffery 	if (rc) {
32470a1be3cbSAndrew Jeffery 		return rc;
32480a1be3cbSAndrew Jeffery 	}
3249a5d18dc7SThu Nguyen 
3250a5d18dc7SThu Nguyen 	return pldm_msgbuf_destroy_consumed(buf);
3251a5d18dc7SThu Nguyen }
3252a5d18dc7SThu Nguyen 
32533559aa1fSThu Nguyen LIBPLDM_ABI_STABLE
3254a5d18dc7SThu Nguyen uint8_t *
3255a5d18dc7SThu Nguyen pldm_platform_cper_event_event_data(struct pldm_platform_cper_event *event)
3256a5d18dc7SThu Nguyen {
3257a5d18dc7SThu Nguyen 	return event->event_data;
3258a5d18dc7SThu Nguyen }
3259