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