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