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