xref: /openbmc/libpldm/src/dsp/platform.c (revision 56ef86a0ba49b46c519f965081fce6ce2ce15e41)
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
encode_state_effecter_pdr(struct pldm_state_effecter_pdr * const effecter,const size_t allocation_size,const struct state_effecter_possible_states * const possible_states,const size_t possible_states_size,size_t * const actual_size)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 	size_t calculated_possible_states_size = 0;
2648761c62SAndrew Jeffery 
27ad33b99aSAndrew Jeffery 	if (!effecter || !possible_states || !actual_size) {
28ad33b99aSAndrew Jeffery 		return PLDM_ERROR;
29ad33b99aSAndrew Jeffery 	}
30ad33b99aSAndrew Jeffery 
311be1d5eaSAndrew Jeffery 	if (SIZE_MAX - (sizeof(*effecter) - sizeof(effecter->possible_states)) <
321be1d5eaSAndrew Jeffery 	    possible_states_size) {
33ad33b99aSAndrew Jeffery 		return PLDM_ERROR;
34ad33b99aSAndrew Jeffery 	}
35ad33b99aSAndrew Jeffery 
36ad33b99aSAndrew Jeffery 	if (allocation_size <
37ad33b99aSAndrew Jeffery 	    (sizeof(*effecter) - sizeof(effecter->possible_states)) +
38ad33b99aSAndrew Jeffery 		    possible_states_size) {
39ad33b99aSAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
40ad33b99aSAndrew Jeffery 	}
41ad33b99aSAndrew Jeffery 
42ad33b99aSAndrew Jeffery 	// Encode possible states
43ad33b99aSAndrew Jeffery 
4448761c62SAndrew Jeffery 	{
4548761c62SAndrew Jeffery 		char *states_ptr = (char *)possible_states;
4648761c62SAndrew Jeffery 		char *const begin_states_ptr = states_ptr;
4748761c62SAndrew Jeffery 
4848761c62SAndrew Jeffery 		for (int i = 0; i < effecter->composite_effecter_count; ++i) {
4948761c62SAndrew Jeffery 			struct state_effecter_possible_states *states =
5048761c62SAndrew Jeffery 				(struct state_effecter_possible_states *)
5148761c62SAndrew Jeffery 					states_ptr;
5248761c62SAndrew Jeffery 
5348761c62SAndrew Jeffery 			HTOLE16(states->state_set_id);
5448761c62SAndrew Jeffery 
5548761c62SAndrew Jeffery 			states_ptr +=
5648761c62SAndrew Jeffery 				(sizeof(*states) - sizeof(states->states) +
5748761c62SAndrew Jeffery 				 states->possible_states_size);
5848761c62SAndrew Jeffery 		}
5948761c62SAndrew Jeffery 
6048761c62SAndrew Jeffery 		calculated_possible_states_size = states_ptr - begin_states_ptr;
6148761c62SAndrew Jeffery 	}
6248761c62SAndrew Jeffery 
6348761c62SAndrew Jeffery 	// Check lengths
6448761c62SAndrew Jeffery 
6548761c62SAndrew Jeffery 	if (possible_states_size != calculated_possible_states_size) {
6648761c62SAndrew Jeffery 		*actual_size = 0;
6748761c62SAndrew Jeffery 		return PLDM_ERROR;
6848761c62SAndrew Jeffery 	}
6948761c62SAndrew Jeffery 
7048761c62SAndrew Jeffery 	*actual_size =
7148761c62SAndrew Jeffery 		(sizeof(struct pldm_state_effecter_pdr) + possible_states_size -
7248761c62SAndrew Jeffery 		 sizeof(effecter->possible_states));
7348761c62SAndrew Jeffery 
7448761c62SAndrew Jeffery 	// Encode rest of PDR
7548761c62SAndrew Jeffery 
7648761c62SAndrew Jeffery 	effecter->hdr.version = 1;
7748761c62SAndrew Jeffery 	effecter->hdr.type = PLDM_STATE_EFFECTER_PDR;
7848761c62SAndrew Jeffery 	effecter->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
7948761c62SAndrew Jeffery 
8048761c62SAndrew Jeffery 	memcpy(effecter->possible_states, possible_states,
8148761c62SAndrew Jeffery 	       possible_states_size);
8248761c62SAndrew Jeffery 
8348761c62SAndrew Jeffery 	// Convert effecter PDR body
8448761c62SAndrew Jeffery 	HTOLE16(effecter->terminus_handle);
8548761c62SAndrew Jeffery 	HTOLE16(effecter->effecter_id);
8648761c62SAndrew Jeffery 	HTOLE16(effecter->entity_type);
8748761c62SAndrew Jeffery 	HTOLE16(effecter->entity_instance);
8848761c62SAndrew Jeffery 	HTOLE16(effecter->container_id);
8948761c62SAndrew Jeffery 	HTOLE16(effecter->effecter_semantic_id);
9048761c62SAndrew Jeffery 
9148761c62SAndrew Jeffery 	// Convert header
9248761c62SAndrew Jeffery 	HTOLE32(effecter->hdr.record_handle);
9348761c62SAndrew Jeffery 	HTOLE16(effecter->hdr.record_change_num);
9448761c62SAndrew Jeffery 	HTOLE16(effecter->hdr.length);
9548761c62SAndrew Jeffery 
9648761c62SAndrew Jeffery 	return PLDM_SUCCESS;
9748761c62SAndrew Jeffery }
9848761c62SAndrew Jeffery 
9948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_state_sensor_pdr(struct pldm_state_sensor_pdr * const sensor,const size_t allocation_size,const struct state_sensor_possible_states * const possible_states,const size_t possible_states_size,size_t * const actual_size)10048761c62SAndrew Jeffery int encode_state_sensor_pdr(
10148761c62SAndrew Jeffery 	struct pldm_state_sensor_pdr *const sensor,
10248761c62SAndrew Jeffery 	const size_t allocation_size,
10348761c62SAndrew Jeffery 	const struct state_sensor_possible_states *const possible_states,
10448761c62SAndrew Jeffery 	const size_t possible_states_size, size_t *const actual_size)
10548761c62SAndrew Jeffery {
10648761c62SAndrew Jeffery 	size_t calculated_possible_states_size = 0;
10748761c62SAndrew Jeffery 
108bb50a590SAndrew Jeffery 	if (!sensor || !possible_states || !actual_size) {
109bb50a590SAndrew Jeffery 		return PLDM_ERROR;
110bb50a590SAndrew Jeffery 	}
111bb50a590SAndrew Jeffery 
112bb50a590SAndrew Jeffery 	if (SIZE_MAX - (sizeof(*sensor) - sizeof(sensor->possible_states)) <
113bb50a590SAndrew Jeffery 	    possible_states_size) {
114bb50a590SAndrew Jeffery 		return PLDM_ERROR;
115bb50a590SAndrew Jeffery 	}
116bb50a590SAndrew Jeffery 
117bb50a590SAndrew Jeffery 	if (allocation_size <
118bb50a590SAndrew Jeffery 	    (sizeof(*sensor) - sizeof(sensor->possible_states) +
119bb50a590SAndrew Jeffery 	     possible_states_size)) {
120bb50a590SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
121bb50a590SAndrew Jeffery 	}
122bb50a590SAndrew Jeffery 
12348761c62SAndrew Jeffery 	{
124bb50a590SAndrew Jeffery 		// Encode possible states
12548761c62SAndrew Jeffery 		char *states_ptr = (char *)possible_states;
12648761c62SAndrew Jeffery 		char *const begin_states_ptr = states_ptr;
12748761c62SAndrew Jeffery 
12848761c62SAndrew Jeffery 		for (int i = 0; i < sensor->composite_sensor_count; ++i) {
12948761c62SAndrew Jeffery 			struct state_sensor_possible_states *states =
13048761c62SAndrew Jeffery 				(struct state_sensor_possible_states *)
13148761c62SAndrew Jeffery 					states_ptr;
13248761c62SAndrew Jeffery 
13348761c62SAndrew Jeffery 			HTOLE16(states->state_set_id);
13448761c62SAndrew Jeffery 
13548761c62SAndrew Jeffery 			states_ptr +=
13648761c62SAndrew Jeffery 				(sizeof(*states) - sizeof(states->states) +
13748761c62SAndrew Jeffery 				 states->possible_states_size);
13848761c62SAndrew Jeffery 		}
13948761c62SAndrew Jeffery 
14048761c62SAndrew Jeffery 		calculated_possible_states_size = states_ptr - begin_states_ptr;
14148761c62SAndrew Jeffery 	}
14248761c62SAndrew Jeffery 
14348761c62SAndrew Jeffery 	// Check lengths
14448761c62SAndrew Jeffery 
14548761c62SAndrew Jeffery 	if (possible_states_size != calculated_possible_states_size) {
14648761c62SAndrew Jeffery 		*actual_size = 0;
14748761c62SAndrew Jeffery 		return PLDM_ERROR;
14848761c62SAndrew Jeffery 	}
14948761c62SAndrew Jeffery 
15048761c62SAndrew Jeffery 	*actual_size = (sizeof(struct pldm_state_sensor_pdr) +
15148761c62SAndrew Jeffery 			possible_states_size - sizeof(sensor->possible_states));
15248761c62SAndrew Jeffery 
15348761c62SAndrew Jeffery 	// Encode rest of PDR
15448761c62SAndrew Jeffery 
15548761c62SAndrew Jeffery 	sensor->hdr.version = 1;
15648761c62SAndrew Jeffery 	sensor->hdr.type = PLDM_STATE_SENSOR_PDR;
15748761c62SAndrew Jeffery 	sensor->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
15848761c62SAndrew Jeffery 
15948761c62SAndrew Jeffery 	memcpy(sensor->possible_states, possible_states, possible_states_size);
16048761c62SAndrew Jeffery 
16148761c62SAndrew Jeffery 	// Convert sensor PDR body
16248761c62SAndrew Jeffery 	HTOLE16(sensor->terminus_handle);
16348761c62SAndrew Jeffery 	HTOLE16(sensor->sensor_id);
16448761c62SAndrew Jeffery 	HTOLE16(sensor->entity_type);
16548761c62SAndrew Jeffery 	HTOLE16(sensor->entity_instance);
16648761c62SAndrew Jeffery 	HTOLE16(sensor->container_id);
16748761c62SAndrew Jeffery 
16848761c62SAndrew Jeffery 	// Convert header
16948761c62SAndrew Jeffery 	HTOLE32(sensor->hdr.record_handle);
17048761c62SAndrew Jeffery 	HTOLE16(sensor->hdr.record_change_num);
17148761c62SAndrew Jeffery 	HTOLE16(sensor->hdr.length);
17248761c62SAndrew Jeffery 
17348761c62SAndrew Jeffery 	return PLDM_SUCCESS;
17448761c62SAndrew Jeffery }
17548761c62SAndrew Jeffery 
17648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_set_state_effecter_states_resp(uint8_t instance_id,uint8_t completion_code,struct pldm_msg * msg)17748761c62SAndrew Jeffery int encode_set_state_effecter_states_resp(uint8_t instance_id,
17848761c62SAndrew Jeffery 					  uint8_t completion_code,
17948761c62SAndrew Jeffery 					  struct pldm_msg *msg)
18048761c62SAndrew Jeffery {
18148761c62SAndrew Jeffery 	if (msg == NULL) {
18248761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
18348761c62SAndrew Jeffery 	}
18448761c62SAndrew Jeffery 
18548761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
18648761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
18748761c62SAndrew Jeffery 	header.instance = instance_id;
18848761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
18948761c62SAndrew Jeffery 	header.command = PLDM_SET_STATE_EFFECTER_STATES;
19048761c62SAndrew Jeffery 
19148761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
19248761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
19348761c62SAndrew Jeffery 		return rc;
19448761c62SAndrew Jeffery 	}
19548761c62SAndrew Jeffery 
19648761c62SAndrew Jeffery 	msg->payload[0] = completion_code;
19748761c62SAndrew Jeffery 
19848761c62SAndrew Jeffery 	return PLDM_SUCCESS;
19948761c62SAndrew Jeffery }
20048761c62SAndrew Jeffery 
20148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_set_state_effecter_states_req(uint8_t instance_id,uint16_t effecter_id,uint8_t comp_effecter_count,set_effecter_state_field * field,struct pldm_msg * msg)20248761c62SAndrew Jeffery int encode_set_state_effecter_states_req(uint8_t instance_id,
20348761c62SAndrew Jeffery 					 uint16_t effecter_id,
20448761c62SAndrew Jeffery 					 uint8_t comp_effecter_count,
20548761c62SAndrew Jeffery 					 set_effecter_state_field *field,
20648761c62SAndrew Jeffery 					 struct pldm_msg *msg)
20748761c62SAndrew Jeffery {
20848761c62SAndrew Jeffery 	if (msg == NULL) {
20948761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
21048761c62SAndrew Jeffery 	}
21148761c62SAndrew Jeffery 
21248761c62SAndrew Jeffery 	if (comp_effecter_count < 0x1 || comp_effecter_count > 0x8 ||
21348761c62SAndrew Jeffery 	    field == NULL) {
21448761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
21548761c62SAndrew Jeffery 	}
21648761c62SAndrew Jeffery 
21748761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
21848761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
21948761c62SAndrew Jeffery 	header.instance = instance_id;
22048761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
22148761c62SAndrew Jeffery 	header.command = PLDM_SET_STATE_EFFECTER_STATES;
22248761c62SAndrew Jeffery 
22348761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
22448761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
22548761c62SAndrew Jeffery 		return rc;
22648761c62SAndrew Jeffery 	}
22748761c62SAndrew Jeffery 
22848761c62SAndrew Jeffery 	struct pldm_set_state_effecter_states_req *request =
22948761c62SAndrew Jeffery 		(struct pldm_set_state_effecter_states_req *)msg->payload;
23048761c62SAndrew Jeffery 	effecter_id = htole16(effecter_id);
23148761c62SAndrew Jeffery 	request->effecter_id = effecter_id;
23248761c62SAndrew Jeffery 	request->comp_effecter_count = comp_effecter_count;
23348761c62SAndrew Jeffery 	memcpy(request->field, field,
23448761c62SAndrew Jeffery 	       (sizeof(set_effecter_state_field) * comp_effecter_count));
23548761c62SAndrew Jeffery 
23648761c62SAndrew Jeffery 	return PLDM_SUCCESS;
23748761c62SAndrew Jeffery }
23848761c62SAndrew Jeffery 
23948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_set_state_effecter_states_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code)24048761c62SAndrew Jeffery int decode_set_state_effecter_states_resp(const struct pldm_msg *msg,
24148761c62SAndrew Jeffery 					  size_t payload_length,
24248761c62SAndrew Jeffery 					  uint8_t *completion_code)
24348761c62SAndrew Jeffery {
24448761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL) {
24548761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
24648761c62SAndrew Jeffery 	}
24748761c62SAndrew Jeffery 
24848761c62SAndrew Jeffery 	*completion_code = msg->payload[0];
24948761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
25048761c62SAndrew Jeffery 		return PLDM_SUCCESS;
25148761c62SAndrew Jeffery 	}
25248761c62SAndrew Jeffery 
25348761c62SAndrew Jeffery 	if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES) {
25448761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
25548761c62SAndrew Jeffery 	}
25648761c62SAndrew Jeffery 
25748761c62SAndrew Jeffery 	return PLDM_SUCCESS;
25848761c62SAndrew Jeffery }
25948761c62SAndrew Jeffery 
26048761c62SAndrew Jeffery #define PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE 3
26148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_set_state_effecter_states_req(const struct pldm_msg * msg,size_t payload_length,uint16_t * effecter_id,uint8_t * comp_effecter_count,set_effecter_state_field * field)26248761c62SAndrew Jeffery int decode_set_state_effecter_states_req(const struct pldm_msg *msg,
26348761c62SAndrew Jeffery 					 size_t payload_length,
26448761c62SAndrew Jeffery 					 uint16_t *effecter_id,
26548761c62SAndrew Jeffery 					 uint8_t *comp_effecter_count,
26648761c62SAndrew Jeffery 					 set_effecter_state_field *field)
26748761c62SAndrew Jeffery {
26848761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
26948761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
27048761c62SAndrew Jeffery 	int rc;
27148761c62SAndrew Jeffery 	int i;
27248761c62SAndrew Jeffery 
27348761c62SAndrew Jeffery 	if (msg == NULL || effecter_id == NULL || comp_effecter_count == NULL ||
27448761c62SAndrew Jeffery 	    field == NULL) {
27548761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
27648761c62SAndrew Jeffery 	}
27748761c62SAndrew Jeffery 
27848761c62SAndrew Jeffery 	if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) {
27948761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
28048761c62SAndrew Jeffery 	}
28148761c62SAndrew Jeffery 
282830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf,
283830c1eb4SAndrew Jeffery 				    PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE,
28448761c62SAndrew Jeffery 				    msg->payload, payload_length);
28548761c62SAndrew Jeffery 	if (rc) {
286830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
28748761c62SAndrew Jeffery 	}
28848761c62SAndrew Jeffery 
28948761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, effecter_id);
29048761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, comp_effecter_count);
29148761c62SAndrew Jeffery 
29248761c62SAndrew Jeffery 	if (*comp_effecter_count > 8) {
29348761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
29448761c62SAndrew Jeffery 	}
29548761c62SAndrew Jeffery 
29648761c62SAndrew Jeffery 	for (i = 0; i < *comp_effecter_count; i++) {
29748761c62SAndrew Jeffery 		pldm_msgbuf_extract(buf, field[i].set_request);
29848761c62SAndrew Jeffery 		pldm_msgbuf_extract(buf, field[i].effecter_state);
29948761c62SAndrew Jeffery 	}
30048761c62SAndrew Jeffery 
301830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
302830c1eb4SAndrew Jeffery 	if (rc) {
303830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
304830c1eb4SAndrew Jeffery 	}
305830c1eb4SAndrew Jeffery 
306830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
30748761c62SAndrew Jeffery }
30848761c62SAndrew Jeffery 
30948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_get_pdr_req(const struct pldm_msg * msg,size_t payload_length,uint32_t * record_hndl,uint32_t * data_transfer_hndl,uint8_t * transfer_op_flag,uint16_t * request_cnt,uint16_t * record_chg_num)31048761c62SAndrew Jeffery int decode_get_pdr_req(const struct pldm_msg *msg, size_t payload_length,
31148761c62SAndrew Jeffery 		       uint32_t *record_hndl, uint32_t *data_transfer_hndl,
31248761c62SAndrew Jeffery 		       uint8_t *transfer_op_flag, uint16_t *request_cnt,
31348761c62SAndrew Jeffery 		       uint16_t *record_chg_num)
31448761c62SAndrew Jeffery {
31548761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
31648761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
31748761c62SAndrew Jeffery 	int rc;
31848761c62SAndrew Jeffery 
31948761c62SAndrew Jeffery 	if (msg == NULL || record_hndl == NULL || data_transfer_hndl == NULL ||
32048761c62SAndrew Jeffery 	    transfer_op_flag == NULL || request_cnt == NULL ||
32148761c62SAndrew Jeffery 	    record_chg_num == NULL) {
32248761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
32348761c62SAndrew Jeffery 	}
32448761c62SAndrew Jeffery 
32548761c62SAndrew Jeffery 	if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
32648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
32748761c62SAndrew Jeffery 	}
32848761c62SAndrew Jeffery 
329830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_REQ_BYTES, msg->payload,
33048761c62SAndrew Jeffery 				    payload_length);
33148761c62SAndrew Jeffery 	if (rc) {
332830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
33348761c62SAndrew Jeffery 	}
33448761c62SAndrew Jeffery 
33548761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, record_hndl);
33648761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, data_transfer_hndl);
33748761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, transfer_op_flag);
33848761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, request_cnt);
33948761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, record_chg_num);
34048761c62SAndrew Jeffery 
341830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
342830c1eb4SAndrew Jeffery 	if (rc) {
343830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
344830c1eb4SAndrew Jeffery 	}
345830c1eb4SAndrew Jeffery 
346830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
34748761c62SAndrew Jeffery }
34848761c62SAndrew Jeffery 
34936324f6bSAndrew Jeffery LIBPLDM_ABI_DEPRECATED_UNSAFE
encode_get_pdr_resp(uint8_t instance_id,uint8_t completion_code,uint32_t next_record_hndl,uint32_t next_data_transfer_hndl,uint8_t transfer_flag,uint16_t resp_cnt,const uint8_t * record_data,uint8_t transfer_crc,struct pldm_msg * msg)35048761c62SAndrew Jeffery int encode_get_pdr_resp(uint8_t instance_id, uint8_t completion_code,
35148761c62SAndrew Jeffery 			uint32_t next_record_hndl,
35248761c62SAndrew Jeffery 			uint32_t next_data_transfer_hndl, uint8_t transfer_flag,
35348761c62SAndrew Jeffery 			uint16_t resp_cnt, const uint8_t *record_data,
35448761c62SAndrew Jeffery 			uint8_t transfer_crc, struct pldm_msg *msg)
35548761c62SAndrew Jeffery {
35648761c62SAndrew Jeffery 	if (msg == NULL) {
35748761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
35848761c62SAndrew Jeffery 	}
35948761c62SAndrew Jeffery 
36048761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
36148761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
36248761c62SAndrew Jeffery 	header.instance = instance_id;
36348761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
36448761c62SAndrew Jeffery 	header.command = PLDM_GET_PDR;
36548761c62SAndrew Jeffery 
36648761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
36748761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
36848761c62SAndrew Jeffery 		return rc;
36948761c62SAndrew Jeffery 	}
37048761c62SAndrew Jeffery 
37148761c62SAndrew Jeffery 	struct pldm_get_pdr_resp *response =
37248761c62SAndrew Jeffery 		(struct pldm_get_pdr_resp *)msg->payload;
37348761c62SAndrew Jeffery 	response->completion_code = completion_code;
37448761c62SAndrew Jeffery 
37548761c62SAndrew Jeffery 	if (response->completion_code == PLDM_SUCCESS) {
37648761c62SAndrew Jeffery 		response->next_record_handle = htole32(next_record_hndl);
37748761c62SAndrew Jeffery 		response->next_data_transfer_handle =
37848761c62SAndrew Jeffery 			htole32(next_data_transfer_hndl);
37948761c62SAndrew Jeffery 		response->transfer_flag = transfer_flag;
38048761c62SAndrew Jeffery 		response->response_count = htole16(resp_cnt);
38148761c62SAndrew Jeffery 		if (record_data != NULL && resp_cnt > 0) {
38248761c62SAndrew Jeffery 			memcpy(response->record_data, record_data, resp_cnt);
38348761c62SAndrew Jeffery 		}
38448761c62SAndrew Jeffery 		if (transfer_flag == PLDM_END) {
38548761c62SAndrew Jeffery 			uint8_t *dst = msg->payload;
38648761c62SAndrew Jeffery 			dst += (sizeof(struct pldm_get_pdr_resp) - 1) +
38748761c62SAndrew Jeffery 			       resp_cnt;
38848761c62SAndrew Jeffery 			*dst = transfer_crc;
38948761c62SAndrew Jeffery 		}
39048761c62SAndrew Jeffery 	}
39148761c62SAndrew Jeffery 
39248761c62SAndrew Jeffery 	return PLDM_SUCCESS;
39348761c62SAndrew Jeffery }
39448761c62SAndrew Jeffery 
39548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_get_pdr_repository_info_resp(uint8_t instance_id,uint8_t completion_code,uint8_t repository_state,const uint8_t * update_time,const uint8_t * oem_update_time,uint32_t record_count,uint32_t repository_size,uint32_t largest_record_size,uint8_t data_transfer_handle_timeout,struct pldm_msg * msg)39648761c62SAndrew Jeffery int encode_get_pdr_repository_info_resp(
39748761c62SAndrew Jeffery 	uint8_t instance_id, uint8_t completion_code, uint8_t repository_state,
39848761c62SAndrew Jeffery 	const uint8_t *update_time, const uint8_t *oem_update_time,
39948761c62SAndrew Jeffery 	uint32_t record_count, uint32_t repository_size,
40048761c62SAndrew Jeffery 	uint32_t largest_record_size, uint8_t data_transfer_handle_timeout,
40148761c62SAndrew Jeffery 	struct pldm_msg *msg)
40248761c62SAndrew Jeffery {
40348761c62SAndrew Jeffery 	if (msg == NULL) {
40448761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
40548761c62SAndrew Jeffery 	}
40648761c62SAndrew Jeffery 
40748761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
40848761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
40948761c62SAndrew Jeffery 	header.instance = instance_id;
41048761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
41148761c62SAndrew Jeffery 	header.command = PLDM_GET_PDR_REPOSITORY_INFO;
41248761c62SAndrew Jeffery 
41348761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
41448761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
41548761c62SAndrew Jeffery 		return rc;
41648761c62SAndrew Jeffery 	}
41748761c62SAndrew Jeffery 
41848761c62SAndrew Jeffery 	struct pldm_pdr_repository_info_resp *response =
41948761c62SAndrew Jeffery 		(struct pldm_pdr_repository_info_resp *)msg->payload;
42048761c62SAndrew Jeffery 	response->completion_code = completion_code;
42148761c62SAndrew Jeffery 
42248761c62SAndrew Jeffery 	if (response->completion_code == PLDM_SUCCESS) {
42348761c62SAndrew Jeffery 		response->repository_state = repository_state;
42448761c62SAndrew Jeffery 		if (update_time != NULL) {
42548761c62SAndrew Jeffery 			memcpy(response->update_time, update_time,
42648761c62SAndrew Jeffery 			       PLDM_TIMESTAMP104_SIZE);
42748761c62SAndrew Jeffery 		}
42848761c62SAndrew Jeffery 		if (oem_update_time != NULL) {
42948761c62SAndrew Jeffery 			memcpy(response->oem_update_time, oem_update_time,
43048761c62SAndrew Jeffery 			       PLDM_TIMESTAMP104_SIZE);
43148761c62SAndrew Jeffery 		}
43248761c62SAndrew Jeffery 		response->record_count = htole32(record_count);
43348761c62SAndrew Jeffery 		response->repository_size = htole32(repository_size);
43448761c62SAndrew Jeffery 		response->largest_record_size = htole32(largest_record_size);
43548761c62SAndrew Jeffery 		response->data_transfer_handle_timeout =
43648761c62SAndrew Jeffery 			data_transfer_handle_timeout;
43748761c62SAndrew Jeffery 	}
43848761c62SAndrew Jeffery 
43948761c62SAndrew Jeffery 	return PLDM_SUCCESS;
44048761c62SAndrew Jeffery }
44148761c62SAndrew Jeffery 
4420a1be3cbSAndrew Jeffery LIBPLDM_ABI_DEPRECATED
decode_get_pdr_repository_info_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint8_t * repository_state,uint8_t * update_time,uint8_t * oem_update_time,uint32_t * record_count,uint32_t * repository_size,uint32_t * largest_record_size,uint8_t * data_transfer_handle_timeout)44348761c62SAndrew Jeffery int decode_get_pdr_repository_info_resp(
44448761c62SAndrew Jeffery 	const struct pldm_msg *msg, size_t payload_length,
44548761c62SAndrew Jeffery 	uint8_t *completion_code, uint8_t *repository_state,
44648761c62SAndrew Jeffery 	uint8_t *update_time, uint8_t *oem_update_time, uint32_t *record_count,
44748761c62SAndrew Jeffery 	uint32_t *repository_size, uint32_t *largest_record_size,
44848761c62SAndrew Jeffery 	uint8_t *data_transfer_handle_timeout)
44948761c62SAndrew Jeffery {
45048761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
45148761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
45248761c62SAndrew Jeffery 	int rc;
45348761c62SAndrew Jeffery 
45448761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL ||
45548761c62SAndrew Jeffery 	    repository_state == NULL || update_time == NULL ||
45648761c62SAndrew Jeffery 	    oem_update_time == NULL || record_count == NULL ||
45748761c62SAndrew Jeffery 	    repository_size == NULL || largest_record_size == NULL ||
45848761c62SAndrew Jeffery 	    data_transfer_handle_timeout == NULL) {
45948761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
46048761c62SAndrew Jeffery 	}
46148761c62SAndrew Jeffery 
462830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf,
463830c1eb4SAndrew Jeffery 				    PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
46448761c62SAndrew Jeffery 				    msg->payload, payload_length);
46548761c62SAndrew Jeffery 	if (rc) {
466830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
46748761c62SAndrew Jeffery 	}
46848761c62SAndrew Jeffery 
46948761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, completion_code);
47048761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
47148761c62SAndrew Jeffery 		return PLDM_SUCCESS;
47248761c62SAndrew Jeffery 	}
47348761c62SAndrew Jeffery 
474830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, repository_state);
475830c1eb4SAndrew Jeffery 	if (rc) {
476830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
477830c1eb4SAndrew Jeffery 	}
478830c1eb4SAndrew Jeffery 
47948761c62SAndrew Jeffery 	if (*repository_state > PLDM_FAILED) {
48048761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
48148761c62SAndrew Jeffery 	}
48248761c62SAndrew Jeffery 
4830a1be3cbSAndrew Jeffery 	/* NOTE: Memory safety */
4840a1be3cbSAndrew Jeffery 	rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE, update_time,
4850a1be3cbSAndrew Jeffery 				       PLDM_TIMESTAMP104_SIZE);
4860a1be3cbSAndrew Jeffery 	if (rc) {
487830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
4880a1be3cbSAndrew Jeffery 	}
4890a1be3cbSAndrew Jeffery 
4900a1be3cbSAndrew Jeffery 	/* NOTE: Memory safety */
4910a1be3cbSAndrew Jeffery 	rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE,
4920a1be3cbSAndrew Jeffery 				       oem_update_time, PLDM_TIMESTAMP104_SIZE);
4930a1be3cbSAndrew Jeffery 	if (rc) {
494830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
4950a1be3cbSAndrew Jeffery 	}
4960a1be3cbSAndrew Jeffery 
49748761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, record_count);
49848761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, repository_size);
49948761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, largest_record_size);
50048761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, data_transfer_handle_timeout);
50148761c62SAndrew Jeffery 
502830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
503830c1eb4SAndrew Jeffery 	if (rc) {
504830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
505830c1eb4SAndrew Jeffery 	}
506830c1eb4SAndrew Jeffery 
507830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
50848761c62SAndrew Jeffery }
50948761c62SAndrew Jeffery 
5100a1be3cbSAndrew Jeffery LIBPLDM_ABI_TESTING
decode_get_pdr_repository_info_resp_safe(const struct pldm_msg * msg,size_t payload_length,struct pldm_pdr_repository_info_resp * resp)5110a1be3cbSAndrew Jeffery int decode_get_pdr_repository_info_resp_safe(
5120a1be3cbSAndrew Jeffery 	const struct pldm_msg *msg, size_t payload_length,
5130a1be3cbSAndrew Jeffery 	struct pldm_pdr_repository_info_resp *resp)
5140a1be3cbSAndrew Jeffery {
5150a1be3cbSAndrew Jeffery 	struct pldm_msgbuf _buf;
5160a1be3cbSAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
5170a1be3cbSAndrew Jeffery 	int rc;
5180a1be3cbSAndrew Jeffery 
5190a1be3cbSAndrew Jeffery 	if (msg == NULL || resp == NULL) {
5200a1be3cbSAndrew Jeffery 		return -EINVAL;
5210a1be3cbSAndrew Jeffery 	}
5220a1be3cbSAndrew Jeffery 
5230a1be3cbSAndrew Jeffery 	rc = pldm_msg_has_error(msg, payload_length);
5240a1be3cbSAndrew Jeffery 	if (rc) {
5250a1be3cbSAndrew Jeffery 		resp->completion_code = rc;
5260a1be3cbSAndrew Jeffery 		return 0;
5270a1be3cbSAndrew Jeffery 	}
5280a1be3cbSAndrew Jeffery 
5290a1be3cbSAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf,
5300a1be3cbSAndrew Jeffery 				    PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
5310a1be3cbSAndrew Jeffery 				    msg->payload, payload_length);
5320a1be3cbSAndrew Jeffery 	if (rc) {
5330a1be3cbSAndrew Jeffery 		return rc;
5340a1be3cbSAndrew Jeffery 	}
5350a1be3cbSAndrew Jeffery 
5360a1be3cbSAndrew Jeffery 	rc = pldm_msgbuf_extract(buf, resp->completion_code);
5370a1be3cbSAndrew Jeffery 	if (rc) {
5380a1be3cbSAndrew Jeffery 		return rc;
5390a1be3cbSAndrew Jeffery 	}
5400a1be3cbSAndrew Jeffery 
5410a1be3cbSAndrew Jeffery 	pldm_msgbuf_extract(buf, resp->repository_state);
5420a1be3cbSAndrew Jeffery 
5430a1be3cbSAndrew Jeffery 	rc = pldm_msgbuf_extract_array(buf, sizeof(resp->update_time),
5440a1be3cbSAndrew Jeffery 				       resp->update_time,
5450a1be3cbSAndrew Jeffery 				       sizeof(resp->update_time));
5460a1be3cbSAndrew Jeffery 	if (rc) {
5470a1be3cbSAndrew Jeffery 		return rc;
5480a1be3cbSAndrew Jeffery 	}
5490a1be3cbSAndrew Jeffery 
5500a1be3cbSAndrew Jeffery 	rc = pldm_msgbuf_extract_array(buf, sizeof(resp->oem_update_time),
5510a1be3cbSAndrew Jeffery 				       resp->oem_update_time,
5520a1be3cbSAndrew Jeffery 				       sizeof(resp->oem_update_time));
5530a1be3cbSAndrew Jeffery 	if (rc) {
5540a1be3cbSAndrew Jeffery 		return rc;
5550a1be3cbSAndrew Jeffery 	}
5560a1be3cbSAndrew Jeffery 
5570a1be3cbSAndrew Jeffery 	pldm_msgbuf_extract(buf, resp->record_count);
5580a1be3cbSAndrew Jeffery 	pldm_msgbuf_extract(buf, resp->repository_size);
5590a1be3cbSAndrew Jeffery 	pldm_msgbuf_extract(buf, resp->largest_record_size);
5600a1be3cbSAndrew Jeffery 	pldm_msgbuf_extract(buf, resp->data_transfer_handle_timeout);
5610a1be3cbSAndrew Jeffery 
5620a1be3cbSAndrew Jeffery 	return pldm_msgbuf_destroy_consumed(buf);
5630a1be3cbSAndrew Jeffery }
5640a1be3cbSAndrew Jeffery 
56548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_get_pdr_req(uint8_t instance_id,uint32_t record_hndl,uint32_t data_transfer_hndl,uint8_t transfer_op_flag,uint16_t request_cnt,uint16_t record_chg_num,struct pldm_msg * msg,size_t payload_length)56648761c62SAndrew Jeffery int encode_get_pdr_req(uint8_t instance_id, uint32_t record_hndl,
56748761c62SAndrew Jeffery 		       uint32_t data_transfer_hndl, uint8_t transfer_op_flag,
56848761c62SAndrew Jeffery 		       uint16_t request_cnt, uint16_t record_chg_num,
56948761c62SAndrew Jeffery 		       struct pldm_msg *msg, size_t payload_length)
57048761c62SAndrew Jeffery {
57148761c62SAndrew Jeffery 	if (msg == NULL) {
57248761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
57348761c62SAndrew Jeffery 	}
57448761c62SAndrew Jeffery 
57548761c62SAndrew Jeffery 	if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
57648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
57748761c62SAndrew Jeffery 	}
57848761c62SAndrew Jeffery 
57948761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
58048761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
58148761c62SAndrew Jeffery 	header.instance = instance_id;
58248761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
58348761c62SAndrew Jeffery 	header.command = PLDM_GET_PDR;
58448761c62SAndrew Jeffery 
58548761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
58648761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
58748761c62SAndrew Jeffery 		return rc;
58848761c62SAndrew Jeffery 	}
58948761c62SAndrew Jeffery 
59048761c62SAndrew Jeffery 	struct pldm_get_pdr_req *request =
59148761c62SAndrew Jeffery 		(struct pldm_get_pdr_req *)msg->payload;
59248761c62SAndrew Jeffery 	request->record_handle = htole32(record_hndl);
59348761c62SAndrew Jeffery 	request->data_transfer_handle = htole32(data_transfer_hndl);
59448761c62SAndrew Jeffery 	request->transfer_op_flag = transfer_op_flag;
59548761c62SAndrew Jeffery 	request->request_count = htole16(request_cnt);
59648761c62SAndrew Jeffery 	request->record_change_number = htole16(record_chg_num);
59748761c62SAndrew Jeffery 
59848761c62SAndrew Jeffery 	return PLDM_SUCCESS;
59948761c62SAndrew Jeffery }
60048761c62SAndrew Jeffery 
6010a1be3cbSAndrew Jeffery LIBPLDM_ABI_DEPRECATED
decode_get_pdr_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint32_t * next_record_hndl,uint32_t * next_data_transfer_hndl,uint8_t * transfer_flag,uint16_t * resp_cnt,uint8_t * record_data,size_t record_data_length,uint8_t * transfer_crc)60248761c62SAndrew Jeffery int decode_get_pdr_resp(const struct pldm_msg *msg, size_t payload_length,
60348761c62SAndrew Jeffery 			uint8_t *completion_code, uint32_t *next_record_hndl,
60448761c62SAndrew Jeffery 			uint32_t *next_data_transfer_hndl,
60548761c62SAndrew Jeffery 			uint8_t *transfer_flag, uint16_t *resp_cnt,
60648761c62SAndrew Jeffery 			uint8_t *record_data, size_t record_data_length,
60748761c62SAndrew Jeffery 			uint8_t *transfer_crc)
60848761c62SAndrew Jeffery {
60948761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
61048761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
61148761c62SAndrew Jeffery 	int rc;
61248761c62SAndrew Jeffery 
61348761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL ||
61448761c62SAndrew Jeffery 	    next_record_hndl == NULL || next_data_transfer_hndl == NULL ||
61548761c62SAndrew Jeffery 	    transfer_flag == NULL || resp_cnt == NULL || transfer_crc == NULL) {
61648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
61748761c62SAndrew Jeffery 	}
61848761c62SAndrew Jeffery 
619830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES,
620830c1eb4SAndrew Jeffery 				    msg->payload, payload_length);
62148761c62SAndrew Jeffery 	if (rc) {
622830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
62348761c62SAndrew Jeffery 	}
62448761c62SAndrew Jeffery 
625830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, completion_code);
626830c1eb4SAndrew Jeffery 	if (rc) {
627830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
628830c1eb4SAndrew Jeffery 	}
629830c1eb4SAndrew Jeffery 
63048761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
63148761c62SAndrew Jeffery 		return PLDM_SUCCESS;
63248761c62SAndrew Jeffery 	}
63348761c62SAndrew Jeffery 
63448761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, next_record_hndl);
63548761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, next_data_transfer_hndl);
63648761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, transfer_flag);
63748761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, resp_cnt);
63848761c62SAndrew Jeffery 	if (rc) {
639830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
64048761c62SAndrew Jeffery 	}
64148761c62SAndrew Jeffery 
64248761c62SAndrew Jeffery 	if (*resp_cnt > 0 && record_data != NULL) {
64348761c62SAndrew Jeffery 		if (record_data_length < *resp_cnt) {
64448761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
64548761c62SAndrew Jeffery 		}
6460a1be3cbSAndrew Jeffery 		/* NOTE: Memory safety */
6470a1be3cbSAndrew Jeffery 		rc = pldm_msgbuf_extract_array(buf, *resp_cnt, record_data,
6480a1be3cbSAndrew Jeffery 					       *resp_cnt);
6490a1be3cbSAndrew Jeffery 		if (rc) {
650830c1eb4SAndrew Jeffery 			return pldm_xlate_errno(rc);
6510a1be3cbSAndrew Jeffery 		}
65248761c62SAndrew Jeffery 	}
65348761c62SAndrew Jeffery 
65448761c62SAndrew Jeffery 	if (*transfer_flag == PLDM_END) {
65548761c62SAndrew Jeffery 		pldm_msgbuf_extract_p(buf, transfer_crc);
65648761c62SAndrew Jeffery 	}
65748761c62SAndrew Jeffery 
658830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
659830c1eb4SAndrew Jeffery 	if (rc) {
660830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
661830c1eb4SAndrew Jeffery 	}
662830c1eb4SAndrew Jeffery 
663830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
66448761c62SAndrew Jeffery }
66548761c62SAndrew Jeffery 
6660a1be3cbSAndrew Jeffery LIBPLDM_ABI_TESTING
decode_get_pdr_resp_safe(const struct pldm_msg * msg,size_t payload_length,struct pldm_get_pdr_resp * resp,size_t resp_len,uint8_t * transfer_crc)6670a1be3cbSAndrew Jeffery int decode_get_pdr_resp_safe(const struct pldm_msg *msg, size_t payload_length,
6680a1be3cbSAndrew Jeffery 			     struct pldm_get_pdr_resp *resp, size_t resp_len,
6690a1be3cbSAndrew Jeffery 			     uint8_t *transfer_crc)
6700a1be3cbSAndrew Jeffery {
6710a1be3cbSAndrew Jeffery 	struct pldm_msgbuf _buf;
6720a1be3cbSAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
6730a1be3cbSAndrew Jeffery 	int rc;
6740a1be3cbSAndrew Jeffery 
6750a1be3cbSAndrew Jeffery 	if (msg == NULL || resp == NULL || transfer_crc == NULL) {
6760a1be3cbSAndrew Jeffery 		return -EINVAL;
6770a1be3cbSAndrew Jeffery 	}
6780a1be3cbSAndrew Jeffery 
6790a1be3cbSAndrew Jeffery 	rc = pldm_msg_has_error(msg, payload_length);
6800a1be3cbSAndrew Jeffery 	if (rc) {
6810a1be3cbSAndrew Jeffery 		resp->completion_code = rc;
6820a1be3cbSAndrew Jeffery 		return 0;
6830a1be3cbSAndrew Jeffery 	}
6840a1be3cbSAndrew Jeffery 
6850a1be3cbSAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES,
6860a1be3cbSAndrew Jeffery 				    msg->payload, payload_length);
6870a1be3cbSAndrew Jeffery 	if (rc) {
6880a1be3cbSAndrew Jeffery 		return rc;
6890a1be3cbSAndrew Jeffery 	}
6900a1be3cbSAndrew Jeffery 
6910a1be3cbSAndrew Jeffery 	pldm_msgbuf_extract(buf, resp->completion_code);
6920a1be3cbSAndrew Jeffery 	pldm_msgbuf_extract(buf, resp->next_record_handle);
6930a1be3cbSAndrew Jeffery 	pldm_msgbuf_extract(buf, resp->next_data_transfer_handle);
6940a1be3cbSAndrew Jeffery 
6950a1be3cbSAndrew Jeffery 	rc = pldm_msgbuf_extract(buf, resp->transfer_flag);
6960a1be3cbSAndrew Jeffery 	if (rc) {
6970a1be3cbSAndrew Jeffery 		return rc;
6980a1be3cbSAndrew Jeffery 	}
6990a1be3cbSAndrew Jeffery 
7000a1be3cbSAndrew Jeffery 	rc = pldm_msgbuf_extract(buf, resp->response_count);
7010a1be3cbSAndrew Jeffery 	if (rc) {
7020a1be3cbSAndrew Jeffery 		return rc;
7030a1be3cbSAndrew Jeffery 	}
7040a1be3cbSAndrew Jeffery 
7050a1be3cbSAndrew Jeffery 	rc = pldm_msgbuf_extract_array(
7060a1be3cbSAndrew Jeffery 		buf, resp->response_count, resp->record_data,
7070a1be3cbSAndrew Jeffery 		resp_len - (sizeof(*resp) - sizeof(resp->record_data)));
7080a1be3cbSAndrew Jeffery 	if (rc) {
7090a1be3cbSAndrew Jeffery 		return rc;
7100a1be3cbSAndrew Jeffery 	}
7110a1be3cbSAndrew Jeffery 
7120a1be3cbSAndrew Jeffery 	if (resp->transfer_flag == PLDM_END) {
7130a1be3cbSAndrew Jeffery 		pldm_msgbuf_extract_p(buf, transfer_crc);
7140a1be3cbSAndrew Jeffery 	}
7150a1be3cbSAndrew Jeffery 
7160a1be3cbSAndrew Jeffery 	return pldm_msgbuf_destroy_consumed(buf);
7170a1be3cbSAndrew Jeffery }
7180a1be3cbSAndrew Jeffery 
71948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_set_numeric_effecter_value_req(const struct pldm_msg * msg,size_t payload_length,uint16_t * effecter_id,uint8_t * effecter_data_size,uint8_t effecter_value[4])72048761c62SAndrew Jeffery int decode_set_numeric_effecter_value_req(const struct pldm_msg *msg,
72148761c62SAndrew Jeffery 					  size_t payload_length,
72248761c62SAndrew Jeffery 					  uint16_t *effecter_id,
72348761c62SAndrew Jeffery 					  uint8_t *effecter_data_size,
72448761c62SAndrew Jeffery 					  uint8_t effecter_value[4])
72548761c62SAndrew Jeffery {
72648761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
72748761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
72848761c62SAndrew Jeffery 	int rc;
72948761c62SAndrew Jeffery 
73048761c62SAndrew Jeffery 	if (msg == NULL || effecter_id == NULL || effecter_data_size == NULL ||
73148761c62SAndrew Jeffery 	    effecter_value == NULL) {
73248761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
73348761c62SAndrew Jeffery 	}
73448761c62SAndrew Jeffery 
735830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(
736830c1eb4SAndrew Jeffery 		buf, PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES,
73748761c62SAndrew Jeffery 		msg->payload, payload_length);
73848761c62SAndrew Jeffery 	if (rc) {
739830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
74048761c62SAndrew Jeffery 	}
74148761c62SAndrew Jeffery 
74248761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, effecter_id);
74348761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
74448761c62SAndrew Jeffery 	if (rc) {
74548761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
74648761c62SAndrew Jeffery 	}
74748761c62SAndrew Jeffery 
74848761c62SAndrew Jeffery 	if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
74948761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
75048761c62SAndrew Jeffery 	}
75148761c62SAndrew Jeffery 
75248761c62SAndrew Jeffery 	pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
75348761c62SAndrew Jeffery 					   effecter_value);
75448761c62SAndrew Jeffery 
755830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
756830c1eb4SAndrew Jeffery 	if (rc) {
757830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
758830c1eb4SAndrew Jeffery 	}
759830c1eb4SAndrew Jeffery 
760830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
76148761c62SAndrew Jeffery }
76248761c62SAndrew Jeffery 
76348761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_set_numeric_effecter_value_resp(uint8_t instance_id,uint8_t completion_code,struct pldm_msg * msg,size_t payload_length)76448761c62SAndrew Jeffery int encode_set_numeric_effecter_value_resp(uint8_t instance_id,
76548761c62SAndrew Jeffery 					   uint8_t completion_code,
76648761c62SAndrew Jeffery 					   struct pldm_msg *msg,
76748761c62SAndrew Jeffery 					   size_t payload_length)
76848761c62SAndrew Jeffery {
76948761c62SAndrew Jeffery 	if (msg == NULL) {
77048761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
77148761c62SAndrew Jeffery 	}
77248761c62SAndrew Jeffery 
77348761c62SAndrew Jeffery 	if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
77448761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
77548761c62SAndrew Jeffery 	}
77648761c62SAndrew Jeffery 
77748761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
77848761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
77948761c62SAndrew Jeffery 	header.instance = instance_id;
78048761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
78148761c62SAndrew Jeffery 	header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
78248761c62SAndrew Jeffery 
78348761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
78448761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
78548761c62SAndrew Jeffery 		return rc;
78648761c62SAndrew Jeffery 	}
78748761c62SAndrew Jeffery 
78848761c62SAndrew Jeffery 	msg->payload[0] = completion_code;
78948761c62SAndrew Jeffery 
79048761c62SAndrew Jeffery 	return rc;
79148761c62SAndrew Jeffery }
79248761c62SAndrew Jeffery 
79348761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_set_numeric_effecter_value_req(uint8_t instance_id,uint16_t effecter_id,uint8_t effecter_data_size,const uint8_t * effecter_value,struct pldm_msg * msg,size_t payload_length)79448761c62SAndrew Jeffery int encode_set_numeric_effecter_value_req(uint8_t instance_id,
79548761c62SAndrew Jeffery 					  uint16_t effecter_id,
79648761c62SAndrew Jeffery 					  uint8_t effecter_data_size,
79748761c62SAndrew Jeffery 					  const uint8_t *effecter_value,
79848761c62SAndrew Jeffery 					  struct pldm_msg *msg,
79948761c62SAndrew Jeffery 					  size_t payload_length)
80048761c62SAndrew Jeffery {
80148761c62SAndrew Jeffery 	if (msg == NULL || effecter_value == NULL) {
80248761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
80348761c62SAndrew Jeffery 	}
80448761c62SAndrew Jeffery 
80548761c62SAndrew Jeffery 	if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
80648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
80748761c62SAndrew Jeffery 	}
80848761c62SAndrew Jeffery 
80948761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
81048761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
81148761c62SAndrew Jeffery 	header.instance = instance_id;
81248761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
81348761c62SAndrew Jeffery 	header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
81448761c62SAndrew Jeffery 
81548761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
81648761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
81748761c62SAndrew Jeffery 		return rc;
81848761c62SAndrew Jeffery 	}
81948761c62SAndrew Jeffery 
82048761c62SAndrew Jeffery 	struct pldm_set_numeric_effecter_value_req *request =
82148761c62SAndrew Jeffery 		(struct pldm_set_numeric_effecter_value_req *)msg->payload;
82248761c62SAndrew Jeffery 	if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
82348761c62SAndrew Jeffery 	    effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
82448761c62SAndrew Jeffery 		if (payload_length !=
82548761c62SAndrew Jeffery 		    PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) {
82648761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
82748761c62SAndrew Jeffery 		}
82848761c62SAndrew Jeffery 		request->effecter_value[0] = *effecter_value;
82948761c62SAndrew Jeffery 	} else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
83048761c62SAndrew Jeffery 		   effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
83148761c62SAndrew Jeffery 		if (payload_length !=
83248761c62SAndrew Jeffery 		    PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1) {
83348761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
83448761c62SAndrew Jeffery 		}
83548761c62SAndrew Jeffery 
83648761c62SAndrew Jeffery 		uint16_t val = *(uint16_t *)(effecter_value);
83748761c62SAndrew Jeffery 		val = htole16(val);
83848761c62SAndrew Jeffery 		memcpy(request->effecter_value, &val, sizeof(uint16_t));
83948761c62SAndrew Jeffery 
84048761c62SAndrew Jeffery 	} else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
84148761c62SAndrew Jeffery 		   effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
84248761c62SAndrew Jeffery 		if (payload_length !=
84348761c62SAndrew Jeffery 		    PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3) {
84448761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
84548761c62SAndrew Jeffery 		}
84648761c62SAndrew Jeffery 
84748761c62SAndrew Jeffery 		uint32_t val = *(uint32_t *)(effecter_value);
84848761c62SAndrew Jeffery 		val = htole32(val);
84948761c62SAndrew Jeffery 		memcpy(request->effecter_value, &val, sizeof(uint32_t));
85048761c62SAndrew Jeffery 	}
85148761c62SAndrew Jeffery 
85248761c62SAndrew Jeffery 	request->effecter_id = htole16(effecter_id);
85348761c62SAndrew Jeffery 	request->effecter_data_size = effecter_data_size;
85448761c62SAndrew Jeffery 
85548761c62SAndrew Jeffery 	return PLDM_SUCCESS;
85648761c62SAndrew Jeffery }
85748761c62SAndrew Jeffery 
85848761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_set_numeric_effecter_value_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code)85948761c62SAndrew Jeffery int decode_set_numeric_effecter_value_resp(const struct pldm_msg *msg,
86048761c62SAndrew Jeffery 					   size_t payload_length,
86148761c62SAndrew Jeffery 					   uint8_t *completion_code)
86248761c62SAndrew Jeffery {
86348761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL) {
86448761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
86548761c62SAndrew Jeffery 	}
86648761c62SAndrew Jeffery 
86748761c62SAndrew Jeffery 	if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
86848761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
86948761c62SAndrew Jeffery 	}
87048761c62SAndrew Jeffery 
87148761c62SAndrew Jeffery 	*completion_code = msg->payload[0];
87248761c62SAndrew Jeffery 
87348761c62SAndrew Jeffery 	return PLDM_SUCCESS;
87448761c62SAndrew Jeffery }
87548761c62SAndrew Jeffery 
87648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_get_state_sensor_readings_resp(uint8_t instance_id,uint8_t completion_code,uint8_t comp_sensor_count,get_sensor_state_field * field,struct pldm_msg * msg)87748761c62SAndrew Jeffery int encode_get_state_sensor_readings_resp(uint8_t instance_id,
87848761c62SAndrew Jeffery 					  uint8_t completion_code,
87948761c62SAndrew Jeffery 					  uint8_t comp_sensor_count,
88048761c62SAndrew Jeffery 					  get_sensor_state_field *field,
88148761c62SAndrew Jeffery 					  struct pldm_msg *msg)
88248761c62SAndrew Jeffery {
88348761c62SAndrew Jeffery 	if (msg == NULL) {
88448761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
88548761c62SAndrew Jeffery 	}
88648761c62SAndrew Jeffery 
88748761c62SAndrew Jeffery 	if (comp_sensor_count < 0x1 || comp_sensor_count > 0x8) {
88848761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
88948761c62SAndrew Jeffery 	}
89048761c62SAndrew Jeffery 
89148761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
89248761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
89348761c62SAndrew Jeffery 	header.instance = instance_id;
89448761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
89548761c62SAndrew Jeffery 	header.command = PLDM_GET_STATE_SENSOR_READINGS;
89648761c62SAndrew Jeffery 
89748761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
89848761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
89948761c62SAndrew Jeffery 		return rc;
90048761c62SAndrew Jeffery 	}
90148761c62SAndrew Jeffery 
90248761c62SAndrew Jeffery 	struct pldm_get_state_sensor_readings_resp *response =
90348761c62SAndrew Jeffery 		(struct pldm_get_state_sensor_readings_resp *)msg->payload;
90448761c62SAndrew Jeffery 
90548761c62SAndrew Jeffery 	response->completion_code = completion_code;
90648761c62SAndrew Jeffery 	response->comp_sensor_count = comp_sensor_count;
90748761c62SAndrew Jeffery 	memcpy(response->field, field,
90848761c62SAndrew Jeffery 	       (sizeof(get_sensor_state_field) * comp_sensor_count));
90948761c62SAndrew Jeffery 
91048761c62SAndrew Jeffery 	return PLDM_SUCCESS;
91148761c62SAndrew Jeffery }
91248761c62SAndrew Jeffery 
91348761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_get_state_sensor_readings_req(uint8_t instance_id,uint16_t sensor_id,bitfield8_t sensor_rearm,uint8_t reserved,struct pldm_msg * msg)91448761c62SAndrew Jeffery int encode_get_state_sensor_readings_req(uint8_t instance_id,
91548761c62SAndrew Jeffery 					 uint16_t sensor_id,
91648761c62SAndrew Jeffery 					 bitfield8_t sensor_rearm,
91748761c62SAndrew Jeffery 					 uint8_t reserved, struct pldm_msg *msg)
91848761c62SAndrew Jeffery {
91948761c62SAndrew Jeffery 	if (msg == NULL) {
92048761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
92148761c62SAndrew Jeffery 	}
92248761c62SAndrew Jeffery 
92348761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
92448761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
92548761c62SAndrew Jeffery 	header.instance = instance_id;
92648761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
92748761c62SAndrew Jeffery 	header.command = PLDM_GET_STATE_SENSOR_READINGS;
92848761c62SAndrew Jeffery 
92948761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
93048761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
93148761c62SAndrew Jeffery 		return rc;
93248761c62SAndrew Jeffery 	}
93348761c62SAndrew Jeffery 
93448761c62SAndrew Jeffery 	struct pldm_get_state_sensor_readings_req *request =
93548761c62SAndrew Jeffery 		(struct pldm_get_state_sensor_readings_req *)msg->payload;
93648761c62SAndrew Jeffery 
93748761c62SAndrew Jeffery 	request->sensor_id = htole16(sensor_id);
93848761c62SAndrew Jeffery 	request->reserved = reserved;
93948761c62SAndrew Jeffery 	request->sensor_rearm = sensor_rearm;
94048761c62SAndrew Jeffery 
94148761c62SAndrew Jeffery 	return PLDM_SUCCESS;
94248761c62SAndrew Jeffery }
94348761c62SAndrew Jeffery 
94448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_get_state_sensor_readings_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint8_t * comp_sensor_count,get_sensor_state_field * field)94548761c62SAndrew Jeffery int decode_get_state_sensor_readings_resp(const struct pldm_msg *msg,
94648761c62SAndrew Jeffery 					  size_t payload_length,
94748761c62SAndrew Jeffery 					  uint8_t *completion_code,
94848761c62SAndrew Jeffery 					  uint8_t *comp_sensor_count,
94948761c62SAndrew Jeffery 					  get_sensor_state_field *field)
95048761c62SAndrew Jeffery {
95148761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
95248761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
95348761c62SAndrew Jeffery 	uint8_t i;
95448761c62SAndrew Jeffery 	int rc;
95548761c62SAndrew Jeffery 
95648761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL ||
95748761c62SAndrew Jeffery 	    comp_sensor_count == NULL || field == NULL) {
95848761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
95948761c62SAndrew Jeffery 	}
96048761c62SAndrew Jeffery 
961830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(
962830c1eb4SAndrew Jeffery 		buf, PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES,
96348761c62SAndrew Jeffery 		msg->payload, payload_length);
96448761c62SAndrew Jeffery 	if (rc) {
965830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
96648761c62SAndrew Jeffery 	}
96748761c62SAndrew Jeffery 
96848761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, completion_code);
96948761c62SAndrew Jeffery 	if (rc) {
970830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
97148761c62SAndrew Jeffery 	}
97248761c62SAndrew Jeffery 
97348761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
97448761c62SAndrew Jeffery 		return PLDM_SUCCESS;
97548761c62SAndrew Jeffery 	}
97648761c62SAndrew Jeffery 
97748761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, comp_sensor_count);
97848761c62SAndrew Jeffery 	if (rc) {
979830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
98048761c62SAndrew Jeffery 	}
98148761c62SAndrew Jeffery 
98248761c62SAndrew Jeffery 	if (*comp_sensor_count < 0x1 || *comp_sensor_count > 0x8) {
98348761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
98448761c62SAndrew Jeffery 	}
98548761c62SAndrew Jeffery 
98648761c62SAndrew Jeffery 	for (i = 0; i < *comp_sensor_count; i++) {
98748761c62SAndrew Jeffery 		pldm_msgbuf_extract(buf, field[i].sensor_op_state);
98848761c62SAndrew Jeffery 		pldm_msgbuf_extract(buf, field[i].present_state);
98948761c62SAndrew Jeffery 		pldm_msgbuf_extract(buf, field[i].previous_state);
99048761c62SAndrew Jeffery 		pldm_msgbuf_extract(buf, field[i].event_state);
99148761c62SAndrew Jeffery 	}
99248761c62SAndrew Jeffery 
993830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy_consumed(buf);
994830c1eb4SAndrew Jeffery 	if (rc) {
995830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
996830c1eb4SAndrew Jeffery 	}
997830c1eb4SAndrew Jeffery 
998830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
99948761c62SAndrew Jeffery }
100048761c62SAndrew Jeffery 
100148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_get_state_sensor_readings_req(const struct pldm_msg * msg,size_t payload_length,uint16_t * sensor_id,bitfield8_t * sensor_rearm,uint8_t * reserved)100248761c62SAndrew Jeffery int decode_get_state_sensor_readings_req(const struct pldm_msg *msg,
100348761c62SAndrew Jeffery 					 size_t payload_length,
100448761c62SAndrew Jeffery 					 uint16_t *sensor_id,
100548761c62SAndrew Jeffery 					 bitfield8_t *sensor_rearm,
100648761c62SAndrew Jeffery 					 uint8_t *reserved)
100748761c62SAndrew Jeffery {
100848761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
100948761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
101048761c62SAndrew Jeffery 	int rc;
101148761c62SAndrew Jeffery 
101248761c62SAndrew Jeffery 	if (msg == NULL || sensor_id == NULL || sensor_rearm == NULL) {
101348761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
101448761c62SAndrew Jeffery 	}
101548761c62SAndrew Jeffery 
1016830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf,
1017830c1eb4SAndrew Jeffery 				    PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES,
101848761c62SAndrew Jeffery 				    msg->payload, payload_length);
101948761c62SAndrew Jeffery 	if (rc) {
1020830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
102148761c62SAndrew Jeffery 	}
102248761c62SAndrew Jeffery 
102348761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, sensor_id);
102448761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, sensor_rearm->byte);
102548761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, reserved);
102648761c62SAndrew Jeffery 
1027830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
1028830c1eb4SAndrew Jeffery 	if (rc) {
1029830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1030830c1eb4SAndrew Jeffery 	}
1031830c1eb4SAndrew Jeffery 
1032830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
103348761c62SAndrew Jeffery }
103448761c62SAndrew Jeffery 
103548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_sensor_event_data(struct pldm_sensor_event_data * const event_data,const size_t event_data_size,const uint16_t sensor_id,const enum sensor_event_class_states sensor_event_class,const uint8_t sensor_offset,const uint8_t event_state,const uint8_t previous_event_state,size_t * const actual_event_data_size)103648761c62SAndrew Jeffery int encode_sensor_event_data(
103748761c62SAndrew Jeffery 	struct pldm_sensor_event_data *const event_data,
103848761c62SAndrew Jeffery 	const size_t event_data_size, const uint16_t sensor_id,
103948761c62SAndrew Jeffery 	const enum sensor_event_class_states sensor_event_class,
104048761c62SAndrew Jeffery 	const uint8_t sensor_offset, const uint8_t event_state,
104148761c62SAndrew Jeffery 	const uint8_t previous_event_state,
104248761c62SAndrew Jeffery 	size_t *const actual_event_data_size)
104348761c62SAndrew Jeffery {
104448761c62SAndrew Jeffery 	*actual_event_data_size =
104548761c62SAndrew Jeffery 		(sizeof(*event_data) - sizeof(event_data->event_class) +
104648761c62SAndrew Jeffery 		 sizeof(struct pldm_sensor_event_state_sensor_state));
104748761c62SAndrew Jeffery 
104848761c62SAndrew Jeffery 	if (!event_data) {
104948761c62SAndrew Jeffery 		return PLDM_SUCCESS;
105048761c62SAndrew Jeffery 	}
105148761c62SAndrew Jeffery 
105248761c62SAndrew Jeffery 	if (event_data_size < *actual_event_data_size) {
105348761c62SAndrew Jeffery 		*actual_event_data_size = 0;
105448761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
105548761c62SAndrew Jeffery 	}
105648761c62SAndrew Jeffery 
105748761c62SAndrew Jeffery 	event_data->sensor_id = htole16(sensor_id);
105848761c62SAndrew Jeffery 	event_data->sensor_event_class_type = sensor_event_class;
105948761c62SAndrew Jeffery 
106048761c62SAndrew Jeffery 	struct pldm_sensor_event_state_sensor_state *const state_data =
106148761c62SAndrew Jeffery 		(struct pldm_sensor_event_state_sensor_state *)
106248761c62SAndrew Jeffery 			event_data->event_class;
106348761c62SAndrew Jeffery 
106448761c62SAndrew Jeffery 	state_data->sensor_offset = sensor_offset;
106548761c62SAndrew Jeffery 	state_data->event_state = event_state;
106648761c62SAndrew Jeffery 	state_data->previous_event_state = previous_event_state;
106748761c62SAndrew Jeffery 
106848761c62SAndrew Jeffery 	return PLDM_SUCCESS;
106948761c62SAndrew Jeffery }
107048761c62SAndrew Jeffery 
107148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_platform_event_message_req(const struct pldm_msg * msg,size_t payload_length,uint8_t * format_version,uint8_t * tid,uint8_t * event_class,size_t * event_data_offset)107248761c62SAndrew Jeffery int decode_platform_event_message_req(const struct pldm_msg *msg,
107348761c62SAndrew Jeffery 				      size_t payload_length,
107448761c62SAndrew Jeffery 				      uint8_t *format_version, uint8_t *tid,
107548761c62SAndrew Jeffery 				      uint8_t *event_class,
107648761c62SAndrew Jeffery 				      size_t *event_data_offset)
107748761c62SAndrew Jeffery {
107848761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
107948761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
108048761c62SAndrew Jeffery 	int rc;
108148761c62SAndrew Jeffery 
108248761c62SAndrew Jeffery 	if (msg == NULL || format_version == NULL || tid == NULL ||
108348761c62SAndrew Jeffery 	    event_class == NULL || event_data_offset == NULL) {
108448761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
108548761c62SAndrew Jeffery 	}
108648761c62SAndrew Jeffery 
1087830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf,
1088830c1eb4SAndrew Jeffery 				    PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES,
108948761c62SAndrew Jeffery 				    msg->payload, payload_length);
109048761c62SAndrew Jeffery 	if (rc) {
1091830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
109248761c62SAndrew Jeffery 	}
109348761c62SAndrew Jeffery 
109448761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, format_version);
109548761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, tid);
109648761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, event_class);
1097830c1eb4SAndrew Jeffery 
1098830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
1099830c1eb4SAndrew Jeffery 	if (rc) {
1100830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1101830c1eb4SAndrew Jeffery 	}
1102830c1eb4SAndrew Jeffery 
110348761c62SAndrew Jeffery 	*event_data_offset =
110448761c62SAndrew Jeffery 		sizeof(*format_version) + sizeof(*tid) + sizeof(*event_class);
110548761c62SAndrew Jeffery 
1106830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
110748761c62SAndrew Jeffery }
110848761c62SAndrew Jeffery 
pldm_platform_poll_for_platform_event_message_validate(uint8_t transfer_operation_flag,uint16_t event_id_to_acknowledge)1109387b10f6SThu Nguyen static int pldm_platform_poll_for_platform_event_message_validate(
1110387b10f6SThu Nguyen 	uint8_t transfer_operation_flag, uint16_t event_id_to_acknowledge)
1111387b10f6SThu Nguyen {
1112387b10f6SThu Nguyen 	if (((transfer_operation_flag == PLDM_GET_FIRSTPART) &&
1113387b10f6SThu Nguyen 	     (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_NULL)) ||
1114387b10f6SThu Nguyen 	    ((transfer_operation_flag == PLDM_GET_NEXTPART) &&
1115387b10f6SThu Nguyen 	     (event_id_to_acknowledge != PLDM_PLATFORM_EVENT_ID_FRAGMENT)) ||
1116387b10f6SThu Nguyen 	    ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) &&
11179e16b18bSThu Nguyen 	     (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_FRAGMENT)) ||
11189e16b18bSThu Nguyen 	    ((transfer_operation_flag == PLDM_ACKNOWLEDGEMENT_ONLY) &&
11199e16b18bSThu Nguyen 	     (event_id_to_acknowledge == PLDM_PLATFORM_EVENT_ID_NULL)) ||
1120387b10f6SThu Nguyen 	    (transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY)) {
1121387b10f6SThu Nguyen 		return -EPROTO;
1122387b10f6SThu Nguyen 	}
1123387b10f6SThu Nguyen 
1124387b10f6SThu Nguyen 	return 0;
1125387b10f6SThu Nguyen }
1126387b10f6SThu Nguyen 
112748761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_poll_for_platform_event_message_req(const struct pldm_msg * msg,size_t payload_length,uint8_t * format_version,uint8_t * transfer_operation_flag,uint32_t * data_transfer_handle,uint16_t * event_id_to_acknowledge)112848761c62SAndrew Jeffery int decode_poll_for_platform_event_message_req(
112948761c62SAndrew Jeffery 	const struct pldm_msg *msg, size_t payload_length,
113048761c62SAndrew Jeffery 	uint8_t *format_version, uint8_t *transfer_operation_flag,
113148761c62SAndrew Jeffery 	uint32_t *data_transfer_handle, uint16_t *event_id_to_acknowledge)
113248761c62SAndrew Jeffery {
113348761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
113448761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
113548761c62SAndrew Jeffery 	int rc;
113648761c62SAndrew Jeffery 
113790bbe6c0SAndrew Jeffery 	if (msg == NULL || format_version == NULL ||
113890bbe6c0SAndrew Jeffery 	    transfer_operation_flag == NULL || data_transfer_handle == NULL ||
113990bbe6c0SAndrew Jeffery 	    event_id_to_acknowledge == NULL) {
114048761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
114148761c62SAndrew Jeffery 	}
114248761c62SAndrew Jeffery 
1143830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(
1144830c1eb4SAndrew Jeffery 		buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES,
114548761c62SAndrew Jeffery 		msg->payload, payload_length);
114648761c62SAndrew Jeffery 	if (rc) {
1147830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
114848761c62SAndrew Jeffery 	}
114948761c62SAndrew Jeffery 
115048761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, format_version);
115148761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, transfer_operation_flag);
115248761c62SAndrew Jeffery 	if (rc) {
1153830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
115448761c62SAndrew Jeffery 	}
115548761c62SAndrew Jeffery 	if (*transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY) {
115648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
115748761c62SAndrew Jeffery 	}
115848761c62SAndrew Jeffery 
115948761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, data_transfer_handle);
116048761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, event_id_to_acknowledge);
116148761c62SAndrew Jeffery 	if (rc) {
1162830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
116348761c62SAndrew Jeffery 	}
116448761c62SAndrew Jeffery 
1165387b10f6SThu Nguyen 	rc = pldm_platform_poll_for_platform_event_message_validate(
1166387b10f6SThu Nguyen 		*transfer_operation_flag, *event_id_to_acknowledge);
1167387b10f6SThu Nguyen 	if (rc < 0) {
116848761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
116948761c62SAndrew Jeffery 	}
117048761c62SAndrew Jeffery 
1171830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
1172830c1eb4SAndrew Jeffery 	if (rc) {
1173830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1174830c1eb4SAndrew Jeffery 	}
1175830c1eb4SAndrew Jeffery 
1176830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
117748761c62SAndrew Jeffery }
117848761c62SAndrew Jeffery 
117948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_platform_event_message_resp(uint8_t instance_id,uint8_t completion_code,uint8_t platform_event_status,struct pldm_msg * msg)118048761c62SAndrew Jeffery int encode_platform_event_message_resp(uint8_t instance_id,
118148761c62SAndrew Jeffery 				       uint8_t completion_code,
118248761c62SAndrew Jeffery 				       uint8_t platform_event_status,
118348761c62SAndrew Jeffery 				       struct pldm_msg *msg)
118448761c62SAndrew Jeffery {
118548761c62SAndrew Jeffery 	if (msg == NULL) {
118648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
118748761c62SAndrew Jeffery 	}
118848761c62SAndrew Jeffery 
118948761c62SAndrew Jeffery 	if (platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
119048761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
119148761c62SAndrew Jeffery 	}
119248761c62SAndrew Jeffery 
119348761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
119448761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
119548761c62SAndrew Jeffery 	header.instance = instance_id;
119648761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
119748761c62SAndrew Jeffery 	header.command = PLDM_PLATFORM_EVENT_MESSAGE;
119848761c62SAndrew Jeffery 
119948761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
120048761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
120148761c62SAndrew Jeffery 		return rc;
120248761c62SAndrew Jeffery 	}
120348761c62SAndrew Jeffery 
120448761c62SAndrew Jeffery 	struct pldm_platform_event_message_resp *response =
120548761c62SAndrew Jeffery 		(struct pldm_platform_event_message_resp *)msg->payload;
120648761c62SAndrew Jeffery 	response->completion_code = completion_code;
120748761c62SAndrew Jeffery 	response->platform_event_status = platform_event_status;
120848761c62SAndrew Jeffery 
120948761c62SAndrew Jeffery 	return PLDM_SUCCESS;
121048761c62SAndrew Jeffery }
121148761c62SAndrew Jeffery 
121248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_poll_for_platform_event_message_resp(uint8_t instance_id,uint8_t completion_code,uint8_t tid,uint16_t event_id,uint32_t next_data_transfer_handle,uint8_t transfer_flag,uint8_t event_class,uint32_t event_data_size,uint8_t * event_data,uint32_t checksum,struct pldm_msg * msg,size_t payload_length)121348761c62SAndrew Jeffery int encode_poll_for_platform_event_message_resp(
121448761c62SAndrew Jeffery 	uint8_t instance_id, uint8_t completion_code, uint8_t tid,
121548761c62SAndrew Jeffery 	uint16_t event_id, uint32_t next_data_transfer_handle,
121648761c62SAndrew Jeffery 	uint8_t transfer_flag, uint8_t event_class, uint32_t event_data_size,
121748761c62SAndrew Jeffery 	uint8_t *event_data, uint32_t checksum, struct pldm_msg *msg,
121848761c62SAndrew Jeffery 	size_t payload_length)
121948761c62SAndrew Jeffery {
122048761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
122148761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
122248761c62SAndrew Jeffery 	int rc;
122348761c62SAndrew Jeffery 
122448761c62SAndrew Jeffery 	if (!msg) {
122548761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
122648761c62SAndrew Jeffery 	}
122748761c62SAndrew Jeffery 
122848761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
122948761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
123048761c62SAndrew Jeffery 	header.instance = instance_id;
123148761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
123248761c62SAndrew Jeffery 	header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
123348761c62SAndrew Jeffery 
123448761c62SAndrew Jeffery 	rc = pack_pldm_header(&header, &(msg->hdr));
123548761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
123648761c62SAndrew Jeffery 		return rc;
123748761c62SAndrew Jeffery 	}
123848761c62SAndrew Jeffery 
1239830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(
124048761c62SAndrew Jeffery 		buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
124148761c62SAndrew Jeffery 		msg->payload, payload_length);
124248761c62SAndrew Jeffery 	if (rc) {
1243830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
124448761c62SAndrew Jeffery 	}
124548761c62SAndrew Jeffery 
124648761c62SAndrew Jeffery 	pldm_msgbuf_insert(buf, completion_code);
124748761c62SAndrew Jeffery 	pldm_msgbuf_insert(buf, tid);
1248830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_insert(buf, event_id);
1249830c1eb4SAndrew Jeffery 	if (rc) {
1250830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1251830c1eb4SAndrew Jeffery 	}
125248761c62SAndrew Jeffery 
125348761c62SAndrew Jeffery 	if (event_id == 0xffff || event_id == 0x0000) {
125448761c62SAndrew Jeffery 		if (PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES !=
125548761c62SAndrew Jeffery 		    payload_length) {
125648761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
125748761c62SAndrew Jeffery 		}
1258830c1eb4SAndrew Jeffery 
1259830c1eb4SAndrew Jeffery 		rc = pldm_msgbuf_destroy(buf);
1260830c1eb4SAndrew Jeffery 		if (rc) {
1261830c1eb4SAndrew Jeffery 			return pldm_xlate_errno(rc);
1262830c1eb4SAndrew Jeffery 		}
1263830c1eb4SAndrew Jeffery 
1264830c1eb4SAndrew Jeffery 		return PLDM_SUCCESS;
126548761c62SAndrew Jeffery 	}
126648761c62SAndrew Jeffery 
126748761c62SAndrew Jeffery 	if ((event_data == NULL) && (event_data_size > 0)) {
126848761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
126948761c62SAndrew Jeffery 	}
127048761c62SAndrew Jeffery 
127148761c62SAndrew Jeffery 	pldm_msgbuf_insert(buf, next_data_transfer_handle);
127248761c62SAndrew Jeffery 	pldm_msgbuf_insert(buf, transfer_flag);
127348761c62SAndrew Jeffery 	pldm_msgbuf_insert(buf, event_class);
1274830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_insert(buf, event_data_size);
1275830c1eb4SAndrew Jeffery 	if (rc) {
1276830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1277830c1eb4SAndrew Jeffery 	}
127848761c62SAndrew Jeffery 
127948761c62SAndrew Jeffery 	if ((event_data_size > 0) && event_data) {
12800a1be3cbSAndrew Jeffery 		rc = pldm_msgbuf_insert_array(buf, event_data_size, event_data,
12810a1be3cbSAndrew Jeffery 					      event_data_size);
12820a1be3cbSAndrew Jeffery 		if (rc) {
1283830c1eb4SAndrew Jeffery 			return pldm_xlate_errno(rc);
12840a1be3cbSAndrew Jeffery 		}
128548761c62SAndrew Jeffery 	}
128648761c62SAndrew Jeffery 
128748761c62SAndrew Jeffery 	if (transfer_flag == PLDM_END || transfer_flag == PLDM_START_AND_END) {
128848761c62SAndrew Jeffery 		pldm_msgbuf_insert(buf, checksum);
128948761c62SAndrew Jeffery 	}
129048761c62SAndrew Jeffery 
1291830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
1292830c1eb4SAndrew Jeffery 	if (rc) {
1293830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1294830c1eb4SAndrew Jeffery 	}
1295830c1eb4SAndrew Jeffery 
1296830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
129748761c62SAndrew Jeffery }
129848761c62SAndrew Jeffery 
129948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_platform_event_message_req(uint8_t instance_id,uint8_t format_version,uint8_t tid,uint8_t event_class,const uint8_t * event_data,size_t event_data_length,struct pldm_msg * msg,size_t payload_length)130048761c62SAndrew Jeffery int encode_platform_event_message_req(
130148761c62SAndrew Jeffery 	uint8_t instance_id, uint8_t format_version, uint8_t tid,
130248761c62SAndrew Jeffery 	uint8_t event_class, const uint8_t *event_data,
130348761c62SAndrew Jeffery 	size_t event_data_length, struct pldm_msg *msg, size_t payload_length)
130448761c62SAndrew Jeffery 
130548761c62SAndrew Jeffery {
130648761c62SAndrew Jeffery 	if (format_version != 1) {
130748761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
130848761c62SAndrew Jeffery 	}
130948761c62SAndrew Jeffery 
131048761c62SAndrew Jeffery 	if (msg == NULL || event_data == NULL) {
131148761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
131248761c62SAndrew Jeffery 	}
131348761c62SAndrew Jeffery 
131448761c62SAndrew Jeffery 	if (event_data_length == 0) {
131548761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
131648761c62SAndrew Jeffery 	}
131748761c62SAndrew Jeffery 
1318225530abSAndrew Jeffery 	if ((SIZE_MAX - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) <
1319225530abSAndrew Jeffery 	    event_data_length) {
1320225530abSAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
1321225530abSAndrew Jeffery 	}
1322225530abSAndrew Jeffery 
132348761c62SAndrew Jeffery 	if (payload_length !=
132448761c62SAndrew Jeffery 	    PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) {
132548761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
132648761c62SAndrew Jeffery 	}
132748761c62SAndrew Jeffery 
1328b43a7787SJohn Chung 	if (event_class > PLDM_CPER_EVENT &&
132948761c62SAndrew Jeffery 	    !(event_class >= 0xf0 && event_class <= 0xfe)) {
133048761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
133148761c62SAndrew Jeffery 	}
133248761c62SAndrew Jeffery 
133348761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
133448761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
133548761c62SAndrew Jeffery 	header.instance = instance_id;
133648761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
133748761c62SAndrew Jeffery 	header.command = PLDM_PLATFORM_EVENT_MESSAGE;
133848761c62SAndrew Jeffery 
133948761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
134048761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
134148761c62SAndrew Jeffery 		return rc;
134248761c62SAndrew Jeffery 	}
134348761c62SAndrew Jeffery 
134448761c62SAndrew Jeffery 	struct pldm_platform_event_message_req *request =
134548761c62SAndrew Jeffery 		(struct pldm_platform_event_message_req *)msg->payload;
134648761c62SAndrew Jeffery 	request->format_version = format_version;
134748761c62SAndrew Jeffery 	request->tid = tid;
134848761c62SAndrew Jeffery 	request->event_class = event_class;
134948761c62SAndrew Jeffery 	memcpy(request->event_data, event_data, event_data_length);
135048761c62SAndrew Jeffery 
135148761c62SAndrew Jeffery 	return PLDM_SUCCESS;
135248761c62SAndrew Jeffery }
135348761c62SAndrew Jeffery 
135448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_platform_event_message_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint8_t * platform_event_status)135548761c62SAndrew Jeffery int decode_platform_event_message_resp(const struct pldm_msg *msg,
135648761c62SAndrew Jeffery 				       size_t payload_length,
135748761c62SAndrew Jeffery 				       uint8_t *completion_code,
135848761c62SAndrew Jeffery 				       uint8_t *platform_event_status)
135948761c62SAndrew Jeffery {
136048761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
136148761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
136248761c62SAndrew Jeffery 	int rc;
136348761c62SAndrew Jeffery 
136448761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL ||
136548761c62SAndrew Jeffery 	    platform_event_status == NULL) {
136648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
136748761c62SAndrew Jeffery 	}
136848761c62SAndrew Jeffery 
1369830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES,
137048761c62SAndrew Jeffery 				    msg->payload, payload_length);
137148761c62SAndrew Jeffery 	if (rc) {
1372830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
137348761c62SAndrew Jeffery 	}
137448761c62SAndrew Jeffery 
137548761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, completion_code);
137648761c62SAndrew Jeffery 	if (rc) {
1377830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
137848761c62SAndrew Jeffery 	}
137948761c62SAndrew Jeffery 
138048761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
138148761c62SAndrew Jeffery 		return PLDM_SUCCESS;
138248761c62SAndrew Jeffery 	}
138348761c62SAndrew Jeffery 
138448761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, platform_event_status);
138548761c62SAndrew Jeffery 	if (rc) {
1386830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
138748761c62SAndrew Jeffery 	}
138848761c62SAndrew Jeffery 
138948761c62SAndrew Jeffery 	if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
139048761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
139148761c62SAndrew Jeffery 	}
139248761c62SAndrew Jeffery 
1393830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
1394830c1eb4SAndrew Jeffery 	if (rc) {
1395830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1396830c1eb4SAndrew Jeffery 	}
1397830c1eb4SAndrew Jeffery 
1398830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
139948761c62SAndrew Jeffery }
140048761c62SAndrew Jeffery 
140148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_event_message_buffer_size_req(uint8_t instance_id,uint16_t event_receiver_max_buffer_size,struct pldm_msg * msg)140248761c62SAndrew Jeffery int encode_event_message_buffer_size_req(uint8_t instance_id,
140348761c62SAndrew Jeffery 					 uint16_t event_receiver_max_buffer_size,
140448761c62SAndrew Jeffery 					 struct pldm_msg *msg)
140548761c62SAndrew Jeffery {
140648761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
140748761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
140848761c62SAndrew Jeffery 	header.instance = instance_id;
140948761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
141048761c62SAndrew Jeffery 	header.command = PLDM_EVENT_MESSAGE_BUFFER_SIZE;
141148761c62SAndrew Jeffery 
141248761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
141348761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
141448761c62SAndrew Jeffery 		return rc;
141548761c62SAndrew Jeffery 	}
141648761c62SAndrew Jeffery 
141748761c62SAndrew Jeffery 	struct pldm_event_message_buffer_size_req *request =
141848761c62SAndrew Jeffery 		(struct pldm_event_message_buffer_size_req *)msg->payload;
141948761c62SAndrew Jeffery 	request->event_receiver_max_buffer_size =
142048761c62SAndrew Jeffery 		event_receiver_max_buffer_size;
142148761c62SAndrew Jeffery 
142248761c62SAndrew Jeffery 	return PLDM_SUCCESS;
142348761c62SAndrew Jeffery }
142448761c62SAndrew Jeffery 
142548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_event_message_buffer_size_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint16_t * terminus_max_buffer_size)142648761c62SAndrew Jeffery int decode_event_message_buffer_size_resp(const struct pldm_msg *msg,
142748761c62SAndrew Jeffery 					  size_t payload_length,
142848761c62SAndrew Jeffery 					  uint8_t *completion_code,
142948761c62SAndrew Jeffery 					  uint16_t *terminus_max_buffer_size)
143048761c62SAndrew Jeffery {
143148761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
143248761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
143348761c62SAndrew Jeffery 	int rc;
143448761c62SAndrew Jeffery 
143548761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL ||
143648761c62SAndrew Jeffery 	    terminus_max_buffer_size == NULL) {
143748761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
143848761c62SAndrew Jeffery 	}
143948761c62SAndrew Jeffery 
1440830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf,
1441830c1eb4SAndrew Jeffery 				    PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES,
144248761c62SAndrew Jeffery 				    msg->payload, payload_length);
144348761c62SAndrew Jeffery 	if (rc) {
1444830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
144548761c62SAndrew Jeffery 	}
144648761c62SAndrew Jeffery 
144748761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, completion_code);
144848761c62SAndrew Jeffery 	if (rc) {
1449830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
145048761c62SAndrew Jeffery 	}
145148761c62SAndrew Jeffery 
145248761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
145348761c62SAndrew Jeffery 		return PLDM_SUCCESS;
145448761c62SAndrew Jeffery 	}
145548761c62SAndrew Jeffery 
145648761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, terminus_max_buffer_size);
145748761c62SAndrew Jeffery 
1458830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy_consumed(buf);
1459830c1eb4SAndrew Jeffery 	if (rc) {
1460830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1461830c1eb4SAndrew Jeffery 	}
1462830c1eb4SAndrew Jeffery 
1463830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
146448761c62SAndrew Jeffery }
146548761c62SAndrew Jeffery 
146648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_event_message_supported_req(uint8_t instance_id,uint8_t format_version,struct pldm_msg * msg)146748761c62SAndrew Jeffery int encode_event_message_supported_req(uint8_t instance_id,
146848761c62SAndrew Jeffery 				       uint8_t format_version,
146948761c62SAndrew Jeffery 				       struct pldm_msg *msg)
147048761c62SAndrew Jeffery {
147148761c62SAndrew Jeffery 	if (format_version != 1) {
147248761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
147348761c62SAndrew Jeffery 	}
147448761c62SAndrew Jeffery 
147548761c62SAndrew Jeffery 	if (msg == NULL) {
147648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
147748761c62SAndrew Jeffery 	}
147848761c62SAndrew Jeffery 
147948761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
148048761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
148148761c62SAndrew Jeffery 	header.instance = instance_id;
148248761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
148348761c62SAndrew Jeffery 	header.command = PLDM_EVENT_MESSAGE_SUPPORTED;
148448761c62SAndrew Jeffery 
148548761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
148648761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
148748761c62SAndrew Jeffery 		return rc;
148848761c62SAndrew Jeffery 	}
148948761c62SAndrew Jeffery 
149048761c62SAndrew Jeffery 	struct pldm_event_message_supported_req *request =
149148761c62SAndrew Jeffery 		(struct pldm_event_message_supported_req *)msg->payload;
149248761c62SAndrew Jeffery 	request->format_version = format_version;
149348761c62SAndrew Jeffery 
149448761c62SAndrew Jeffery 	return PLDM_SUCCESS;
149548761c62SAndrew Jeffery }
149648761c62SAndrew Jeffery 
149748761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_event_message_supported_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint8_t * synchrony_config,bitfield8_t * synchrony_config_support,uint8_t * number_event_class_returned,uint8_t * event_class,uint8_t event_class_count)149848761c62SAndrew Jeffery int decode_event_message_supported_resp(const struct pldm_msg *msg,
149948761c62SAndrew Jeffery 					size_t payload_length,
150048761c62SAndrew Jeffery 					uint8_t *completion_code,
150148761c62SAndrew Jeffery 					uint8_t *synchrony_config,
150248761c62SAndrew Jeffery 					bitfield8_t *synchrony_config_support,
150348761c62SAndrew Jeffery 					uint8_t *number_event_class_returned,
150448761c62SAndrew Jeffery 					uint8_t *event_class,
150548761c62SAndrew Jeffery 					uint8_t event_class_count)
150648761c62SAndrew Jeffery {
150748761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
150848761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
150948761c62SAndrew Jeffery 	int i;
151048761c62SAndrew Jeffery 	int rc;
151148761c62SAndrew Jeffery 
151248761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL ||
151348761c62SAndrew Jeffery 	    synchrony_config == NULL || synchrony_config_support == NULL ||
151448761c62SAndrew Jeffery 	    number_event_class_returned == NULL || event_class == NULL) {
151548761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
151648761c62SAndrew Jeffery 	}
151748761c62SAndrew Jeffery 
1518830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf,
151948761c62SAndrew Jeffery 				    PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES,
152048761c62SAndrew Jeffery 				    msg->payload, payload_length);
152148761c62SAndrew Jeffery 	if (rc) {
1522830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
152348761c62SAndrew Jeffery 	}
152448761c62SAndrew Jeffery 
152548761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, completion_code);
152648761c62SAndrew Jeffery 	if (rc) {
1527830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
152848761c62SAndrew Jeffery 	}
152948761c62SAndrew Jeffery 
153048761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
153148761c62SAndrew Jeffery 		return PLDM_SUCCESS;
153248761c62SAndrew Jeffery 	}
153348761c62SAndrew Jeffery 
153448761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, synchrony_config);
153548761c62SAndrew Jeffery 	if (rc) {
1536830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
153748761c62SAndrew Jeffery 	}
153848761c62SAndrew Jeffery 
153948761c62SAndrew Jeffery 	if (*synchrony_config > PLDM_MESSAGE_TYPE_ASYNCHRONOUS_WITH_HEARTBEAT) {
154048761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
154148761c62SAndrew Jeffery 	}
154248761c62SAndrew Jeffery 
154348761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, &synchrony_config_support->byte);
154448761c62SAndrew Jeffery 
154548761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, number_event_class_returned);
154648761c62SAndrew Jeffery 	if (rc) {
1547830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
154848761c62SAndrew Jeffery 	}
154948761c62SAndrew Jeffery 
155048761c62SAndrew Jeffery 	if (*number_event_class_returned == 0) {
1551830c1eb4SAndrew Jeffery 		rc = pldm_msgbuf_destroy(buf);
1552830c1eb4SAndrew Jeffery 		if (rc) {
1553830c1eb4SAndrew Jeffery 			return pldm_xlate_errno(rc);
1554830c1eb4SAndrew Jeffery 		}
1555830c1eb4SAndrew Jeffery 
1556830c1eb4SAndrew Jeffery 		return PLDM_SUCCESS;
155748761c62SAndrew Jeffery 	}
155848761c62SAndrew Jeffery 
155948761c62SAndrew Jeffery 	if (event_class_count < *number_event_class_returned) {
156048761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
156148761c62SAndrew Jeffery 	}
156248761c62SAndrew Jeffery 
156348761c62SAndrew Jeffery 	for (i = 0; i < *number_event_class_returned; i++) {
156448761c62SAndrew Jeffery 		pldm_msgbuf_extract(buf, event_class[i]);
156548761c62SAndrew Jeffery 	}
156648761c62SAndrew Jeffery 
1567830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy_consumed(buf);
1568830c1eb4SAndrew Jeffery 	if (rc) {
1569830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1570830c1eb4SAndrew Jeffery 	}
1571830c1eb4SAndrew Jeffery 
1572830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
157348761c62SAndrew Jeffery }
157448761c62SAndrew Jeffery 
157548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_sensor_event_data(const uint8_t * event_data,size_t event_data_length,uint16_t * sensor_id,uint8_t * sensor_event_class_type,size_t * event_class_data_offset)157648761c62SAndrew Jeffery int decode_sensor_event_data(const uint8_t *event_data,
157748761c62SAndrew Jeffery 			     size_t event_data_length, uint16_t *sensor_id,
157848761c62SAndrew Jeffery 			     uint8_t *sensor_event_class_type,
157948761c62SAndrew Jeffery 			     size_t *event_class_data_offset)
158048761c62SAndrew Jeffery {
158148761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
158248761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
158348761c62SAndrew Jeffery 	int rc;
158448761c62SAndrew Jeffery 
158590bbe6c0SAndrew Jeffery 	if (event_data == NULL || sensor_id == NULL ||
158690bbe6c0SAndrew Jeffery 	    sensor_event_class_type == NULL ||
158790bbe6c0SAndrew Jeffery 	    event_class_data_offset == NULL) {
158890bbe6c0SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
158990bbe6c0SAndrew Jeffery 	}
159090bbe6c0SAndrew Jeffery 
1591830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf, PLDM_SENSOR_EVENT_DATA_MIN_LENGTH,
159248761c62SAndrew Jeffery 				    event_data, event_data_length);
159348761c62SAndrew Jeffery 	if (rc) {
1594830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1595830c1eb4SAndrew Jeffery 	}
1596830c1eb4SAndrew Jeffery 
1597830c1eb4SAndrew Jeffery 	if (event_data_length < PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) {
1598830c1eb4SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
159948761c62SAndrew Jeffery 	}
160048761c62SAndrew Jeffery 
160148761c62SAndrew Jeffery 	size_t event_class_data_length =
160248761c62SAndrew Jeffery 		event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES;
160348761c62SAndrew Jeffery 
160448761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, sensor_id);
160548761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, sensor_event_class_type);
160648761c62SAndrew Jeffery 	if (rc) {
1607830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
160848761c62SAndrew Jeffery 	}
160948761c62SAndrew Jeffery 
161048761c62SAndrew Jeffery 	if (*sensor_event_class_type == PLDM_SENSOR_OP_STATE) {
161148761c62SAndrew Jeffery 		if (event_class_data_length !=
161248761c62SAndrew Jeffery 		    PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
161348761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
161448761c62SAndrew Jeffery 		}
161548761c62SAndrew Jeffery 	} else if (*sensor_event_class_type == PLDM_STATE_SENSOR_STATE) {
161648761c62SAndrew Jeffery 		if (event_class_data_length !=
161748761c62SAndrew Jeffery 		    PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
161848761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
161948761c62SAndrew Jeffery 		}
162048761c62SAndrew Jeffery 	} else if (*sensor_event_class_type == PLDM_NUMERIC_SENSOR_STATE) {
162148761c62SAndrew Jeffery 		if (event_class_data_length <
162248761c62SAndrew Jeffery 			    PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
162348761c62SAndrew Jeffery 		    event_class_data_length >
162448761c62SAndrew Jeffery 			    PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
162548761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
162648761c62SAndrew Jeffery 		}
162748761c62SAndrew Jeffery 	} else {
162848761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
162948761c62SAndrew Jeffery 	}
163048761c62SAndrew Jeffery 
163148761c62SAndrew Jeffery 	*event_class_data_offset =
163248761c62SAndrew Jeffery 		sizeof(*sensor_id) + sizeof(*sensor_event_class_type);
163348761c62SAndrew Jeffery 
1634830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
1635830c1eb4SAndrew Jeffery 	if (rc) {
1636830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1637830c1eb4SAndrew Jeffery 	}
1638830c1eb4SAndrew Jeffery 
1639830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
164048761c62SAndrew Jeffery }
164148761c62SAndrew Jeffery 
164248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_sensor_op_data(const uint8_t * sensor_data,size_t sensor_data_length,uint8_t * present_op_state,uint8_t * previous_op_state)164348761c62SAndrew Jeffery int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length,
164448761c62SAndrew Jeffery 			  uint8_t *present_op_state, uint8_t *previous_op_state)
164548761c62SAndrew Jeffery {
164648761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
164748761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
164848761c62SAndrew Jeffery 	int rc;
164948761c62SAndrew Jeffery 
165090bbe6c0SAndrew Jeffery 	if (sensor_data == NULL || present_op_state == NULL ||
165190bbe6c0SAndrew Jeffery 	    previous_op_state == NULL) {
165248761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
165348761c62SAndrew Jeffery 	}
165448761c62SAndrew Jeffery 
1655830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(
1656830c1eb4SAndrew Jeffery 		buf, PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH, sensor_data,
1657830c1eb4SAndrew Jeffery 		sensor_data_length);
165848761c62SAndrew Jeffery 	if (rc) {
1659830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
166048761c62SAndrew Jeffery 	}
166148761c62SAndrew Jeffery 
166248761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, present_op_state);
166348761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, previous_op_state);
166448761c62SAndrew Jeffery 
1665830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy_consumed(buf);
1666830c1eb4SAndrew Jeffery 	if (rc) {
1667830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1668830c1eb4SAndrew Jeffery 	}
1669830c1eb4SAndrew Jeffery 
1670830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
167148761c62SAndrew Jeffery }
167248761c62SAndrew Jeffery 
167348761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_state_sensor_data(const uint8_t * sensor_data,size_t sensor_data_length,uint8_t * sensor_offset,uint8_t * event_state,uint8_t * previous_event_state)167448761c62SAndrew Jeffery int decode_state_sensor_data(const uint8_t *sensor_data,
167548761c62SAndrew Jeffery 			     size_t sensor_data_length, uint8_t *sensor_offset,
167648761c62SAndrew Jeffery 			     uint8_t *event_state,
167748761c62SAndrew Jeffery 			     uint8_t *previous_event_state)
167848761c62SAndrew Jeffery {
167948761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
168048761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
168148761c62SAndrew Jeffery 	int rc;
168248761c62SAndrew Jeffery 
168390bbe6c0SAndrew Jeffery 	if (sensor_data == NULL || sensor_offset == NULL ||
168490bbe6c0SAndrew Jeffery 	    event_state == NULL || previous_event_state == NULL) {
168548761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
168648761c62SAndrew Jeffery 	}
168748761c62SAndrew Jeffery 
1688830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(
168948761c62SAndrew Jeffery 		buf, PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH,
169048761c62SAndrew Jeffery 		sensor_data, sensor_data_length);
169148761c62SAndrew Jeffery 	if (rc) {
1692830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
169348761c62SAndrew Jeffery 	}
169448761c62SAndrew Jeffery 
169548761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, sensor_offset);
169648761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, event_state);
169748761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, previous_event_state);
169848761c62SAndrew Jeffery 
1699830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy_consumed(buf);
1700830c1eb4SAndrew Jeffery 	if (rc) {
1701830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1702830c1eb4SAndrew Jeffery 	}
1703830c1eb4SAndrew Jeffery 
1704830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
170548761c62SAndrew Jeffery }
170648761c62SAndrew Jeffery 
170748761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_numeric_sensor_data(const uint8_t * sensor_data,size_t sensor_data_length,uint8_t * event_state,uint8_t * previous_event_state,uint8_t * sensor_data_size,uint32_t * present_reading)170848761c62SAndrew Jeffery int decode_numeric_sensor_data(const uint8_t *sensor_data,
170948761c62SAndrew Jeffery 			       size_t sensor_data_length, uint8_t *event_state,
171048761c62SAndrew Jeffery 			       uint8_t *previous_event_state,
171148761c62SAndrew Jeffery 			       uint8_t *sensor_data_size,
171248761c62SAndrew Jeffery 			       uint32_t *present_reading)
171348761c62SAndrew Jeffery {
171448761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
171548761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
171648761c62SAndrew Jeffery 	int rc;
171748761c62SAndrew Jeffery 
171890bbe6c0SAndrew Jeffery 	if (sensor_data == NULL || sensor_data_size == NULL ||
171990bbe6c0SAndrew Jeffery 	    event_state == NULL || previous_event_state == NULL ||
172090bbe6c0SAndrew Jeffery 	    present_reading == NULL) {
172148761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
172248761c62SAndrew Jeffery 	}
172348761c62SAndrew Jeffery 
172448761c62SAndrew Jeffery 	if (sensor_data_length >
172548761c62SAndrew Jeffery 	    PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
172648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
172748761c62SAndrew Jeffery 	}
172848761c62SAndrew Jeffery 
1729830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(
173048761c62SAndrew Jeffery 		buf, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH,
173148761c62SAndrew Jeffery 		sensor_data, sensor_data_length);
173248761c62SAndrew Jeffery 	if (rc) {
1733830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
173448761c62SAndrew Jeffery 	}
173548761c62SAndrew Jeffery 
173648761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, event_state);
173748761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, previous_event_state);
173848761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
173948761c62SAndrew Jeffery 	if (rc) {
1740830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
174148761c62SAndrew Jeffery 	}
174248761c62SAndrew Jeffery 
174348761c62SAndrew Jeffery 	/*
174448761c62SAndrew Jeffery 	 * The implementation below is bonkers, but it's because the function
174548761c62SAndrew Jeffery 	 * prototype is bonkers. The `present_reading` argument should have been
174648761c62SAndrew Jeffery 	 * a tagged union.
174748761c62SAndrew Jeffery 	 */
174848761c62SAndrew Jeffery 	switch (*sensor_data_size) {
174948761c62SAndrew Jeffery 	case PLDM_SENSOR_DATA_SIZE_UINT8: {
175048761c62SAndrew Jeffery 		uint8_t val;
175148761c62SAndrew Jeffery 		if (!pldm_msgbuf_extract(buf, val)) {
175248761c62SAndrew Jeffery 			*present_reading = (uint32_t)val;
175348761c62SAndrew Jeffery 		}
175448761c62SAndrew Jeffery 		break;
175548761c62SAndrew Jeffery 	}
175648761c62SAndrew Jeffery 	case PLDM_SENSOR_DATA_SIZE_SINT8: {
175748761c62SAndrew Jeffery 		int8_t val;
175848761c62SAndrew Jeffery 		if (!pldm_msgbuf_extract(buf, val)) {
175948761c62SAndrew Jeffery 			*present_reading = (uint32_t)(int32_t)val;
176048761c62SAndrew Jeffery 		}
176148761c62SAndrew Jeffery 		break;
176248761c62SAndrew Jeffery 	}
176348761c62SAndrew Jeffery 	case PLDM_SENSOR_DATA_SIZE_UINT16: {
176448761c62SAndrew Jeffery 		uint16_t val;
176548761c62SAndrew Jeffery 		if (!pldm_msgbuf_extract(buf, val)) {
176648761c62SAndrew Jeffery 			*present_reading = (uint32_t)val;
176748761c62SAndrew Jeffery 		}
176848761c62SAndrew Jeffery 		break;
176948761c62SAndrew Jeffery 	}
177048761c62SAndrew Jeffery 	case PLDM_SENSOR_DATA_SIZE_SINT16: {
177148761c62SAndrew Jeffery 		int16_t val;
177248761c62SAndrew Jeffery 		if (!pldm_msgbuf_extract(buf, val)) {
177348761c62SAndrew Jeffery 			*present_reading = (uint32_t)(int32_t)val;
177448761c62SAndrew Jeffery 		}
177548761c62SAndrew Jeffery 		break;
177648761c62SAndrew Jeffery 	}
177748761c62SAndrew Jeffery 	case PLDM_SENSOR_DATA_SIZE_UINT32: {
177848761c62SAndrew Jeffery 		uint32_t val;
177948761c62SAndrew Jeffery 		if (!pldm_msgbuf_extract(buf, val)) {
178048761c62SAndrew Jeffery 			*present_reading = (uint32_t)val;
178148761c62SAndrew Jeffery 		}
178248761c62SAndrew Jeffery 		break;
178348761c62SAndrew Jeffery 	}
178448761c62SAndrew Jeffery 	case PLDM_SENSOR_DATA_SIZE_SINT32: {
178548761c62SAndrew Jeffery 		int32_t val;
178648761c62SAndrew Jeffery 		if (!pldm_msgbuf_extract(buf, val)) {
178748761c62SAndrew Jeffery 			*present_reading = (uint32_t)val;
178848761c62SAndrew Jeffery 		}
178948761c62SAndrew Jeffery 		break;
179048761c62SAndrew Jeffery 	}
179148761c62SAndrew Jeffery 	default:
179248761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
179348761c62SAndrew Jeffery 	}
179448761c62SAndrew Jeffery 
1795830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy_consumed(buf);
1796830c1eb4SAndrew Jeffery 	if (rc) {
1797830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1798830c1eb4SAndrew Jeffery 	}
1799830c1eb4SAndrew Jeffery 
1800830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
180148761c62SAndrew Jeffery }
180248761c62SAndrew Jeffery 
180348761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_numeric_sensor_pdr_data(const void * pdr_data,size_t pdr_data_length,struct pldm_numeric_sensor_value_pdr * pdr_value)180448761c62SAndrew Jeffery int decode_numeric_sensor_pdr_data(
180548761c62SAndrew Jeffery 	const void *pdr_data, size_t pdr_data_length,
180648761c62SAndrew Jeffery 	struct pldm_numeric_sensor_value_pdr *pdr_value)
180748761c62SAndrew Jeffery {
180848761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
180948761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
181048761c62SAndrew Jeffery 	int rc;
181148761c62SAndrew Jeffery 
1812830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
181348761c62SAndrew Jeffery 				    pdr_data, pdr_data_length);
181448761c62SAndrew Jeffery 	if (rc) {
1815830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
181648761c62SAndrew Jeffery 	}
181748761c62SAndrew Jeffery 
1818329176a8SAndrew Jeffery 	rc = pldm_msgbuf_extract_value_pdr_hdr(
1819329176a8SAndrew Jeffery 		buf, &pdr_value->hdr, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
182048761c62SAndrew Jeffery 		pdr_data_length);
182148761c62SAndrew Jeffery 	if (rc) {
1822329176a8SAndrew Jeffery 		return pldm_xlate_errno(rc);
182348761c62SAndrew Jeffery 	}
182448761c62SAndrew Jeffery 
182548761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
182648761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->sensor_id);
182748761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->entity_type);
182848761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->entity_instance_num);
182948761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->container_id);
183048761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->sensor_init);
183148761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->sensor_auxiliary_names_pdr);
183248761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->base_unit);
183348761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->unit_modifier);
183448761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->rate_unit);
183548761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle);
183648761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->aux_unit);
183748761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier);
183848761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit);
183948761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->rel);
184048761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle);
184148761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->is_linear);
184248761c62SAndrew Jeffery 
184348761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract(buf, pdr_value->sensor_data_size);
184448761c62SAndrew Jeffery 	if (rc) {
1845830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
184648761c62SAndrew Jeffery 	}
184748761c62SAndrew Jeffery 	if (pdr_value->sensor_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
184848761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
184948761c62SAndrew Jeffery 	}
185048761c62SAndrew Jeffery 
185148761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->resolution);
185248761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->offset);
185348761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->accuracy);
185448761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->plus_tolerance);
185548761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->minus_tolerance);
185648761c62SAndrew Jeffery 	pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
185748761c62SAndrew Jeffery 					&pdr_value->hysteresis);
185848761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->supported_thresholds.byte);
185948761c62SAndrew Jeffery 	pldm_msgbuf_extract(
186048761c62SAndrew Jeffery 		buf, pdr_value->threshold_and_hysteresis_volatility.byte);
186148761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->state_transition_interval);
186248761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->update_interval);
186348761c62SAndrew Jeffery 	pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
186448761c62SAndrew Jeffery 					&pdr_value->max_readable);
186548761c62SAndrew Jeffery 	pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
186648761c62SAndrew Jeffery 					&pdr_value->min_readable);
186748761c62SAndrew Jeffery 
186848761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
186948761c62SAndrew Jeffery 	if (rc) {
1870830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
187148761c62SAndrew Jeffery 	}
187248761c62SAndrew Jeffery 	if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
187348761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
187448761c62SAndrew Jeffery 	}
187548761c62SAndrew Jeffery 
187648761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
187748761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
187848761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->nominal_value);
187948761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
188048761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->normal_max);
188148761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
188248761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->normal_min);
188348761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
188448761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->warning_high);
188548761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
188648761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->warning_low);
188748761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
188848761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->critical_high);
188948761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
189048761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->critical_low);
189148761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
189248761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->fatal_high);
189348761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
189448761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->fatal_low);
189548761c62SAndrew Jeffery 
1896830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
1897830c1eb4SAndrew Jeffery 	if (rc) {
1898830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
1899830c1eb4SAndrew Jeffery 	}
1900830c1eb4SAndrew Jeffery 
1901830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
190248761c62SAndrew Jeffery }
190348761c62SAndrew Jeffery 
190448761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_get_numeric_effecter_value_req(uint8_t instance_id,uint16_t effecter_id,struct pldm_msg * msg)190548761c62SAndrew Jeffery int encode_get_numeric_effecter_value_req(uint8_t instance_id,
190648761c62SAndrew Jeffery 					  uint16_t effecter_id,
190748761c62SAndrew Jeffery 					  struct pldm_msg *msg)
190848761c62SAndrew Jeffery {
190948761c62SAndrew Jeffery 	if (msg == NULL) {
191048761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
191148761c62SAndrew Jeffery 	}
191248761c62SAndrew Jeffery 
191348761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
191448761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
191548761c62SAndrew Jeffery 	header.instance = instance_id;
191648761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
191748761c62SAndrew Jeffery 	header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
191848761c62SAndrew Jeffery 
191948761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
192048761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
192148761c62SAndrew Jeffery 		return rc;
192248761c62SAndrew Jeffery 	}
192348761c62SAndrew Jeffery 
192448761c62SAndrew Jeffery 	struct pldm_get_numeric_effecter_value_req *request =
192548761c62SAndrew Jeffery 		(struct pldm_get_numeric_effecter_value_req *)msg->payload;
192648761c62SAndrew Jeffery 	request->effecter_id = htole16(effecter_id);
192748761c62SAndrew Jeffery 
192848761c62SAndrew Jeffery 	return PLDM_SUCCESS;
192948761c62SAndrew Jeffery }
193048761c62SAndrew Jeffery 
193148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_get_numeric_effecter_value_resp(uint8_t instance_id,uint8_t completion_code,uint8_t effecter_data_size,uint8_t effecter_oper_state,const uint8_t * pending_value,const uint8_t * present_value,struct pldm_msg * msg,size_t payload_length)193248761c62SAndrew Jeffery int encode_get_numeric_effecter_value_resp(
193348761c62SAndrew Jeffery 	uint8_t instance_id, uint8_t completion_code,
193448761c62SAndrew Jeffery 	uint8_t effecter_data_size, uint8_t effecter_oper_state,
193548761c62SAndrew Jeffery 	const uint8_t *pending_value, const uint8_t *present_value,
193648761c62SAndrew Jeffery 	struct pldm_msg *msg, size_t payload_length)
193748761c62SAndrew Jeffery {
193848761c62SAndrew Jeffery 	if (msg == NULL || pending_value == NULL || present_value == NULL) {
193948761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
194048761c62SAndrew Jeffery 	}
194148761c62SAndrew Jeffery 
194248761c62SAndrew Jeffery 	if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
194348761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
194448761c62SAndrew Jeffery 	}
194548761c62SAndrew Jeffery 
194648761c62SAndrew Jeffery 	if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
194748761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
194848761c62SAndrew Jeffery 	}
194948761c62SAndrew Jeffery 
195048761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
195148761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
195248761c62SAndrew Jeffery 	header.instance = instance_id;
195348761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
195448761c62SAndrew Jeffery 	header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
195548761c62SAndrew Jeffery 
195648761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
195748761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
195848761c62SAndrew Jeffery 		return rc;
195948761c62SAndrew Jeffery 	}
196048761c62SAndrew Jeffery 
196148761c62SAndrew Jeffery 	struct pldm_get_numeric_effecter_value_resp *response =
196248761c62SAndrew Jeffery 		(struct pldm_get_numeric_effecter_value_resp *)msg->payload;
196348761c62SAndrew Jeffery 
196448761c62SAndrew Jeffery 	response->completion_code = completion_code;
196548761c62SAndrew Jeffery 	response->effecter_data_size = effecter_data_size;
196648761c62SAndrew Jeffery 	response->effecter_oper_state = effecter_oper_state;
196748761c62SAndrew Jeffery 
196848761c62SAndrew Jeffery 	if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
196948761c62SAndrew Jeffery 	    effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
197048761c62SAndrew Jeffery 		if (payload_length !=
197148761c62SAndrew Jeffery 		    PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
197248761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
197348761c62SAndrew Jeffery 		}
197448761c62SAndrew Jeffery 		response->pending_and_present_values[0] = *pending_value;
197548761c62SAndrew Jeffery 		response->pending_and_present_values[1] = *present_value;
197648761c62SAndrew Jeffery 
197748761c62SAndrew Jeffery 	} else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
197848761c62SAndrew Jeffery 		   effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
197948761c62SAndrew Jeffery 		if (payload_length !=
198048761c62SAndrew Jeffery 		    PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
198148761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
198248761c62SAndrew Jeffery 		}
198348761c62SAndrew Jeffery 		uint16_t val_pending = *(uint16_t *)pending_value;
198448761c62SAndrew Jeffery 		val_pending = htole16(val_pending);
198548761c62SAndrew Jeffery 		memcpy(response->pending_and_present_values, &val_pending,
198648761c62SAndrew Jeffery 		       sizeof(uint16_t));
198748761c62SAndrew Jeffery 		uint16_t val_present = *(uint16_t *)present_value;
198848761c62SAndrew Jeffery 		val_present = htole16(val_present);
198948761c62SAndrew Jeffery 		memcpy((response->pending_and_present_values +
199048761c62SAndrew Jeffery 			sizeof(uint16_t)),
199148761c62SAndrew Jeffery 		       &val_present, sizeof(uint16_t));
199248761c62SAndrew Jeffery 
199348761c62SAndrew Jeffery 	} else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
199448761c62SAndrew Jeffery 		   effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
199548761c62SAndrew Jeffery 		if (payload_length !=
199648761c62SAndrew Jeffery 		    PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
199748761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
199848761c62SAndrew Jeffery 		}
199948761c62SAndrew Jeffery 		uint32_t val_pending = *(uint32_t *)pending_value;
200048761c62SAndrew Jeffery 		val_pending = htole32(val_pending);
200148761c62SAndrew Jeffery 		memcpy(response->pending_and_present_values, &val_pending,
200248761c62SAndrew Jeffery 		       sizeof(uint32_t));
200348761c62SAndrew Jeffery 		uint32_t val_present = *(uint32_t *)present_value;
200448761c62SAndrew Jeffery 		val_present = htole32(val_present);
200548761c62SAndrew Jeffery 		memcpy((response->pending_and_present_values +
200648761c62SAndrew Jeffery 			sizeof(uint32_t)),
200748761c62SAndrew Jeffery 		       &val_present, sizeof(uint32_t));
200848761c62SAndrew Jeffery 	}
200948761c62SAndrew Jeffery 	return PLDM_SUCCESS;
201048761c62SAndrew Jeffery }
201148761c62SAndrew Jeffery 
201248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_get_numeric_effecter_value_req(const struct pldm_msg * msg,size_t payload_length,uint16_t * effecter_id)201348761c62SAndrew Jeffery int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg,
201448761c62SAndrew Jeffery 					  size_t payload_length,
201548761c62SAndrew Jeffery 					  uint16_t *effecter_id)
201648761c62SAndrew Jeffery {
201748761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
201848761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
201948761c62SAndrew Jeffery 	int rc;
202048761c62SAndrew Jeffery 
202148761c62SAndrew Jeffery 	if (msg == NULL || effecter_id == NULL) {
202248761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
202348761c62SAndrew Jeffery 	}
202448761c62SAndrew Jeffery 
2025830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf,
2026830c1eb4SAndrew Jeffery 				    PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES,
202748761c62SAndrew Jeffery 				    msg->payload, payload_length);
202848761c62SAndrew Jeffery 	if (rc) {
2029830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
203048761c62SAndrew Jeffery 	}
203148761c62SAndrew Jeffery 
203248761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, effecter_id);
203348761c62SAndrew Jeffery 
2034830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy_consumed(buf);
2035830c1eb4SAndrew Jeffery 	if (rc) {
2036830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
2037830c1eb4SAndrew Jeffery 	}
2038830c1eb4SAndrew Jeffery 
2039830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
204048761c62SAndrew Jeffery }
204148761c62SAndrew Jeffery 
204248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_get_numeric_effecter_value_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint8_t * effecter_data_size,uint8_t * effecter_oper_state,uint8_t * pending_value,uint8_t * present_value)204348761c62SAndrew Jeffery int decode_get_numeric_effecter_value_resp(const struct pldm_msg *msg,
204448761c62SAndrew Jeffery 					   size_t payload_length,
204548761c62SAndrew Jeffery 					   uint8_t *completion_code,
204648761c62SAndrew Jeffery 					   uint8_t *effecter_data_size,
204748761c62SAndrew Jeffery 					   uint8_t *effecter_oper_state,
204848761c62SAndrew Jeffery 					   uint8_t *pending_value,
204948761c62SAndrew Jeffery 					   uint8_t *present_value)
205048761c62SAndrew Jeffery {
205148761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
205248761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
205348761c62SAndrew Jeffery 	int rc;
205448761c62SAndrew Jeffery 
205548761c62SAndrew Jeffery 	if (msg == NULL || effecter_data_size == NULL ||
205648761c62SAndrew Jeffery 	    effecter_oper_state == NULL || pending_value == NULL ||
205748761c62SAndrew Jeffery 	    present_value == NULL) {
205848761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
205948761c62SAndrew Jeffery 	}
206048761c62SAndrew Jeffery 
2061830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(
2062830c1eb4SAndrew Jeffery 		buf, PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES,
206348761c62SAndrew Jeffery 		msg->payload, payload_length);
206448761c62SAndrew Jeffery 	if (rc) {
2065830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
206648761c62SAndrew Jeffery 	}
206748761c62SAndrew Jeffery 
206848761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, completion_code);
206948761c62SAndrew Jeffery 	if (rc) {
2070830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
207148761c62SAndrew Jeffery 	}
207248761c62SAndrew Jeffery 
207348761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
207448761c62SAndrew Jeffery 		return PLDM_SUCCESS;
207548761c62SAndrew Jeffery 	}
207648761c62SAndrew Jeffery 
207748761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
207848761c62SAndrew Jeffery 	if (rc) {
2079830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
208048761c62SAndrew Jeffery 	}
208148761c62SAndrew Jeffery 
208248761c62SAndrew Jeffery 	if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
208348761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
208448761c62SAndrew Jeffery 	}
208548761c62SAndrew Jeffery 
208648761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, effecter_oper_state);
208748761c62SAndrew Jeffery 	if (rc) {
2088830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
208948761c62SAndrew Jeffery 	}
209048761c62SAndrew Jeffery 
209148761c62SAndrew Jeffery 	if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
209248761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
209348761c62SAndrew Jeffery 	}
209448761c62SAndrew Jeffery 
209548761c62SAndrew Jeffery 	pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
209648761c62SAndrew Jeffery 					   pending_value);
209748761c62SAndrew Jeffery 	pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
209848761c62SAndrew Jeffery 					   present_value);
209948761c62SAndrew Jeffery 
2100830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy_consumed(buf);
2101830c1eb4SAndrew Jeffery 	if (rc) {
2102830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
2103830c1eb4SAndrew Jeffery 	}
2104830c1eb4SAndrew Jeffery 
2105830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
210648761c62SAndrew Jeffery }
210748761c62SAndrew Jeffery 
210848761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_pldm_pdr_repository_chg_event_data(uint8_t event_data_format,uint8_t number_of_change_records,const uint8_t * event_data_operations,const uint8_t * numbers_of_change_entries,const uint32_t * const * change_entries,struct pldm_pdr_repository_chg_event_data * event_data,size_t * actual_change_records_size,size_t max_change_records_size)210948761c62SAndrew Jeffery int encode_pldm_pdr_repository_chg_event_data(
211048761c62SAndrew Jeffery 	uint8_t event_data_format, uint8_t number_of_change_records,
211148761c62SAndrew Jeffery 	const uint8_t *event_data_operations,
211248761c62SAndrew Jeffery 	const uint8_t *numbers_of_change_entries,
211348761c62SAndrew Jeffery 	const uint32_t *const *change_entries,
211448761c62SAndrew Jeffery 	struct pldm_pdr_repository_chg_event_data *event_data,
211548761c62SAndrew Jeffery 	size_t *actual_change_records_size, size_t max_change_records_size)
211648761c62SAndrew Jeffery {
211748761c62SAndrew Jeffery 	if (event_data_operations == NULL ||
211848761c62SAndrew Jeffery 	    numbers_of_change_entries == NULL || change_entries == NULL) {
211948761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
212048761c62SAndrew Jeffery 	}
212148761c62SAndrew Jeffery 
212248761c62SAndrew Jeffery 	size_t expected_size =
212348761c62SAndrew Jeffery 		sizeof(event_data_format) + sizeof(number_of_change_records);
212448761c62SAndrew Jeffery 
212548761c62SAndrew Jeffery 	expected_size +=
212648761c62SAndrew Jeffery 		sizeof(*event_data_operations) * number_of_change_records;
212748761c62SAndrew Jeffery 	expected_size +=
212848761c62SAndrew Jeffery 		sizeof(*numbers_of_change_entries) * number_of_change_records;
212948761c62SAndrew Jeffery 
213048761c62SAndrew Jeffery 	for (uint8_t i = 0; i < number_of_change_records; ++i) {
213148761c62SAndrew Jeffery 		expected_size += sizeof(*change_entries[0]) *
213248761c62SAndrew Jeffery 				 numbers_of_change_entries[i];
213348761c62SAndrew Jeffery 	}
213448761c62SAndrew Jeffery 
213548761c62SAndrew Jeffery 	*actual_change_records_size = expected_size;
213648761c62SAndrew Jeffery 
213748761c62SAndrew Jeffery 	if (event_data == NULL) {
213848761c62SAndrew Jeffery 		return PLDM_SUCCESS;
213948761c62SAndrew Jeffery 	}
214048761c62SAndrew Jeffery 
214148761c62SAndrew Jeffery 	if (max_change_records_size < expected_size) {
214248761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
214348761c62SAndrew Jeffery 	}
214448761c62SAndrew Jeffery 
214548761c62SAndrew Jeffery 	event_data->event_data_format = event_data_format;
214648761c62SAndrew Jeffery 	event_data->number_of_change_records = number_of_change_records;
214748761c62SAndrew Jeffery 
214848761c62SAndrew Jeffery 	struct pldm_pdr_repository_change_record_data *record_data =
214948761c62SAndrew Jeffery 		(struct pldm_pdr_repository_change_record_data *)
215048761c62SAndrew Jeffery 			event_data->change_records;
215148761c62SAndrew Jeffery 
215248761c62SAndrew Jeffery 	for (uint8_t i = 0; i < number_of_change_records; ++i) {
215348761c62SAndrew Jeffery 		record_data->event_data_operation = event_data_operations[i];
215448761c62SAndrew Jeffery 		record_data->number_of_change_entries =
215548761c62SAndrew Jeffery 			numbers_of_change_entries[i];
215648761c62SAndrew Jeffery 
215748761c62SAndrew Jeffery 		for (uint8_t j = 0; j < record_data->number_of_change_entries;
215848761c62SAndrew Jeffery 		     ++j) {
215948761c62SAndrew Jeffery 			record_data->change_entry[j] =
216048761c62SAndrew Jeffery 				htole32(change_entries[i][j]);
216148761c62SAndrew Jeffery 		}
216248761c62SAndrew Jeffery 
216348761c62SAndrew Jeffery 		record_data =
216448761c62SAndrew Jeffery 			(struct pldm_pdr_repository_change_record_data
216548761c62SAndrew Jeffery 				 *)(record_data->change_entry +
216648761c62SAndrew Jeffery 				    record_data->number_of_change_entries);
216748761c62SAndrew Jeffery 	}
216848761c62SAndrew Jeffery 
216948761c62SAndrew Jeffery 	return PLDM_SUCCESS;
217048761c62SAndrew Jeffery }
217148761c62SAndrew Jeffery 
217248761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_pldm_pdr_repository_chg_event_data(const uint8_t * event_data,size_t event_data_size,uint8_t * event_data_format,uint8_t * number_of_change_records,size_t * change_record_data_offset)217348761c62SAndrew Jeffery int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data,
217448761c62SAndrew Jeffery 					      size_t event_data_size,
217548761c62SAndrew Jeffery 					      uint8_t *event_data_format,
217648761c62SAndrew Jeffery 					      uint8_t *number_of_change_records,
217748761c62SAndrew Jeffery 					      size_t *change_record_data_offset)
217848761c62SAndrew Jeffery {
217948761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
218048761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
218148761c62SAndrew Jeffery 	int rc;
218248761c62SAndrew Jeffery 
218390bbe6c0SAndrew Jeffery 	if (event_data == NULL || event_data_format == NULL ||
218490bbe6c0SAndrew Jeffery 	    number_of_change_records == NULL ||
218548761c62SAndrew Jeffery 	    change_record_data_offset == NULL) {
218648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
218748761c62SAndrew Jeffery 	}
218848761c62SAndrew Jeffery 
2189830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf,
2190830c1eb4SAndrew Jeffery 				    PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH,
219148761c62SAndrew Jeffery 				    event_data, event_data_size);
219248761c62SAndrew Jeffery 	if (rc) {
2193830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
219448761c62SAndrew Jeffery 	}
219548761c62SAndrew Jeffery 
219648761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, event_data_format);
219748761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, number_of_change_records);
219848761c62SAndrew Jeffery 
219948761c62SAndrew Jeffery 	*change_record_data_offset =
220048761c62SAndrew Jeffery 		sizeof(*event_data_format) + sizeof(*number_of_change_records);
220148761c62SAndrew Jeffery 
2202830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
2203830c1eb4SAndrew Jeffery 	if (rc) {
2204830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
2205830c1eb4SAndrew Jeffery 	}
2206830c1eb4SAndrew Jeffery 
2207830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
220848761c62SAndrew Jeffery }
220948761c62SAndrew Jeffery 
2210f874b383SThu Nguyen LIBPLDM_ABI_STABLE
decode_pldm_message_poll_event_data(const void * event_data,size_t event_data_length,struct pldm_message_poll_event * poll_event)22117739d123SThu Nguyen int decode_pldm_message_poll_event_data(
22127739d123SThu Nguyen 	const void *event_data, size_t event_data_length,
22137739d123SThu Nguyen 	struct pldm_message_poll_event *poll_event)
221448761c62SAndrew Jeffery {
221548761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
221648761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
221748761c62SAndrew Jeffery 	int rc;
221848761c62SAndrew Jeffery 
221990bbe6c0SAndrew Jeffery 	if (!event_data || !poll_event) {
22207739d123SThu Nguyen 		return -EINVAL;
222148761c62SAndrew Jeffery 	}
222248761c62SAndrew Jeffery 
22237739d123SThu Nguyen 	rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
222448761c62SAndrew Jeffery 				    event_data_length);
222548761c62SAndrew Jeffery 	if (rc) {
222648761c62SAndrew Jeffery 		return rc;
222748761c62SAndrew Jeffery 	}
222848761c62SAndrew Jeffery 
22297739d123SThu Nguyen 	pldm_msgbuf_extract(buf, poll_event->format_version);
22307739d123SThu Nguyen 	rc = pldm_msgbuf_extract(buf, poll_event->event_id);
223148761c62SAndrew Jeffery 	if (rc) {
223248761c62SAndrew Jeffery 		return rc;
223348761c62SAndrew Jeffery 	}
223448761c62SAndrew Jeffery 
22357739d123SThu Nguyen 	if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) {
22367739d123SThu Nguyen 		return -EPROTO;
223748761c62SAndrew Jeffery 	}
223848761c62SAndrew Jeffery 
22397739d123SThu Nguyen 	pldm_msgbuf_extract(buf, poll_event->data_transfer_handle);
224048761c62SAndrew Jeffery 
224148761c62SAndrew Jeffery 	return pldm_msgbuf_destroy_consumed(buf);
224248761c62SAndrew Jeffery }
224348761c62SAndrew Jeffery 
224448761c62SAndrew Jeffery LIBPLDM_ABI_TESTING
encode_pldm_message_poll_event_data(const struct pldm_message_poll_event * poll_event,void * event_data,size_t event_data_length)22457739d123SThu Nguyen int encode_pldm_message_poll_event_data(
22467739d123SThu Nguyen 	const struct pldm_message_poll_event *poll_event, void *event_data,
224748761c62SAndrew Jeffery 	size_t event_data_length)
224848761c62SAndrew Jeffery {
224948761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
225048761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
225148761c62SAndrew Jeffery 	int rc;
225248761c62SAndrew Jeffery 
225390bbe6c0SAndrew Jeffery 	if (poll_event == NULL || event_data == NULL) {
225490bbe6c0SAndrew Jeffery 		return -EINVAL;
225590bbe6c0SAndrew Jeffery 	}
225690bbe6c0SAndrew Jeffery 
22577739d123SThu Nguyen 	if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) {
22587739d123SThu Nguyen 		return -EPROTO;
225948761c62SAndrew Jeffery 	}
226048761c62SAndrew Jeffery 
22617739d123SThu Nguyen 	rc = pldm_msgbuf_init_errno(buf, PLDM_MSG_POLL_EVENT_LENGTH, event_data,
226248761c62SAndrew Jeffery 				    event_data_length);
226348761c62SAndrew Jeffery 	if (rc) {
226448761c62SAndrew Jeffery 		return rc;
226548761c62SAndrew Jeffery 	}
22667739d123SThu Nguyen 	pldm_msgbuf_insert(buf, poll_event->format_version);
22677739d123SThu Nguyen 	pldm_msgbuf_insert(buf, poll_event->event_id);
22687739d123SThu Nguyen 	pldm_msgbuf_insert(buf, poll_event->data_transfer_handle);
226948761c62SAndrew Jeffery 
22707739d123SThu Nguyen 	return pldm_msgbuf_destroy_consumed(buf);
227148761c62SAndrew Jeffery }
227248761c62SAndrew Jeffery 
227348761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_pldm_pdr_repository_change_record_data(const uint8_t * change_record_data,size_t change_record_data_size,uint8_t * event_data_operation,uint8_t * number_of_change_entries,size_t * change_entry_data_offset)227448761c62SAndrew Jeffery int decode_pldm_pdr_repository_change_record_data(
227548761c62SAndrew Jeffery 	const uint8_t *change_record_data, size_t change_record_data_size,
227648761c62SAndrew Jeffery 	uint8_t *event_data_operation, uint8_t *number_of_change_entries,
227748761c62SAndrew Jeffery 	size_t *change_entry_data_offset)
227848761c62SAndrew Jeffery {
227948761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
228048761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
228148761c62SAndrew Jeffery 	int rc;
228248761c62SAndrew Jeffery 
228390bbe6c0SAndrew Jeffery 	if (change_record_data == NULL || event_data_operation == NULL ||
228490bbe6c0SAndrew Jeffery 	    number_of_change_entries == NULL ||
228548761c62SAndrew Jeffery 	    change_entry_data_offset == NULL) {
228648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
228748761c62SAndrew Jeffery 	}
228848761c62SAndrew Jeffery 
2289830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(
2290830c1eb4SAndrew Jeffery 		buf, PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH,
229148761c62SAndrew Jeffery 		change_record_data, change_record_data_size);
229248761c62SAndrew Jeffery 	if (rc) {
2293830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
229448761c62SAndrew Jeffery 	}
229548761c62SAndrew Jeffery 
229648761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, event_data_operation);
229748761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, number_of_change_entries);
229848761c62SAndrew Jeffery 
229948761c62SAndrew Jeffery 	*change_entry_data_offset = sizeof(*event_data_operation) +
230048761c62SAndrew Jeffery 				    sizeof(*number_of_change_entries);
230148761c62SAndrew Jeffery 
2302830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
2303830c1eb4SAndrew Jeffery 	if (rc) {
2304830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
2305830c1eb4SAndrew Jeffery 	}
2306830c1eb4SAndrew Jeffery 
2307830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
230848761c62SAndrew Jeffery }
230948761c62SAndrew Jeffery 
231048761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_get_sensor_reading_req(uint8_t instance_id,uint16_t sensor_id,uint8_t rearm_event_state,struct pldm_msg * msg)231148761c62SAndrew Jeffery int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id,
231248761c62SAndrew Jeffery 				  uint8_t rearm_event_state,
231348761c62SAndrew Jeffery 				  struct pldm_msg *msg)
231448761c62SAndrew Jeffery {
231548761c62SAndrew Jeffery 	if (msg == NULL) {
231648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
231748761c62SAndrew Jeffery 	}
231848761c62SAndrew Jeffery 
231948761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
232048761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
232148761c62SAndrew Jeffery 	header.instance = instance_id;
232248761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
232348761c62SAndrew Jeffery 	header.command = PLDM_GET_SENSOR_READING;
232448761c62SAndrew Jeffery 
232548761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
232648761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
232748761c62SAndrew Jeffery 		return rc;
232848761c62SAndrew Jeffery 	}
232948761c62SAndrew Jeffery 
233048761c62SAndrew Jeffery 	struct pldm_get_sensor_reading_req *request =
233148761c62SAndrew Jeffery 		(struct pldm_get_sensor_reading_req *)msg->payload;
233248761c62SAndrew Jeffery 
233348761c62SAndrew Jeffery 	request->sensor_id = htole16(sensor_id);
233448761c62SAndrew Jeffery 	request->rearm_event_state = rearm_event_state;
233548761c62SAndrew Jeffery 
233648761c62SAndrew Jeffery 	return PLDM_SUCCESS;
233748761c62SAndrew Jeffery }
233848761c62SAndrew Jeffery 
233948761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_get_sensor_reading_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint8_t * sensor_data_size,uint8_t * sensor_operational_state,uint8_t * sensor_event_message_enable,uint8_t * present_state,uint8_t * previous_state,uint8_t * event_state,uint8_t * present_reading)234048761c62SAndrew Jeffery int decode_get_sensor_reading_resp(
234148761c62SAndrew Jeffery 	const struct pldm_msg *msg, size_t payload_length,
234248761c62SAndrew Jeffery 	uint8_t *completion_code, uint8_t *sensor_data_size,
234348761c62SAndrew Jeffery 	uint8_t *sensor_operational_state, uint8_t *sensor_event_message_enable,
234448761c62SAndrew Jeffery 	uint8_t *present_state, uint8_t *previous_state, uint8_t *event_state,
234548761c62SAndrew Jeffery 	uint8_t *present_reading)
234648761c62SAndrew Jeffery {
234748761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
234848761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
234948761c62SAndrew Jeffery 	int rc;
235048761c62SAndrew Jeffery 
235148761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL ||
235248761c62SAndrew Jeffery 	    sensor_data_size == NULL || sensor_operational_state == NULL ||
235348761c62SAndrew Jeffery 	    sensor_event_message_enable == NULL || present_state == NULL ||
235448761c62SAndrew Jeffery 	    previous_state == NULL || event_state == NULL ||
235548761c62SAndrew Jeffery 	    present_reading == NULL) {
235648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
235748761c62SAndrew Jeffery 	}
235848761c62SAndrew Jeffery 
2359830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_MIN_RESP_BYTES,
236048761c62SAndrew Jeffery 				    msg->payload, payload_length);
236148761c62SAndrew Jeffery 	if (rc) {
2362830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
236348761c62SAndrew Jeffery 	}
236448761c62SAndrew Jeffery 
236548761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, completion_code);
236648761c62SAndrew Jeffery 	if (rc) {
2367830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
236848761c62SAndrew Jeffery 	}
236948761c62SAndrew Jeffery 
237048761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
237148761c62SAndrew Jeffery 		return PLDM_SUCCESS;
237248761c62SAndrew Jeffery 	}
237348761c62SAndrew Jeffery 
237448761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
237548761c62SAndrew Jeffery 	if (rc) {
2376830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
237748761c62SAndrew Jeffery 	}
237848761c62SAndrew Jeffery 
237948761c62SAndrew Jeffery 	if (*sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) {
238048761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
238148761c62SAndrew Jeffery 	}
238248761c62SAndrew Jeffery 
238348761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, sensor_operational_state);
238448761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, sensor_event_message_enable);
238548761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, present_state);
238648761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, previous_state);
238748761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, event_state);
238848761c62SAndrew Jeffery 
238948761c62SAndrew Jeffery 	pldm_msgbuf_extract_sensor_value(buf, *sensor_data_size,
239048761c62SAndrew Jeffery 					 present_reading);
239148761c62SAndrew Jeffery 
2392830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy_consumed(buf);
2393830c1eb4SAndrew Jeffery 	if (rc) {
2394830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
2395830c1eb4SAndrew Jeffery 	}
2396830c1eb4SAndrew Jeffery 
2397830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
239848761c62SAndrew Jeffery }
239948761c62SAndrew Jeffery 
240048761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_get_sensor_reading_resp(uint8_t instance_id,uint8_t completion_code,uint8_t sensor_data_size,uint8_t sensor_operational_state,uint8_t sensor_event_message_enable,uint8_t present_state,uint8_t previous_state,uint8_t event_state,const uint8_t * present_reading,struct pldm_msg * msg,size_t payload_length)240148761c62SAndrew Jeffery int encode_get_sensor_reading_resp(uint8_t instance_id, uint8_t completion_code,
240248761c62SAndrew Jeffery 				   uint8_t sensor_data_size,
240348761c62SAndrew Jeffery 				   uint8_t sensor_operational_state,
240448761c62SAndrew Jeffery 				   uint8_t sensor_event_message_enable,
240548761c62SAndrew Jeffery 				   uint8_t present_state,
240648761c62SAndrew Jeffery 				   uint8_t previous_state, uint8_t event_state,
240748761c62SAndrew Jeffery 				   const uint8_t *present_reading,
240848761c62SAndrew Jeffery 				   struct pldm_msg *msg, size_t payload_length)
240948761c62SAndrew Jeffery {
241048761c62SAndrew Jeffery 	if (msg == NULL || present_reading == NULL) {
241148761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
241248761c62SAndrew Jeffery 	}
241348761c62SAndrew Jeffery 
241448761c62SAndrew Jeffery 	if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
241548761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
241648761c62SAndrew Jeffery 	}
241748761c62SAndrew Jeffery 
241848761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
241948761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
242048761c62SAndrew Jeffery 	header.instance = instance_id;
242148761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
242248761c62SAndrew Jeffery 	header.command = PLDM_GET_SENSOR_READING;
242348761c62SAndrew Jeffery 
242448761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
242548761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
242648761c62SAndrew Jeffery 		return rc;
242748761c62SAndrew Jeffery 	}
242848761c62SAndrew Jeffery 
242948761c62SAndrew Jeffery 	struct pldm_get_sensor_reading_resp *response =
243048761c62SAndrew Jeffery 		(struct pldm_get_sensor_reading_resp *)msg->payload;
243148761c62SAndrew Jeffery 
243248761c62SAndrew Jeffery 	response->completion_code = completion_code;
243348761c62SAndrew Jeffery 	response->sensor_data_size = sensor_data_size;
243448761c62SAndrew Jeffery 	response->sensor_operational_state = sensor_operational_state;
243548761c62SAndrew Jeffery 	response->sensor_event_message_enable = sensor_event_message_enable;
243648761c62SAndrew Jeffery 	response->present_state = present_state;
243748761c62SAndrew Jeffery 	response->previous_state = previous_state;
243848761c62SAndrew Jeffery 	response->event_state = event_state;
243948761c62SAndrew Jeffery 
244048761c62SAndrew Jeffery 	if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
244148761c62SAndrew Jeffery 	    sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
244248761c62SAndrew Jeffery 		if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
244348761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
244448761c62SAndrew Jeffery 		}
244548761c62SAndrew Jeffery 		response->present_reading[0] = *present_reading;
244648761c62SAndrew Jeffery 
244748761c62SAndrew Jeffery 	} else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
244848761c62SAndrew Jeffery 		   sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
244948761c62SAndrew Jeffery 		if (payload_length !=
245048761c62SAndrew Jeffery 		    PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
245148761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
245248761c62SAndrew Jeffery 		}
245348761c62SAndrew Jeffery 		uint16_t val = *(uint16_t *)present_reading;
245448761c62SAndrew Jeffery 		val = htole16(val);
245548761c62SAndrew Jeffery 		memcpy(response->present_reading, &val, 2);
245648761c62SAndrew Jeffery 
245748761c62SAndrew Jeffery 	} else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
245848761c62SAndrew Jeffery 		   sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
245948761c62SAndrew Jeffery 		if (payload_length !=
246048761c62SAndrew Jeffery 		    PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
246148761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_LENGTH;
246248761c62SAndrew Jeffery 		}
246348761c62SAndrew Jeffery 		uint32_t val = *(uint32_t *)present_reading;
246448761c62SAndrew Jeffery 		val = htole32(val);
246548761c62SAndrew Jeffery 		memcpy(response->present_reading, &val, 4);
246648761c62SAndrew Jeffery 	}
246748761c62SAndrew Jeffery 
246848761c62SAndrew Jeffery 	return PLDM_SUCCESS;
246948761c62SAndrew Jeffery }
247048761c62SAndrew Jeffery 
247148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_get_sensor_reading_req(const struct pldm_msg * msg,size_t payload_length,uint16_t * sensor_id,uint8_t * rearm_event_state)247248761c62SAndrew Jeffery int decode_get_sensor_reading_req(const struct pldm_msg *msg,
247348761c62SAndrew Jeffery 				  size_t payload_length, uint16_t *sensor_id,
247448761c62SAndrew Jeffery 				  uint8_t *rearm_event_state)
247548761c62SAndrew Jeffery {
247648761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
247748761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
247848761c62SAndrew Jeffery 	int rc;
247948761c62SAndrew Jeffery 
248048761c62SAndrew Jeffery 	if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) {
248148761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
248248761c62SAndrew Jeffery 	}
248348761c62SAndrew Jeffery 
2484830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf, PLDM_GET_SENSOR_READING_REQ_BYTES,
248548761c62SAndrew Jeffery 				    msg->payload, payload_length);
248648761c62SAndrew Jeffery 	if (rc) {
2487830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
248848761c62SAndrew Jeffery 	}
248948761c62SAndrew Jeffery 
249048761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, sensor_id);
249148761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, rearm_event_state);
249248761c62SAndrew Jeffery 
2493830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
2494830c1eb4SAndrew Jeffery 	if (rc) {
2495830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
2496830c1eb4SAndrew Jeffery 	}
2497830c1eb4SAndrew Jeffery 
2498830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
249948761c62SAndrew Jeffery }
250048761c62SAndrew Jeffery 
250148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_set_event_receiver_req(uint8_t instance_id,uint8_t event_message_global_enable,uint8_t transport_protocol_type,uint8_t event_receiver_address_info,uint16_t heartbeat_timer,struct pldm_msg * msg)250248761c62SAndrew Jeffery int encode_set_event_receiver_req(uint8_t instance_id,
250348761c62SAndrew Jeffery 				  uint8_t event_message_global_enable,
250448761c62SAndrew Jeffery 				  uint8_t transport_protocol_type,
250548761c62SAndrew Jeffery 				  uint8_t event_receiver_address_info,
250648761c62SAndrew Jeffery 				  uint16_t heartbeat_timer,
250748761c62SAndrew Jeffery 				  struct pldm_msg *msg)
250848761c62SAndrew Jeffery {
250948761c62SAndrew Jeffery 	if (msg == NULL) {
251048761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
251148761c62SAndrew Jeffery 	}
251248761c62SAndrew Jeffery 
251348761c62SAndrew Jeffery 	if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
251448761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
251548761c62SAndrew Jeffery 	}
251648761c62SAndrew Jeffery 
251748761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
251848761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
251948761c62SAndrew Jeffery 	header.instance = instance_id;
252048761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
252148761c62SAndrew Jeffery 	header.command = PLDM_SET_EVENT_RECEIVER;
252248761c62SAndrew Jeffery 
252348761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
252448761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
252548761c62SAndrew Jeffery 		return rc;
252648761c62SAndrew Jeffery 	}
252748761c62SAndrew Jeffery 
252848761c62SAndrew Jeffery 	struct pldm_set_event_receiver_req *request =
252948761c62SAndrew Jeffery 		(struct pldm_set_event_receiver_req *)msg->payload;
253048761c62SAndrew Jeffery 	request->event_message_global_enable = event_message_global_enable;
253148761c62SAndrew Jeffery 
253248761c62SAndrew Jeffery 	request->transport_protocol_type = transport_protocol_type;
253348761c62SAndrew Jeffery 	request->event_receiver_address_info = event_receiver_address_info;
253448761c62SAndrew Jeffery 
253548761c62SAndrew Jeffery 	if (event_message_global_enable ==
253648761c62SAndrew Jeffery 	    PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {
253748761c62SAndrew Jeffery 		if (heartbeat_timer == 0) {
253848761c62SAndrew Jeffery 			return PLDM_ERROR_INVALID_DATA;
253948761c62SAndrew Jeffery 		}
254048761c62SAndrew Jeffery 		request->heartbeat_timer = htole16(heartbeat_timer);
254148761c62SAndrew Jeffery 	}
254248761c62SAndrew Jeffery 
254348761c62SAndrew Jeffery 	return PLDM_SUCCESS;
254448761c62SAndrew Jeffery }
254548761c62SAndrew Jeffery 
254648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_set_event_receiver_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code)254748761c62SAndrew Jeffery int decode_set_event_receiver_resp(const struct pldm_msg *msg,
254848761c62SAndrew Jeffery 				   size_t payload_length,
254948761c62SAndrew Jeffery 				   uint8_t *completion_code)
255048761c62SAndrew Jeffery {
255148761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
255248761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
255348761c62SAndrew Jeffery 	int rc;
255448761c62SAndrew Jeffery 
255548761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL) {
255648761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
255748761c62SAndrew Jeffery 	}
255848761c62SAndrew Jeffery 
2559830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_RESP_BYTES,
256048761c62SAndrew Jeffery 				    msg->payload, payload_length);
256148761c62SAndrew Jeffery 	if (rc) {
2562830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
256348761c62SAndrew Jeffery 	}
256448761c62SAndrew Jeffery 
256548761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, completion_code);
256648761c62SAndrew Jeffery 
2567830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
2568830c1eb4SAndrew Jeffery 	if (rc) {
2569830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
2570830c1eb4SAndrew Jeffery 	}
2571830c1eb4SAndrew Jeffery 
2572830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
257348761c62SAndrew Jeffery }
257448761c62SAndrew Jeffery 
257548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_set_event_receiver_req(const struct pldm_msg * msg,size_t payload_length,uint8_t * event_message_global_enable,uint8_t * transport_protocol_type,uint8_t * event_receiver_address_info,uint16_t * heartbeat_timer)257648761c62SAndrew Jeffery int decode_set_event_receiver_req(const struct pldm_msg *msg,
257748761c62SAndrew Jeffery 				  size_t payload_length,
257848761c62SAndrew Jeffery 				  uint8_t *event_message_global_enable,
257948761c62SAndrew Jeffery 				  uint8_t *transport_protocol_type,
258048761c62SAndrew Jeffery 				  uint8_t *event_receiver_address_info,
258148761c62SAndrew Jeffery 				  uint16_t *heartbeat_timer)
258248761c62SAndrew Jeffery 
258348761c62SAndrew Jeffery {
258448761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
258548761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
258648761c62SAndrew Jeffery 	int rc;
258748761c62SAndrew Jeffery 
258848761c62SAndrew Jeffery 	if (msg == NULL || event_message_global_enable == NULL ||
258948761c62SAndrew Jeffery 	    transport_protocol_type == NULL ||
259048761c62SAndrew Jeffery 	    event_receiver_address_info == NULL || heartbeat_timer == NULL) {
259148761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
259248761c62SAndrew Jeffery 	}
259348761c62SAndrew Jeffery 
259498e137deSGilbert Chen 	rc = pldm_msgbuf_init_errno(buf, PLDM_SET_EVENT_RECEIVER_MIN_REQ_BYTES,
259548761c62SAndrew Jeffery 				    msg->payload, payload_length);
259648761c62SAndrew Jeffery 	if (rc) {
2597830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
259848761c62SAndrew Jeffery 	}
259948761c62SAndrew Jeffery 
260048761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, event_message_global_enable);
260198e137deSGilbert Chen 	if (rc) {
260298e137deSGilbert Chen 		return pldm_xlate_errno(rc);
260398e137deSGilbert Chen 	}
260498e137deSGilbert Chen 
260548761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, transport_protocol_type);
260648761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, event_receiver_address_info);
2607*56ef86a0SMatt Johnston 	if (*event_message_global_enable ==
2608*56ef86a0SMatt Johnston 	    PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {
260948761c62SAndrew Jeffery 		pldm_msgbuf_extract_p(buf, heartbeat_timer);
261098e137deSGilbert Chen 	}
261148761c62SAndrew Jeffery 
261248761c62SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
261348761c62SAndrew Jeffery 	if (rc) {
2614830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
261548761c62SAndrew Jeffery 	}
261648761c62SAndrew Jeffery 
261748761c62SAndrew Jeffery 	if ((*event_message_global_enable ==
261848761c62SAndrew Jeffery 	     PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) &&
261948761c62SAndrew Jeffery 	    (*heartbeat_timer == 0)) {
262048761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
262148761c62SAndrew Jeffery 	}
262248761c62SAndrew Jeffery 
262348761c62SAndrew Jeffery 	return PLDM_SUCCESS;
262448761c62SAndrew Jeffery }
262548761c62SAndrew Jeffery 
262648761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_set_event_receiver_resp(uint8_t instance_id,uint8_t completion_code,struct pldm_msg * msg)262748761c62SAndrew Jeffery int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code,
262848761c62SAndrew Jeffery 				   struct pldm_msg *msg)
262948761c62SAndrew Jeffery 
263048761c62SAndrew Jeffery {
263148761c62SAndrew Jeffery 	if (msg == NULL) {
263248761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
263348761c62SAndrew Jeffery 	}
263448761c62SAndrew Jeffery 
263548761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
263648761c62SAndrew Jeffery 	header.instance = instance_id;
263748761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
263848761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
263948761c62SAndrew Jeffery 	header.command = PLDM_SET_EVENT_RECEIVER;
264048761c62SAndrew Jeffery 
264148761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
264248761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
264348761c62SAndrew Jeffery 		return rc;
264448761c62SAndrew Jeffery 	}
264548761c62SAndrew Jeffery 
264648761c62SAndrew Jeffery 	msg->payload[0] = completion_code;
264748761c62SAndrew Jeffery 
264848761c62SAndrew Jeffery 	return PLDM_SUCCESS;
264948761c62SAndrew Jeffery }
265048761c62SAndrew Jeffery 
265148761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_poll_for_platform_event_message_req(uint8_t instance_id,uint8_t format_version,uint8_t transfer_operation_flag,uint32_t data_transfer_handle,uint16_t event_id_to_acknowledge,struct pldm_msg * msg,size_t payload_length)265248761c62SAndrew Jeffery int encode_poll_for_platform_event_message_req(uint8_t instance_id,
265348761c62SAndrew Jeffery 					       uint8_t format_version,
265448761c62SAndrew Jeffery 					       uint8_t transfer_operation_flag,
265548761c62SAndrew Jeffery 					       uint32_t data_transfer_handle,
265648761c62SAndrew Jeffery 					       uint16_t event_id_to_acknowledge,
265748761c62SAndrew Jeffery 					       struct pldm_msg *msg,
265848761c62SAndrew Jeffery 					       size_t payload_length)
265948761c62SAndrew Jeffery {
266048761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
266148761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
266248761c62SAndrew Jeffery 	int rc;
266348761c62SAndrew Jeffery 
266448761c62SAndrew Jeffery 	if (msg == NULL) {
266548761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
266648761c62SAndrew Jeffery 	}
266748761c62SAndrew Jeffery 
2668387b10f6SThu Nguyen 	rc = pldm_platform_poll_for_platform_event_message_validate(
2669387b10f6SThu Nguyen 		transfer_operation_flag, event_id_to_acknowledge);
2670387b10f6SThu Nguyen 	if (rc < 0) {
2671387b10f6SThu Nguyen 		return PLDM_ERROR_INVALID_DATA;
2672387b10f6SThu Nguyen 	}
2673387b10f6SThu Nguyen 
267448761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
267548761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
267648761c62SAndrew Jeffery 	header.instance = instance_id;
267748761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
267848761c62SAndrew Jeffery 	header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
267948761c62SAndrew Jeffery 
268048761c62SAndrew Jeffery 	rc = pack_pldm_header(&header, &(msg->hdr));
268148761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
268248761c62SAndrew Jeffery 		return rc;
268348761c62SAndrew Jeffery 	}
268448761c62SAndrew Jeffery 
2685830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(
268648761c62SAndrew Jeffery 		buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
268748761c62SAndrew Jeffery 		msg->payload, payload_length);
268848761c62SAndrew Jeffery 	if (rc) {
2689830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
269048761c62SAndrew Jeffery 	}
269148761c62SAndrew Jeffery 
269248761c62SAndrew Jeffery 	pldm_msgbuf_insert(buf, format_version);
269348761c62SAndrew Jeffery 	pldm_msgbuf_insert(buf, transfer_operation_flag);
269448761c62SAndrew Jeffery 	pldm_msgbuf_insert(buf, data_transfer_handle);
269548761c62SAndrew Jeffery 	pldm_msgbuf_insert(buf, event_id_to_acknowledge);
269648761c62SAndrew Jeffery 
2697830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy(buf);
2698830c1eb4SAndrew Jeffery 	if (rc) {
2699830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
2700830c1eb4SAndrew Jeffery 	}
2701830c1eb4SAndrew Jeffery 
2702830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
270348761c62SAndrew Jeffery }
270448761c62SAndrew Jeffery 
270548761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_poll_for_platform_event_message_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint8_t * tid,uint16_t * event_id,uint32_t * next_data_transfer_handle,uint8_t * transfer_flag,uint8_t * event_class,uint32_t * event_data_size,void ** event_data,uint32_t * event_data_integrity_checksum)270648761c62SAndrew Jeffery int decode_poll_for_platform_event_message_resp(
270748761c62SAndrew Jeffery 	const struct pldm_msg *msg, size_t payload_length,
270848761c62SAndrew Jeffery 	uint8_t *completion_code, uint8_t *tid, uint16_t *event_id,
270948761c62SAndrew Jeffery 	uint32_t *next_data_transfer_handle, uint8_t *transfer_flag,
271048761c62SAndrew Jeffery 	uint8_t *event_class, uint32_t *event_data_size, void **event_data,
271148761c62SAndrew Jeffery 	uint32_t *event_data_integrity_checksum)
271248761c62SAndrew Jeffery {
271348761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
271448761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
271548761c62SAndrew Jeffery 	int rc;
271648761c62SAndrew Jeffery 
271748761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL || tid == NULL ||
271848761c62SAndrew Jeffery 	    event_id == NULL || next_data_transfer_handle == NULL ||
271948761c62SAndrew Jeffery 	    transfer_flag == NULL || event_class == NULL ||
272048761c62SAndrew Jeffery 	    event_data_size == NULL || event_data == NULL ||
272148761c62SAndrew Jeffery 	    event_data_integrity_checksum == NULL) {
272248761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
272348761c62SAndrew Jeffery 	}
272448761c62SAndrew Jeffery 
2725830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(
272648761c62SAndrew Jeffery 		buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
272748761c62SAndrew Jeffery 		msg->payload, payload_length);
272848761c62SAndrew Jeffery 	if (rc) {
2729830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
273048761c62SAndrew Jeffery 	}
273148761c62SAndrew Jeffery 
273248761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, completion_code);
273348761c62SAndrew Jeffery 	if (rc) {
2734830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
273548761c62SAndrew Jeffery 	}
273648761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
273748761c62SAndrew Jeffery 		return *completion_code;
273848761c62SAndrew Jeffery 	}
273948761c62SAndrew Jeffery 
274048761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, tid);
274148761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, event_id);
274248761c62SAndrew Jeffery 	if (rc) {
2743830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
274448761c62SAndrew Jeffery 	}
274548761c62SAndrew Jeffery 	if ((*event_id == 0) || (*event_id == 0xffff)) {
274648761c62SAndrew Jeffery 		return PLDM_SUCCESS;
274748761c62SAndrew Jeffery 	}
274848761c62SAndrew Jeffery 
274948761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, next_data_transfer_handle);
275048761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, transfer_flag);
275148761c62SAndrew Jeffery 	if (rc) {
2752830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
275348761c62SAndrew Jeffery 	}
275448761c62SAndrew Jeffery 
275548761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, event_class);
275648761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract_p(buf, event_data_size);
275748761c62SAndrew Jeffery 	if (rc) {
2758830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
275948761c62SAndrew Jeffery 	}
276048761c62SAndrew Jeffery 	if (*event_data_size > payload_length) {
276148761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
276248761c62SAndrew Jeffery 	}
276348761c62SAndrew Jeffery 
276448761c62SAndrew Jeffery 	if (*event_data_size > 0) {
276548761c62SAndrew Jeffery 		pldm_msgbuf_span_required(buf, *event_data_size, event_data);
276648761c62SAndrew Jeffery 	}
276748761c62SAndrew Jeffery 
276848761c62SAndrew Jeffery 	if (*transfer_flag == PLDM_END ||
276948761c62SAndrew Jeffery 	    *transfer_flag == PLDM_START_AND_END) {
277048761c62SAndrew Jeffery 		pldm_msgbuf_extract_p(buf, event_data_integrity_checksum);
277148761c62SAndrew Jeffery 	}
277248761c62SAndrew Jeffery 
2773830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy_consumed(buf);
2774830c1eb4SAndrew Jeffery 	if (rc) {
2775830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
2776830c1eb4SAndrew Jeffery 	}
2777830c1eb4SAndrew Jeffery 
2778830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
277948761c62SAndrew Jeffery }
278048761c62SAndrew Jeffery 
278148761c62SAndrew Jeffery LIBPLDM_ABI_TESTING
decode_numeric_effecter_pdr_data(const void * pdr_data,size_t pdr_data_length,struct pldm_numeric_effecter_value_pdr * pdr_value)278248761c62SAndrew Jeffery int decode_numeric_effecter_pdr_data(
278348761c62SAndrew Jeffery 	const void *pdr_data, size_t pdr_data_length,
278448761c62SAndrew Jeffery 	struct pldm_numeric_effecter_value_pdr *pdr_value)
278548761c62SAndrew Jeffery {
278648761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
278748761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
278848761c62SAndrew Jeffery 	struct pldm_value_pdr_hdr hdr;
278948761c62SAndrew Jeffery 	int rc;
279048761c62SAndrew Jeffery 
279190bbe6c0SAndrew Jeffery 	if (!pdr_data || !pdr_value) {
279290bbe6c0SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
279390bbe6c0SAndrew Jeffery 	}
279490bbe6c0SAndrew Jeffery 
2795830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_init_errno(buf,
2796830c1eb4SAndrew Jeffery 				    PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
279748761c62SAndrew Jeffery 				    pdr_data, pdr_data_length);
279848761c62SAndrew Jeffery 	if (rc) {
2799830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
280048761c62SAndrew Jeffery 	}
280148761c62SAndrew Jeffery 
2802329176a8SAndrew Jeffery 	rc = pldm_msgbuf_extract_value_pdr_hdr(
2803329176a8SAndrew Jeffery 		buf, &hdr, PLDM_PDR_NUMERIC_EFFECTER_PDR_MIN_LENGTH,
280448761c62SAndrew Jeffery 		pdr_data_length);
280548761c62SAndrew Jeffery 	if (rc) {
2806329176a8SAndrew Jeffery 		return pldm_xlate_errno(rc);
280748761c62SAndrew Jeffery 	}
280848761c62SAndrew Jeffery 
280948761c62SAndrew Jeffery 	memcpy(&pdr_value->hdr, &hdr, sizeof(hdr));
281048761c62SAndrew Jeffery 
281148761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
281248761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->effecter_id);
281348761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->entity_type);
281448761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->entity_instance);
281548761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->container_id);
281648761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->effecter_semantic_id);
281748761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->effecter_init);
281848761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->effecter_auxiliary_names);
281948761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->base_unit);
282048761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->unit_modifier);
282148761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->rate_unit);
282248761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->base_oem_unit_handle);
282348761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->aux_unit);
282448761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->aux_unit_modifier);
282548761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->aux_rate_unit);
282648761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->aux_oem_unit_handle);
282748761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->is_linear);
282848761c62SAndrew Jeffery 
282948761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract(buf, pdr_value->effecter_data_size);
283048761c62SAndrew Jeffery 	if (rc) {
2831830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
283248761c62SAndrew Jeffery 	}
283348761c62SAndrew Jeffery 	if (pdr_value->effecter_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
283448761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
283548761c62SAndrew Jeffery 	}
283648761c62SAndrew Jeffery 
283748761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->resolution);
283848761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->offset);
283948761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->accuracy);
284048761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->plus_tolerance);
284148761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->minus_tolerance);
284248761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->state_transition_interval);
284348761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->transition_interval);
284448761c62SAndrew Jeffery 	pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size,
284548761c62SAndrew Jeffery 					  pdr_value->max_settable);
284648761c62SAndrew Jeffery 	pldm_msgbuf_extract_effecter_data(buf, pdr_value->effecter_data_size,
284748761c62SAndrew Jeffery 					  pdr_value->min_settable);
284848761c62SAndrew Jeffery 
284948761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
285048761c62SAndrew Jeffery 	if (rc) {
2851830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
285248761c62SAndrew Jeffery 	}
285348761c62SAndrew Jeffery 	if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
285448761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
285548761c62SAndrew Jeffery 	}
285648761c62SAndrew Jeffery 
285748761c62SAndrew Jeffery 	pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
285848761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
285948761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->nominal_value);
286048761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
286148761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->normal_max);
286248761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
286348761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->normal_min);
286448761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
286548761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->rated_max);
286648761c62SAndrew Jeffery 	pldm_msgbuf_extract_range_field_format(
286748761c62SAndrew Jeffery 		buf, pdr_value->range_field_format, pdr_value->rated_min);
286848761c62SAndrew Jeffery 
2869830c1eb4SAndrew Jeffery 	rc = pldm_msgbuf_destroy_consumed(buf);
2870830c1eb4SAndrew Jeffery 	if (rc) {
2871830c1eb4SAndrew Jeffery 		return pldm_xlate_errno(rc);
2872830c1eb4SAndrew Jeffery 	}
2873830c1eb4SAndrew Jeffery 
2874830c1eb4SAndrew Jeffery 	return PLDM_SUCCESS;
287548761c62SAndrew Jeffery }
287648761c62SAndrew Jeffery 
2877de67ab62STal Yacobi LIBPLDM_ABI_STABLE
encode_get_state_effecter_states_req(uint8_t instance_id,uint16_t effecter_id,struct pldm_msg * msg,size_t payload_length)287848761c62SAndrew Jeffery int encode_get_state_effecter_states_req(uint8_t instance_id,
287948761c62SAndrew Jeffery 					 uint16_t effecter_id,
288048761c62SAndrew Jeffery 					 struct pldm_msg *msg,
288148761c62SAndrew Jeffery 					 size_t payload_length)
288248761c62SAndrew Jeffery {
288348761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
288448761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
288548761c62SAndrew Jeffery 	int rc;
288648761c62SAndrew Jeffery 
288748761c62SAndrew Jeffery 	if (msg == NULL) {
2888f490a38fSTal Yacobi 		return -EINVAL;
288948761c62SAndrew Jeffery 	}
289048761c62SAndrew Jeffery 
289148761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
289248761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
289348761c62SAndrew Jeffery 	header.instance = instance_id;
289448761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
289548761c62SAndrew Jeffery 	header.command = PLDM_GET_STATE_EFFECTER_STATES;
289648761c62SAndrew Jeffery 
2897f490a38fSTal Yacobi 	rc = pack_pldm_header_errno(&header, &msg->hdr);
2898f490a38fSTal Yacobi 	if (rc < 0) {
289948761c62SAndrew Jeffery 		return rc;
290048761c62SAndrew Jeffery 	}
290148761c62SAndrew Jeffery 
2902f490a38fSTal Yacobi 	rc = pldm_msgbuf_init_errno(buf,
2903f490a38fSTal Yacobi 				    PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES,
290448761c62SAndrew Jeffery 				    msg->payload, payload_length);
290548761c62SAndrew Jeffery 	if (rc) {
290648761c62SAndrew Jeffery 		return rc;
290748761c62SAndrew Jeffery 	}
290848761c62SAndrew Jeffery 
290948761c62SAndrew Jeffery 	pldm_msgbuf_insert(buf, effecter_id);
291048761c62SAndrew Jeffery 
291148761c62SAndrew Jeffery 	return pldm_msgbuf_destroy_consumed(buf);
291248761c62SAndrew Jeffery }
291348761c62SAndrew Jeffery 
2914de67ab62STal Yacobi LIBPLDM_ABI_STABLE
decode_get_state_effecter_states_req(const struct pldm_msg * msg,size_t payload_length,uint16_t * effecter_id)291548761c62SAndrew Jeffery int decode_get_state_effecter_states_req(const struct pldm_msg *msg,
291648761c62SAndrew Jeffery 					 size_t payload_length,
291748761c62SAndrew Jeffery 					 uint16_t *effecter_id)
291848761c62SAndrew Jeffery {
291948761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
292048761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
292148761c62SAndrew Jeffery 	int rc;
292248761c62SAndrew Jeffery 
292348761c62SAndrew Jeffery 	if (msg == NULL || effecter_id == NULL) {
2924f490a38fSTal Yacobi 		return -EINVAL;
292548761c62SAndrew Jeffery 	}
292648761c62SAndrew Jeffery 
2927f490a38fSTal Yacobi 	rc = pldm_msgbuf_init_errno(
2928f490a38fSTal Yacobi 		buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
292948761c62SAndrew Jeffery 		msg->payload, payload_length);
293048761c62SAndrew Jeffery 	if (rc) {
293148761c62SAndrew Jeffery 		return rc;
293248761c62SAndrew Jeffery 	}
293348761c62SAndrew Jeffery 
293448761c62SAndrew Jeffery 	pldm_msgbuf_extract_p(buf, effecter_id);
293548761c62SAndrew Jeffery 
293648761c62SAndrew Jeffery 	return pldm_msgbuf_destroy_consumed(buf);
293748761c62SAndrew Jeffery }
293848761c62SAndrew Jeffery 
2939de67ab62STal Yacobi LIBPLDM_ABI_STABLE
decode_get_state_effecter_states_resp(const struct pldm_msg * msg,size_t payload_length,struct pldm_get_state_effecter_states_resp * resp)294048761c62SAndrew Jeffery int decode_get_state_effecter_states_resp(
294148761c62SAndrew Jeffery 	const struct pldm_msg *msg, size_t payload_length,
294248761c62SAndrew Jeffery 	struct pldm_get_state_effecter_states_resp *resp)
294348761c62SAndrew Jeffery {
294448761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
294548761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
294648761c62SAndrew Jeffery 	get_effecter_state_field *field;
294748761c62SAndrew Jeffery 	int rc;
294848761c62SAndrew Jeffery 	int i;
294948761c62SAndrew Jeffery 
295048761c62SAndrew Jeffery 	if (msg == NULL || resp == NULL) {
2951f490a38fSTal Yacobi 		return -EINVAL;
295248761c62SAndrew Jeffery 	}
295348761c62SAndrew Jeffery 
2954f490a38fSTal Yacobi 	rc = pldm_msgbuf_init_errno(
2955f490a38fSTal Yacobi 		buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
295648761c62SAndrew Jeffery 		msg->payload, payload_length);
295748761c62SAndrew Jeffery 	if (rc) {
295848761c62SAndrew Jeffery 		return rc;
295948761c62SAndrew Jeffery 	}
296048761c62SAndrew Jeffery 
296148761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract(buf, resp->completion_code);
296248761c62SAndrew Jeffery 	if (rc) {
296348761c62SAndrew Jeffery 		return rc;
296448761c62SAndrew Jeffery 	}
296548761c62SAndrew Jeffery 
296648761c62SAndrew Jeffery 	if (PLDM_SUCCESS != resp->completion_code) {
2967f490a38fSTal Yacobi 		return 0;
296848761c62SAndrew Jeffery 	}
296948761c62SAndrew Jeffery 
297048761c62SAndrew Jeffery 	rc = pldm_msgbuf_extract(buf, resp->comp_effecter_count);
297148761c62SAndrew Jeffery 	if (rc) {
297248761c62SAndrew Jeffery 		return rc;
297348761c62SAndrew Jeffery 	}
297448761c62SAndrew Jeffery 
297548761c62SAndrew Jeffery 	uint8_t comp_effecter_count = resp->comp_effecter_count;
297648761c62SAndrew Jeffery 
297748761c62SAndrew Jeffery 	if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN ||
297848761c62SAndrew Jeffery 	    comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) {
2979f490a38fSTal Yacobi 		return -EBADMSG;
298048761c62SAndrew Jeffery 	}
298148761c62SAndrew Jeffery 
298248761c62SAndrew Jeffery 	for (i = 0, field = resp->field; i < comp_effecter_count;
298348761c62SAndrew Jeffery 	     i++, field++) {
298448761c62SAndrew Jeffery 		pldm_msgbuf_extract(buf, field->effecter_op_state);
298548761c62SAndrew Jeffery 		pldm_msgbuf_extract(buf, field->pending_state);
298648761c62SAndrew Jeffery 		pldm_msgbuf_extract(buf, field->present_state);
298748761c62SAndrew Jeffery 	}
298848761c62SAndrew Jeffery 
298948761c62SAndrew Jeffery 	return pldm_msgbuf_destroy_consumed(buf);
299048761c62SAndrew Jeffery }
299148761c62SAndrew Jeffery 
2992de67ab62STal Yacobi LIBPLDM_ABI_STABLE
encode_get_state_effecter_states_resp(uint8_t instance_id,struct pldm_get_state_effecter_states_resp * resp,struct pldm_msg * msg,size_t payload_length)299348761c62SAndrew Jeffery int encode_get_state_effecter_states_resp(
299448761c62SAndrew Jeffery 	uint8_t instance_id, struct pldm_get_state_effecter_states_resp *resp,
299548761c62SAndrew Jeffery 	struct pldm_msg *msg, size_t payload_length)
299648761c62SAndrew Jeffery {
299748761c62SAndrew Jeffery 	struct pldm_msgbuf _buf;
299848761c62SAndrew Jeffery 	struct pldm_msgbuf *buf = &_buf;
299948761c62SAndrew Jeffery 	get_effecter_state_field *field;
300048761c62SAndrew Jeffery 	int rc;
300148761c62SAndrew Jeffery 	int i;
300248761c62SAndrew Jeffery 
300348761c62SAndrew Jeffery 	if (msg == NULL || resp == NULL) {
3004f490a38fSTal Yacobi 		return -EINVAL;
300548761c62SAndrew Jeffery 	}
300648761c62SAndrew Jeffery 
300748761c62SAndrew Jeffery 	uint8_t comp_effecter_count = resp->comp_effecter_count;
300848761c62SAndrew Jeffery 
300948761c62SAndrew Jeffery 	if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN ||
301048761c62SAndrew Jeffery 	    comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) {
3011f490a38fSTal Yacobi 		return -EBADMSG;
301248761c62SAndrew Jeffery 	}
301348761c62SAndrew Jeffery 
301448761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
301548761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
301648761c62SAndrew Jeffery 	header.instance = instance_id;
301748761c62SAndrew Jeffery 	header.pldm_type = PLDM_PLATFORM;
301848761c62SAndrew Jeffery 	header.command = PLDM_GET_STATE_EFFECTER_STATES;
301948761c62SAndrew Jeffery 
3020f490a38fSTal Yacobi 	rc = pack_pldm_header_errno(&header, &msg->hdr);
3021f490a38fSTal Yacobi 	if (rc < 0) {
302248761c62SAndrew Jeffery 		return rc;
302348761c62SAndrew Jeffery 	}
302448761c62SAndrew Jeffery 
3025f490a38fSTal Yacobi 	rc = pldm_msgbuf_init_errno(
3026f490a38fSTal Yacobi 		buf, PLDM_GET_STATE_EFFECTER_STATES_MIN_RESP_BYTES,
302748761c62SAndrew Jeffery 		msg->payload, payload_length);
302848761c62SAndrew Jeffery 	if (rc) {
302948761c62SAndrew Jeffery 		return rc;
303048761c62SAndrew Jeffery 	}
303148761c62SAndrew Jeffery 
303248761c62SAndrew Jeffery 	pldm_msgbuf_insert(buf, resp->completion_code);
303348761c62SAndrew Jeffery 	pldm_msgbuf_insert(buf, comp_effecter_count);
303448761c62SAndrew Jeffery 
303548761c62SAndrew Jeffery 	for (i = 0, field = resp->field; i < comp_effecter_count;
303648761c62SAndrew Jeffery 	     i++, field++) {
303748761c62SAndrew Jeffery 		pldm_msgbuf_insert(buf, field->effecter_op_state);
303848761c62SAndrew Jeffery 		pldm_msgbuf_insert(buf, field->pending_state);
303948761c62SAndrew Jeffery 		pldm_msgbuf_insert(buf, field->present_state);
304048761c62SAndrew Jeffery 	}
304148761c62SAndrew Jeffery 
304248761c62SAndrew Jeffery 	return pldm_msgbuf_destroy_consumed(buf);
304348761c62SAndrew Jeffery }
3044dacfa354SThu Nguyen 
304543cb4b5fSThu Nguyen LIBPLDM_ABI_STABLE
decode_entity_auxiliary_names_pdr(const void * data,size_t data_length,struct pldm_entity_auxiliary_names_pdr * pdr,size_t pdr_length)3046dacfa354SThu Nguyen int decode_entity_auxiliary_names_pdr(
3047dacfa354SThu Nguyen 	const void *data, size_t data_length,
3048dacfa354SThu Nguyen 	struct pldm_entity_auxiliary_names_pdr *pdr, size_t pdr_length)
3049dacfa354SThu Nguyen {
3050dacfa354SThu Nguyen 	struct pldm_msgbuf _buf;
3051dacfa354SThu Nguyen 	struct pldm_msgbuf *buf = &_buf;
3052dacfa354SThu Nguyen 	struct pldm_msgbuf _src;
3053dacfa354SThu Nguyen 	struct pldm_msgbuf *src = &_src;
3054dacfa354SThu Nguyen 	struct pldm_msgbuf _dst;
3055dacfa354SThu Nguyen 	struct pldm_msgbuf *dst = &_dst;
3056dacfa354SThu Nguyen 	size_t names_len = 0;
3057dacfa354SThu Nguyen 	void *names = NULL;
3058dacfa354SThu Nguyen 	int rc;
3059dacfa354SThu Nguyen 	int i;
3060dacfa354SThu Nguyen 
306190bbe6c0SAndrew Jeffery 	if (!data || !pdr) {
306290bbe6c0SAndrew Jeffery 		return -EINVAL;
306390bbe6c0SAndrew Jeffery 	}
306490bbe6c0SAndrew Jeffery 
3065dacfa354SThu Nguyen 	/*
3066dacfa354SThu Nguyen 	 * Alignment of auxiliary_name_data is an invariant as we statically assert
3067dacfa354SThu Nguyen 	 * its behaviour in the header.
3068dacfa354SThu Nguyen 	 */
3069dacfa354SThu Nguyen 	assert(!((uintptr_t)pdr->auxiliary_name_data &
3070dacfa354SThu Nguyen 		 (alignof(pldm_utf16be) - 1)));
3071dacfa354SThu Nguyen 
3072dacfa354SThu Nguyen 	/* Reject any lengths that are obviously invalid */
3073dacfa354SThu Nguyen 	if (pdr_length < data_length || pdr_length < sizeof(*pdr)) {
3074dacfa354SThu Nguyen 		return -EINVAL;
3075dacfa354SThu Nguyen 	}
3076dacfa354SThu Nguyen 
3077dacfa354SThu Nguyen 	rc = pldm_msgbuf_init_errno(
3078dacfa354SThu Nguyen 		buf, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH, data,
3079dacfa354SThu Nguyen 		data_length);
3080dacfa354SThu Nguyen 	if (rc) {
3081dacfa354SThu Nguyen 		return rc;
3082dacfa354SThu Nguyen 	}
3083dacfa354SThu Nguyen 
3084329176a8SAndrew Jeffery 	rc = pldm_msgbuf_extract_value_pdr_hdr(
3085329176a8SAndrew Jeffery 		buf, &pdr->hdr, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH,
3086dacfa354SThu Nguyen 		data_length);
3087dacfa354SThu Nguyen 	if (rc) {
3088dacfa354SThu Nguyen 		return rc;
3089dacfa354SThu Nguyen 	}
3090dacfa354SThu Nguyen 
3091dacfa354SThu Nguyen 	pldm_msgbuf_extract(buf, pdr->container.entity_type);
3092dacfa354SThu Nguyen 	pldm_msgbuf_extract(buf, pdr->container.entity_instance_num);
3093dacfa354SThu Nguyen 	pldm_msgbuf_extract(buf, pdr->container.entity_container_id);
3094dacfa354SThu Nguyen 	pldm_msgbuf_extract(buf, pdr->shared_name_count);
3095dacfa354SThu Nguyen 	rc = pldm_msgbuf_extract(buf, pdr->name_string_count);
3096dacfa354SThu Nguyen 	if (rc < 0) {
3097dacfa354SThu Nguyen 		return rc;
3098dacfa354SThu Nguyen 	}
3099dacfa354SThu Nguyen 
3100dacfa354SThu Nguyen 	rc = pldm_msgbuf_span_remaining(buf, &names, &names_len);
3101dacfa354SThu Nguyen 	if (rc < 0) {
3102dacfa354SThu Nguyen 		return rc;
3103dacfa354SThu Nguyen 	}
310490bbe6c0SAndrew Jeffery 	assert(names);
3105dacfa354SThu Nguyen 
3106dacfa354SThu Nguyen 	pdr->auxiliary_name_data_size = pdr_length - sizeof(*pdr);
3107dacfa354SThu Nguyen 
3108dacfa354SThu Nguyen 	rc = pldm_msgbuf_init_errno(dst, pdr->auxiliary_name_data_size,
3109dacfa354SThu Nguyen 				    pdr->auxiliary_name_data,
3110dacfa354SThu Nguyen 				    pdr->auxiliary_name_data_size);
3111dacfa354SThu Nguyen 	if (rc < 0) {
3112dacfa354SThu Nguyen 		return rc;
3113dacfa354SThu Nguyen 	}
3114dacfa354SThu Nguyen 
3115dacfa354SThu Nguyen 	/*
3116dacfa354SThu Nguyen 	 * Below we do two passes over the same region. This is to first pack the
3117dacfa354SThu Nguyen 	 * UTF16-BE strings into auxiliary_name_data, followed by the ASCII strings,
3118dacfa354SThu Nguyen 	 * to maintain appropriate alignment.
3119dacfa354SThu Nguyen 	 */
3120dacfa354SThu Nguyen 
3121dacfa354SThu Nguyen 	/* Initialise for the first pass to extract the UTF16-BE name strings */
3122dacfa354SThu Nguyen 	rc = pldm_msgbuf_init_errno(src, names_len, names, names_len);
3123dacfa354SThu Nguyen 	if (rc < 0) {
3124dacfa354SThu Nguyen 		return rc;
3125dacfa354SThu Nguyen 	}
3126dacfa354SThu Nguyen 
3127dacfa354SThu Nguyen 	for (i = 0; i < pdr->name_string_count; i++) {
3128dacfa354SThu Nguyen 		pldm_msgbuf_span_string_ascii(src, NULL, NULL);
31290a1be3cbSAndrew Jeffery 		rc = pldm_msgbuf_copy_string_utf16(dst, src);
31300a1be3cbSAndrew Jeffery 		if (rc) {
31310a1be3cbSAndrew Jeffery 			return rc;
31320a1be3cbSAndrew Jeffery 		}
3133dacfa354SThu Nguyen 	}
3134dacfa354SThu Nguyen 
3135dacfa354SThu Nguyen 	rc = pldm_msgbuf_destroy_consumed(src);
3136dacfa354SThu Nguyen 	if (rc < 0) {
3137dacfa354SThu Nguyen 		return rc;
3138dacfa354SThu Nguyen 	}
3139dacfa354SThu Nguyen 
3140dacfa354SThu Nguyen 	/* Reinitialise for the second pass to extract the ASCII tag strings */
3141dacfa354SThu Nguyen 	rc = pldm_msgbuf_init_errno(src, names_len, names, names_len);
3142dacfa354SThu Nguyen 	if (rc < 0) {
3143dacfa354SThu Nguyen 		return rc;
3144dacfa354SThu Nguyen 	}
3145dacfa354SThu Nguyen 
3146dacfa354SThu Nguyen 	for (i = 0; i < pdr->name_string_count; i++) {
31470a1be3cbSAndrew Jeffery 		rc = pldm_msgbuf_copy_string_ascii(dst, src);
31480a1be3cbSAndrew Jeffery 		if (rc) {
31490a1be3cbSAndrew Jeffery 			return rc;
31500a1be3cbSAndrew Jeffery 		}
3151dacfa354SThu Nguyen 		pldm_msgbuf_span_string_utf16(src, NULL, NULL);
3152dacfa354SThu Nguyen 	}
3153dacfa354SThu Nguyen 
3154dacfa354SThu Nguyen 	if ((rc = pldm_msgbuf_destroy(dst)) ||
3155dacfa354SThu Nguyen 	    (rc = pldm_msgbuf_destroy(src)) ||
3156dacfa354SThu Nguyen 	    (rc = pldm_msgbuf_destroy(buf))) {
3157dacfa354SThu Nguyen 		return rc;
3158dacfa354SThu Nguyen 	}
3159dacfa354SThu Nguyen 
3160dacfa354SThu Nguyen 	return 0;
3161dacfa354SThu Nguyen }
3162dacfa354SThu Nguyen 
316343cb4b5fSThu Nguyen LIBPLDM_ABI_STABLE
decode_pldm_entity_auxiliary_names_pdr_index(struct pldm_entity_auxiliary_names_pdr * pdr)3164dacfa354SThu Nguyen int decode_pldm_entity_auxiliary_names_pdr_index(
3165dacfa354SThu Nguyen 	struct pldm_entity_auxiliary_names_pdr *pdr)
3166dacfa354SThu Nguyen {
3167dacfa354SThu Nguyen 	struct pldm_msgbuf _buf;
3168dacfa354SThu Nguyen 	struct pldm_msgbuf *buf = &_buf;
3169dacfa354SThu Nguyen 	int rc;
3170dacfa354SThu Nguyen 	int i;
3171dacfa354SThu Nguyen 
3172dacfa354SThu Nguyen 	if (!pdr) {
3173dacfa354SThu Nguyen 		return -EINVAL;
3174dacfa354SThu Nguyen 	}
3175dacfa354SThu Nguyen 
3176dacfa354SThu Nguyen 	if (pdr->name_string_count == 0 && pdr->names) {
3177dacfa354SThu Nguyen 		return -EINVAL;
3178dacfa354SThu Nguyen 	}
3179dacfa354SThu Nguyen 
3180dacfa354SThu Nguyen 	if (pdr->name_string_count > 0 && !pdr->names) {
3181dacfa354SThu Nguyen 		return -EINVAL;
3182dacfa354SThu Nguyen 	}
3183dacfa354SThu Nguyen 
3184dacfa354SThu Nguyen 	if (pdr->name_string_count == 0) {
3185dacfa354SThu Nguyen 		return 0;
3186dacfa354SThu Nguyen 	}
3187dacfa354SThu Nguyen 
3188dacfa354SThu Nguyen 	/*
3189dacfa354SThu Nguyen 	 * Minimum size is one NUL for each member of each entry
3190dacfa354SThu Nguyen 	 *
3191dacfa354SThu Nguyen 	 * Note that the definition of nameLanguageTag in DSP0248 v1.2.2
3192dacfa354SThu Nguyen 	 * states the following:
3193dacfa354SThu Nguyen 	 *
3194dacfa354SThu Nguyen 	 * > A null-terminated ISO646 ASCII string ...
3195dacfa354SThu Nguyen 	 * >
3196dacfa354SThu Nguyen 	 * > special value: null string = 0x0000 = unspecified.
3197dacfa354SThu Nguyen 	 *
3198dacfa354SThu Nguyen 	 * Until proven otherwise we will assume the "0x0000" is a
3199dacfa354SThu Nguyen 	 * misrepresentation of an ASCII NUL, and that ASCII NUL is
3200dacfa354SThu Nguyen 	 * represented by a single byte.
3201dacfa354SThu Nguyen 	 */
3202dacfa354SThu Nguyen 	rc = pldm_msgbuf_init_errno(
3203dacfa354SThu Nguyen 		buf, pdr->name_string_count * (sizeof(char) + sizeof(char16_t)),
3204dacfa354SThu Nguyen 		pdr->auxiliary_name_data, pdr->auxiliary_name_data_size);
3205dacfa354SThu Nguyen 	if (rc) {
3206dacfa354SThu Nguyen 		return rc;
3207dacfa354SThu Nguyen 	}
3208dacfa354SThu Nguyen 
3209dacfa354SThu Nguyen 	for (i = 0; i < pdr->name_string_count; i++) {
3210dacfa354SThu Nguyen 		void *loc = NULL;
3211dacfa354SThu Nguyen 		pldm_msgbuf_span_string_utf16(buf, &loc, NULL);
3212dacfa354SThu Nguyen 		pdr->names[i].name = loc;
3213dacfa354SThu Nguyen 	}
3214dacfa354SThu Nguyen 
3215dacfa354SThu Nguyen 	for (i = 0; i < pdr->name_string_count; i++) {
3216dacfa354SThu Nguyen 		void *loc = NULL;
3217dacfa354SThu Nguyen 		pldm_msgbuf_span_string_ascii(buf, &loc, NULL);
3218dacfa354SThu Nguyen 		pdr->names[i].tag = loc;
3219dacfa354SThu Nguyen 	}
3220dacfa354SThu Nguyen 
3221dacfa354SThu Nguyen 	return pldm_msgbuf_destroy_consumed(buf);
3222dacfa354SThu Nguyen }
3223a5d18dc7SThu Nguyen 
32243559aa1fSThu Nguyen LIBPLDM_ABI_STABLE
decode_pldm_platform_cper_event(const void * event_data,size_t event_data_length,struct pldm_platform_cper_event * cper_event,size_t cper_event_length)322502903038SThu Nguyen int decode_pldm_platform_cper_event(const void *event_data,
322602903038SThu Nguyen 				    size_t event_data_length,
322702903038SThu Nguyen 				    struct pldm_platform_cper_event *cper_event,
322802903038SThu Nguyen 				    size_t cper_event_length)
3229a5d18dc7SThu Nguyen {
3230a5d18dc7SThu Nguyen 	struct pldm_msgbuf _buf;
3231a5d18dc7SThu Nguyen 	struct pldm_msgbuf *buf = &_buf;
3232a5d18dc7SThu Nguyen 	int rc;
3233a5d18dc7SThu Nguyen 
3234a5d18dc7SThu Nguyen 	if (!cper_event || !event_data) {
3235a5d18dc7SThu Nguyen 		return -EINVAL;
3236a5d18dc7SThu Nguyen 	}
3237a5d18dc7SThu Nguyen 
3238a5d18dc7SThu Nguyen 	if (cper_event_length < sizeof(*cper_event)) {
3239a5d18dc7SThu Nguyen 		return -EINVAL;
3240a5d18dc7SThu Nguyen 	}
3241a5d18dc7SThu Nguyen 
3242a5d18dc7SThu Nguyen 	rc = pldm_msgbuf_init_errno(buf, PLDM_PLATFORM_CPER_EVENT_MIN_LENGTH,
3243a5d18dc7SThu Nguyen 				    event_data, event_data_length);
3244a5d18dc7SThu Nguyen 	if (rc) {
3245a5d18dc7SThu Nguyen 		return rc;
3246a5d18dc7SThu Nguyen 	}
3247a5d18dc7SThu Nguyen 
3248a5d18dc7SThu Nguyen 	pldm_msgbuf_extract(buf, cper_event->format_version);
3249a5d18dc7SThu Nguyen 	rc = pldm_msgbuf_extract(buf, cper_event->format_type);
3250a5d18dc7SThu Nguyen 	if (rc) {
3251a5d18dc7SThu Nguyen 		return rc;
3252a5d18dc7SThu Nguyen 	}
3253a5d18dc7SThu Nguyen 	if (cper_event->format_type != PLDM_PLATFORM_CPER_EVENT_WITH_HEADER &&
3254a5d18dc7SThu Nguyen 	    cper_event->format_type !=
3255a5d18dc7SThu Nguyen 		    PLDM_PLATFORM_CPER_EVENT_WITHOUT_HEADER) {
3256a5d18dc7SThu Nguyen 		return -EPROTO;
3257a5d18dc7SThu Nguyen 	}
3258a5d18dc7SThu Nguyen 
3259a5d18dc7SThu Nguyen 	rc = pldm_msgbuf_extract(buf, cper_event->event_data_length);
3260a5d18dc7SThu Nguyen 	if (rc) {
3261a5d18dc7SThu Nguyen 		return rc;
3262a5d18dc7SThu Nguyen 	}
3263a5d18dc7SThu Nguyen 
3264a5d18dc7SThu Nguyen 	if (cper_event->event_data_length >
3265a5d18dc7SThu Nguyen 	    (cper_event_length - sizeof(*cper_event))) {
3266a5d18dc7SThu Nguyen 		return -EOVERFLOW;
3267a5d18dc7SThu Nguyen 	}
3268a5d18dc7SThu Nguyen 
32690a1be3cbSAndrew Jeffery 	rc = pldm_msgbuf_extract_array_uint8(
32700a1be3cbSAndrew Jeffery 		buf, cper_event->event_data_length, cper_event->event_data,
32710a1be3cbSAndrew Jeffery 		cper_event_length - sizeof(*cper_event));
32720a1be3cbSAndrew Jeffery 	if (rc) {
32730a1be3cbSAndrew Jeffery 		return rc;
32740a1be3cbSAndrew Jeffery 	}
3275a5d18dc7SThu Nguyen 
3276a5d18dc7SThu Nguyen 	return pldm_msgbuf_destroy_consumed(buf);
3277a5d18dc7SThu Nguyen }
3278a5d18dc7SThu Nguyen 
32793559aa1fSThu Nguyen LIBPLDM_ABI_STABLE
3280a5d18dc7SThu Nguyen uint8_t *
pldm_platform_cper_event_event_data(struct pldm_platform_cper_event * event)3281a5d18dc7SThu Nguyen pldm_platform_cper_event_event_data(struct pldm_platform_cper_event *event)
3282a5d18dc7SThu Nguyen {
3283a5d18dc7SThu Nguyen 	return event->event_data;
3284a5d18dc7SThu Nguyen }
3285