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