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