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