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