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