blob: a781f3c43df7e514e788dba391b91086866f4b5d [file] [log] [blame]
Andrew Jeffery9c766792022-08-10 23:12:49 +09301#include <endian.h>
2#include <string.h>
3
4#include "platform.h"
5
6int encode_state_effecter_pdr(
7 struct pldm_state_effecter_pdr *const effecter,
8 const size_t allocation_size,
9 const struct state_effecter_possible_states *const possible_states,
10 const size_t possible_states_size, size_t *const actual_size)
11{
12 // Encode possible states
13
14 size_t calculated_possible_states_size = 0;
15
16 {
17 char *states_ptr = (char *)possible_states;
18 char *const begin_states_ptr = states_ptr;
19
20 for (int i = 0; i < effecter->composite_effecter_count; ++i) {
21 struct state_effecter_possible_states *states =
22 (struct state_effecter_possible_states *)states_ptr;
23
24 HTOLE16(states->state_set_id);
25
26 states_ptr +=
27 (sizeof(*states) - sizeof(states->states) +
28 states->possible_states_size);
29 }
30
31 calculated_possible_states_size = states_ptr - begin_states_ptr;
32 }
33
34 // Check lengths
35
36 if (possible_states_size != calculated_possible_states_size) {
37 *actual_size = 0;
38 return PLDM_ERROR;
39 }
40
41 *actual_size =
42 (sizeof(struct pldm_state_effecter_pdr) + possible_states_size -
43 sizeof(effecter->possible_states));
44
45 if (allocation_size < *actual_size) {
46 *actual_size = 0;
47 return PLDM_ERROR_INVALID_LENGTH;
48 }
49
50 // Encode rest of PDR
51
52 effecter->hdr.version = 1;
53 effecter->hdr.type = PLDM_STATE_EFFECTER_PDR;
54 effecter->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
55
56 memcpy(effecter->possible_states, possible_states,
57 possible_states_size);
58
59 // Convert effecter PDR body
60 HTOLE16(effecter->terminus_handle);
61 HTOLE16(effecter->effecter_id);
62 HTOLE16(effecter->entity_type);
63 HTOLE16(effecter->entity_instance);
64 HTOLE16(effecter->container_id);
65 HTOLE16(effecter->effecter_semantic_id);
66
67 // Convert header
68 HTOLE32(effecter->hdr.record_handle);
69 HTOLE16(effecter->hdr.record_change_num);
70 HTOLE16(effecter->hdr.length);
71
72 return PLDM_SUCCESS;
73}
74
75int encode_state_sensor_pdr(
76 struct pldm_state_sensor_pdr *const sensor, const size_t allocation_size,
77 const struct state_sensor_possible_states *const possible_states,
78 const size_t possible_states_size, size_t *const actual_size)
79{
80 // Encode possible states
81
82 size_t calculated_possible_states_size = 0;
83
84 {
85 char *states_ptr = (char *)possible_states,
86 *const begin_states_ptr = states_ptr;
87
88 for (int i = 0; i < sensor->composite_sensor_count; ++i) {
89 struct state_sensor_possible_states *states =
90 (struct state_sensor_possible_states *)states_ptr;
91
92 HTOLE16(states->state_set_id);
93
94 states_ptr +=
95 (sizeof(*states) - sizeof(states->states) +
96 states->possible_states_size);
97 }
98
99 calculated_possible_states_size = states_ptr - begin_states_ptr;
100 }
101
102 // Check lengths
103
104 if (possible_states_size != calculated_possible_states_size) {
105 *actual_size = 0;
106 return PLDM_ERROR;
107 }
108
109 *actual_size = (sizeof(struct pldm_state_sensor_pdr) +
110 possible_states_size - sizeof(sensor->possible_states));
111
112 if (allocation_size < *actual_size) {
113 *actual_size = 0;
114 return PLDM_ERROR_INVALID_LENGTH;
115 }
116
117 // Encode rest of PDR
118
119 sensor->hdr.version = 1;
120 sensor->hdr.type = PLDM_STATE_SENSOR_PDR;
121 sensor->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
122
123 memcpy(sensor->possible_states, possible_states, possible_states_size);
124
125 // Convert sensor PDR body
126 HTOLE16(sensor->terminus_handle);
127 HTOLE16(sensor->sensor_id);
128 HTOLE16(sensor->entity_type);
129 HTOLE16(sensor->entity_instance);
130 HTOLE16(sensor->container_id);
131
132 // Convert header
133 HTOLE32(sensor->hdr.record_handle);
134 HTOLE16(sensor->hdr.record_change_num);
135 HTOLE16(sensor->hdr.length);
136
137 return PLDM_SUCCESS;
138}
139
140int encode_set_state_effecter_states_resp(uint8_t instance_id,
141 uint8_t completion_code,
142 struct pldm_msg *msg)
143{
144 if (msg == NULL) {
145 return PLDM_ERROR_INVALID_DATA;
146 }
147
148 struct pldm_header_info header = {0};
149 header.msg_type = PLDM_RESPONSE;
150 header.instance = instance_id;
151 header.pldm_type = PLDM_PLATFORM;
152 header.command = PLDM_SET_STATE_EFFECTER_STATES;
153
154 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
155 if (rc != PLDM_SUCCESS) {
156 return rc;
157 }
158
159 msg->payload[0] = completion_code;
160
161 return PLDM_SUCCESS;
162}
163
164int encode_set_state_effecter_states_req(uint8_t instance_id,
165 uint16_t effecter_id,
166 uint8_t comp_effecter_count,
167 set_effecter_state_field *field,
168 struct pldm_msg *msg)
169{
170 if (msg == NULL) {
171 return PLDM_ERROR_INVALID_DATA;
172 }
173
174 if (comp_effecter_count < 0x1 || comp_effecter_count > 0x8 ||
175 field == NULL) {
176 return PLDM_ERROR_INVALID_DATA;
177 }
178
179 struct pldm_header_info header = {0};
180 header.msg_type = PLDM_REQUEST;
181 header.instance = instance_id;
182 header.pldm_type = PLDM_PLATFORM;
183 header.command = PLDM_SET_STATE_EFFECTER_STATES;
184
185 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
186 if (rc != PLDM_SUCCESS) {
187 return rc;
188 }
189
190 struct pldm_set_state_effecter_states_req *request =
191 (struct pldm_set_state_effecter_states_req *)msg->payload;
192 effecter_id = htole16(effecter_id);
193 request->effecter_id = effecter_id;
194 request->comp_effecter_count = comp_effecter_count;
195 memcpy(request->field, field,
196 (sizeof(set_effecter_state_field) * comp_effecter_count));
197
198 return PLDM_SUCCESS;
199}
200
201int decode_set_state_effecter_states_resp(const struct pldm_msg *msg,
202 size_t payload_length,
203 uint8_t *completion_code)
204{
205 if (msg == NULL || completion_code == NULL) {
206 return PLDM_ERROR_INVALID_DATA;
207 }
208
209 *completion_code = msg->payload[0];
210 if (PLDM_SUCCESS != *completion_code) {
211 return PLDM_SUCCESS;
212 }
213
214 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES) {
215 return PLDM_ERROR_INVALID_LENGTH;
216 }
217
218 return PLDM_SUCCESS;
219}
220
221int decode_set_state_effecter_states_req(const struct pldm_msg *msg,
222 size_t payload_length,
223 uint16_t *effecter_id,
224 uint8_t *comp_effecter_count,
225 set_effecter_state_field *field)
226{
227 if (msg == NULL || effecter_id == NULL || comp_effecter_count == NULL ||
228 field == NULL) {
229 return PLDM_ERROR_INVALID_DATA;
230 }
231
232 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) {
233 return PLDM_ERROR_INVALID_LENGTH;
234 }
235
236 struct pldm_set_state_effecter_states_req *request =
237 (struct pldm_set_state_effecter_states_req *)msg->payload;
238
239 *effecter_id = le16toh(request->effecter_id);
240 *comp_effecter_count = request->comp_effecter_count;
241 memcpy(field, request->field,
242 (sizeof(set_effecter_state_field) * (*comp_effecter_count)));
243
244 return PLDM_SUCCESS;
245}
246
247int decode_get_pdr_req(const struct pldm_msg *msg, size_t payload_length,
248 uint32_t *record_hndl, uint32_t *data_transfer_hndl,
249 uint8_t *transfer_op_flag, uint16_t *request_cnt,
250 uint16_t *record_chg_num)
251{
252 if (msg == NULL || record_hndl == NULL || data_transfer_hndl == NULL ||
253 transfer_op_flag == NULL || request_cnt == NULL ||
254 record_chg_num == NULL) {
255 return PLDM_ERROR_INVALID_DATA;
256 }
257 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
258 return PLDM_ERROR_INVALID_LENGTH;
259 }
260
261 struct pldm_get_pdr_req *request =
262 (struct pldm_get_pdr_req *)msg->payload;
263 *record_hndl = le32toh(request->record_handle);
264 *data_transfer_hndl = le32toh(request->data_transfer_handle);
265 *transfer_op_flag = request->transfer_op_flag;
266 *request_cnt = le16toh(request->request_count);
267 *record_chg_num = le16toh(request->record_change_number);
268
269 return PLDM_SUCCESS;
270}
271
272int encode_get_pdr_resp(uint8_t instance_id, uint8_t completion_code,
273 uint32_t next_record_hndl,
274 uint32_t next_data_transfer_hndl, uint8_t transfer_flag,
275 uint16_t resp_cnt, const uint8_t *record_data,
276 uint8_t transfer_crc, struct pldm_msg *msg)
277{
278 if (msg == NULL) {
279 return PLDM_ERROR_INVALID_DATA;
280 }
281
282 struct pldm_header_info header = {0};
283 header.msg_type = PLDM_RESPONSE;
284 header.instance = instance_id;
285 header.pldm_type = PLDM_PLATFORM;
286 header.command = PLDM_GET_PDR;
287
288 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
289 if (rc != PLDM_SUCCESS) {
290 return rc;
291 }
292
293 struct pldm_get_pdr_resp *response =
294 (struct pldm_get_pdr_resp *)msg->payload;
295 response->completion_code = completion_code;
296
297 if (response->completion_code == PLDM_SUCCESS) {
298 response->next_record_handle = htole32(next_record_hndl);
299 response->next_data_transfer_handle =
300 htole32(next_data_transfer_hndl);
301 response->transfer_flag = transfer_flag;
302 response->response_count = htole16(resp_cnt);
303 if (record_data != NULL && resp_cnt > 0) {
304 memcpy(response->record_data, record_data, resp_cnt);
305 }
306 if (transfer_flag == PLDM_END) {
307 uint8_t *dst = msg->payload;
308 dst +=
309 (sizeof(struct pldm_get_pdr_resp) - 1) + resp_cnt;
310 *dst = transfer_crc;
311 }
312 }
313
314 return PLDM_SUCCESS;
315}
316
317int encode_get_pdr_repository_info_resp(
318 uint8_t instance_id, uint8_t completion_code, uint8_t repository_state,
319 const uint8_t *update_time, const uint8_t *oem_update_time,
320 uint32_t record_count, uint32_t repository_size,
321 uint32_t largest_record_size, uint8_t data_transfer_handle_timeout,
322 struct pldm_msg *msg)
323{
324 if (msg == NULL) {
325 return PLDM_ERROR_INVALID_DATA;
326 }
327
328 struct pldm_header_info header = {0};
329 header.msg_type = PLDM_RESPONSE;
330 header.instance = instance_id;
331 header.pldm_type = PLDM_PLATFORM;
332 header.command = PLDM_GET_PDR_REPOSITORY_INFO;
333
334 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
335 if (rc != PLDM_SUCCESS) {
336 return rc;
337 }
338
339 struct pldm_pdr_repository_info_resp *response =
340 (struct pldm_pdr_repository_info_resp *)msg->payload;
341 response->completion_code = completion_code;
342
343 if (response->completion_code == PLDM_SUCCESS) {
344 response->repository_state = repository_state;
345 if (update_time != NULL) {
346 memcpy(response->update_time, update_time,
347 PLDM_TIMESTAMP104_SIZE);
348 }
349 if (oem_update_time != NULL) {
350 memcpy(response->oem_update_time, oem_update_time,
351 PLDM_TIMESTAMP104_SIZE);
352 }
353 response->record_count = htole32(record_count);
354 response->repository_size = htole32(repository_size);
355 response->largest_record_size = htole32(largest_record_size);
356 response->data_transfer_handle_timeout =
357 data_transfer_handle_timeout;
358 }
359
360 return PLDM_SUCCESS;
361}
362
363int encode_get_pdr_req(uint8_t instance_id, uint32_t record_hndl,
364 uint32_t data_transfer_hndl, uint8_t transfer_op_flag,
365 uint16_t request_cnt, uint16_t record_chg_num,
366 struct pldm_msg *msg, size_t payload_length)
367{
368 if (msg == NULL) {
369 return PLDM_ERROR_INVALID_DATA;
370 }
371
372 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
373 return PLDM_ERROR_INVALID_LENGTH;
374 }
375
376 struct pldm_header_info header = {0};
377 header.msg_type = PLDM_REQUEST;
378 header.instance = instance_id;
379 header.pldm_type = PLDM_PLATFORM;
380 header.command = PLDM_GET_PDR;
381
382 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
383 if (rc != PLDM_SUCCESS) {
384 return rc;
385 }
386
387 struct pldm_get_pdr_req *request =
388 (struct pldm_get_pdr_req *)msg->payload;
389 request->record_handle = htole32(record_hndl);
390 request->data_transfer_handle = htole32(data_transfer_hndl);
391 request->transfer_op_flag = transfer_op_flag;
392 request->request_count = htole16(request_cnt);
393 request->record_change_number = htole16(record_chg_num);
394
395 return PLDM_SUCCESS;
396}
397
398int decode_get_pdr_resp(const struct pldm_msg *msg, size_t payload_length,
399 uint8_t *completion_code, uint32_t *next_record_hndl,
400 uint32_t *next_data_transfer_hndl,
401 uint8_t *transfer_flag, uint16_t *resp_cnt,
402 uint8_t *record_data, size_t record_data_length,
403 uint8_t *transfer_crc)
404{
405 if (msg == NULL || completion_code == NULL ||
406 next_record_hndl == NULL || next_data_transfer_hndl == NULL ||
407 transfer_flag == NULL || resp_cnt == NULL || transfer_crc == NULL) {
408 return PLDM_ERROR_INVALID_DATA;
409 }
410
411 *completion_code = msg->payload[0];
412 if (PLDM_SUCCESS != *completion_code) {
413 return PLDM_SUCCESS;
414 }
415
416 if (payload_length < PLDM_GET_PDR_MIN_RESP_BYTES) {
417 return PLDM_ERROR_INVALID_LENGTH;
418 }
419
420 struct pldm_get_pdr_resp *response =
421 (struct pldm_get_pdr_resp *)msg->payload;
422
423 *next_record_hndl = le32toh(response->next_record_handle);
424 *next_data_transfer_hndl = le32toh(response->next_data_transfer_handle);
425 *transfer_flag = response->transfer_flag;
426 *resp_cnt = le16toh(response->response_count);
427
428 if (*transfer_flag != PLDM_END &&
429 (int)payload_length != PLDM_GET_PDR_MIN_RESP_BYTES + *resp_cnt) {
430 return PLDM_ERROR_INVALID_LENGTH;
431 }
432
433 if (*transfer_flag == PLDM_END &&
434 (int)payload_length !=
435 PLDM_GET_PDR_MIN_RESP_BYTES + *resp_cnt + 1) {
436 return PLDM_ERROR_INVALID_LENGTH;
437 }
438
439 if (*resp_cnt > 0 && record_data != NULL) {
440 if (record_data_length < *resp_cnt) {
441 return PLDM_ERROR_INVALID_LENGTH;
442 }
443 memcpy(record_data, response->record_data, *resp_cnt);
444 }
445
446 if (*transfer_flag == PLDM_END) {
447 *transfer_crc =
448 msg->payload[PLDM_GET_PDR_MIN_RESP_BYTES + *resp_cnt];
449 }
450
451 return PLDM_SUCCESS;
452}
453
454int decode_set_numeric_effecter_value_req(const struct pldm_msg *msg,
455 size_t payload_length,
456 uint16_t *effecter_id,
457 uint8_t *effecter_data_size,
458 uint8_t *effecter_value)
459{
460 if (msg == NULL || effecter_id == NULL || effecter_data_size == NULL ||
461 effecter_value == NULL) {
462 return PLDM_ERROR_INVALID_DATA;
463 }
464
465 if (payload_length < PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) {
466 return PLDM_ERROR_INVALID_LENGTH;
467 }
468
469 struct pldm_set_numeric_effecter_value_req *request =
470 (struct pldm_set_numeric_effecter_value_req *)msg->payload;
471 *effecter_id = le16toh(request->effecter_id);
472 *effecter_data_size = request->effecter_data_size;
473
474 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
475 return PLDM_ERROR_INVALID_DATA;
476 }
477
478 if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
479 *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
480
481 if (payload_length !=
482 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) {
483 return PLDM_ERROR_INVALID_LENGTH;
484 }
485
486 *effecter_value = request->effecter_value[0];
487 }
488
489 if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
490 *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
491
492 if (payload_length !=
493 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1) {
494 return PLDM_ERROR_INVALID_LENGTH;
495 }
496
497 memcpy(effecter_value, request->effecter_value, 2);
498 uint16_t *val = (uint16_t *)(effecter_value);
499 *val = le16toh(*val);
500 }
501
502 if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
503 *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
504
505 if (payload_length !=
506 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3) {
507 return PLDM_ERROR_INVALID_LENGTH;
508 }
509
510 memcpy(effecter_value, request->effecter_value, 4);
511 uint32_t *val = (uint32_t *)(effecter_value);
512 *val = le32toh(*val);
513 }
514
515 return PLDM_SUCCESS;
516}
517
518int encode_set_numeric_effecter_value_resp(uint8_t instance_id,
519 uint8_t completion_code,
520 struct pldm_msg *msg,
521 size_t payload_length)
522{
523 if (msg == NULL) {
524 return PLDM_ERROR_INVALID_DATA;
525 }
526
527 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
528 return PLDM_ERROR_INVALID_LENGTH;
529 }
530
531 struct pldm_header_info header = {0};
532 header.msg_type = PLDM_RESPONSE;
533 header.instance = instance_id;
534 header.pldm_type = PLDM_PLATFORM;
535 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
536
537 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
538 if (rc != PLDM_SUCCESS) {
539 return rc;
540 }
541
542 msg->payload[0] = completion_code;
543
544 return rc;
545}
546
547int encode_set_numeric_effecter_value_req(
548 uint8_t instance_id, uint16_t effecter_id, uint8_t effecter_data_size,
549 uint8_t *effecter_value, struct pldm_msg *msg, size_t payload_length)
550{
551 if (msg == NULL || effecter_value == NULL) {
552 return PLDM_ERROR_INVALID_DATA;
553 }
554
555 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
556 return PLDM_ERROR_INVALID_DATA;
557 }
558
559 struct pldm_header_info header = {0};
560 header.msg_type = PLDM_REQUEST;
561 header.instance = instance_id;
562 header.pldm_type = PLDM_PLATFORM;
563 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
564
565 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
566 if (rc != PLDM_SUCCESS) {
567 return rc;
568 }
569
570 struct pldm_set_numeric_effecter_value_req *request =
571 (struct pldm_set_numeric_effecter_value_req *)msg->payload;
572 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
573 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
574 if (payload_length !=
575 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) {
576 return PLDM_ERROR_INVALID_LENGTH;
577 }
578 request->effecter_value[0] = *effecter_value;
579 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
580 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
581 if (payload_length !=
582 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1) {
583 return PLDM_ERROR_INVALID_LENGTH;
584 }
585
586 uint16_t val = *(uint16_t *)(effecter_value);
587 val = htole16(val);
588 memcpy(request->effecter_value, &val, sizeof(uint16_t));
589
590 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
591 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
592 if (payload_length !=
593 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3) {
594 return PLDM_ERROR_INVALID_LENGTH;
595 }
596
597 uint32_t val = *(uint32_t *)(effecter_value);
598 val = htole32(val);
599 memcpy(request->effecter_value, &val, sizeof(uint32_t));
600 }
601
602 request->effecter_id = htole16(effecter_id);
603 request->effecter_data_size = effecter_data_size;
604
605 return PLDM_SUCCESS;
606}
607
608int decode_set_numeric_effecter_value_resp(const struct pldm_msg *msg,
609 size_t payload_length,
610 uint8_t *completion_code)
611{
612 if (msg == NULL || completion_code == NULL) {
613 return PLDM_ERROR_INVALID_DATA;
614 }
615
616 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
617 return PLDM_ERROR_INVALID_LENGTH;
618 }
619
620 *completion_code = msg->payload[0];
621
622 return PLDM_SUCCESS;
623}
624
625int encode_get_state_sensor_readings_resp(uint8_t instance_id,
626 uint8_t completion_code,
627 uint8_t comp_sensor_count,
628 get_sensor_state_field *field,
629 struct pldm_msg *msg)
630{
631 if (msg == NULL) {
632 return PLDM_ERROR_INVALID_DATA;
633 }
634
635 if (comp_sensor_count < 0x1 || comp_sensor_count > 0x8) {
636 return PLDM_ERROR_INVALID_DATA;
637 }
638
639 struct pldm_header_info header = {0};
640 header.msg_type = PLDM_RESPONSE;
641 header.instance = instance_id;
642 header.pldm_type = PLDM_PLATFORM;
643 header.command = PLDM_GET_STATE_SENSOR_READINGS;
644
645 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
646 if (rc != PLDM_SUCCESS) {
647 return rc;
648 }
649
650 struct pldm_get_state_sensor_readings_resp *response =
651 (struct pldm_get_state_sensor_readings_resp *)msg->payload;
652
653 response->completion_code = completion_code;
654 response->comp_sensor_count = comp_sensor_count;
655 memcpy(response->field, field,
656 (sizeof(get_sensor_state_field) * comp_sensor_count));
657
658 return PLDM_SUCCESS;
659}
660
661int encode_get_state_sensor_readings_req(uint8_t instance_id,
662 uint16_t sensor_id,
663 bitfield8_t sensor_rearm,
664 uint8_t reserved, struct pldm_msg *msg)
665{
666 if (msg == NULL) {
667 return PLDM_ERROR_INVALID_DATA;
668 }
669
670 struct pldm_header_info header = {0};
671 header.msg_type = PLDM_REQUEST;
672 header.instance = instance_id;
673 header.pldm_type = PLDM_PLATFORM;
674 header.command = PLDM_GET_STATE_SENSOR_READINGS;
675
676 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
677 if (rc != PLDM_SUCCESS) {
678 return rc;
679 }
680
681 struct pldm_get_state_sensor_readings_req *request =
682 (struct pldm_get_state_sensor_readings_req *)msg->payload;
683
684 request->sensor_id = htole16(sensor_id);
685 request->reserved = reserved;
686 request->sensor_rearm = sensor_rearm;
687
688 return PLDM_SUCCESS;
689}
690
691int decode_get_state_sensor_readings_resp(const struct pldm_msg *msg,
692 size_t payload_length,
693 uint8_t *completion_code,
694 uint8_t *comp_sensor_count,
695 get_sensor_state_field *field)
696{
697 if (msg == NULL || completion_code == NULL ||
698 comp_sensor_count == NULL || field == NULL) {
699 return PLDM_ERROR_INVALID_DATA;
700 }
701
702 *completion_code = msg->payload[0];
703 if (PLDM_SUCCESS != *completion_code) {
704 return PLDM_SUCCESS;
705 }
706
707 struct pldm_get_state_sensor_readings_resp *response =
708 (struct pldm_get_state_sensor_readings_resp *)msg->payload;
709
710 if (response->comp_sensor_count < 0x1 ||
711 response->comp_sensor_count > 0x8) {
712 return PLDM_ERROR_INVALID_DATA;
713 }
714
715 if (payload_length >
716 PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES +
717 sizeof(get_sensor_state_field) * response->comp_sensor_count) {
718 return PLDM_ERROR_INVALID_LENGTH;
719 }
720
721 *comp_sensor_count = response->comp_sensor_count;
722
723 memcpy(field, response->field,
724 (sizeof(get_sensor_state_field) * (*comp_sensor_count)));
725
726 return PLDM_SUCCESS;
727}
728
729int decode_get_state_sensor_readings_req(const struct pldm_msg *msg,
730 size_t payload_length,
731 uint16_t *sensor_id,
732 bitfield8_t *sensor_rearm,
733 uint8_t *reserved)
734{
735 if (msg == NULL || sensor_id == NULL || sensor_rearm == NULL) {
736 return PLDM_ERROR_INVALID_DATA;
737 }
738
739 if (payload_length != PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES) {
740 return PLDM_ERROR_INVALID_LENGTH;
741 }
742
743 struct pldm_get_state_sensor_readings_req *request =
744 (struct pldm_get_state_sensor_readings_req *)msg->payload;
745
746 *sensor_id = le16toh(request->sensor_id);
747 *reserved = request->reserved;
748 memcpy(&(sensor_rearm->byte), &(request->sensor_rearm.byte),
749 sizeof(request->sensor_rearm.byte));
750
751 return PLDM_SUCCESS;
752}
753
754int encode_sensor_event_data(
755 struct pldm_sensor_event_data *const event_data,
756 const size_t event_data_size, const uint16_t sensor_id,
757 const enum sensor_event_class_states sensor_event_class,
758 const uint8_t sensor_offset, const uint8_t event_state,
759 const uint8_t previous_event_state, size_t *const actual_event_data_size)
760{
761 *actual_event_data_size =
762 (sizeof(*event_data) - sizeof(event_data->event_class) +
763 sizeof(struct pldm_sensor_event_state_sensor_state));
764
765 if (!event_data) {
766 return PLDM_SUCCESS;
767 }
768
769 if (event_data_size < *actual_event_data_size) {
770 *actual_event_data_size = 0;
771 return PLDM_ERROR_INVALID_LENGTH;
772 }
773
774 event_data->sensor_id = htole16(sensor_id);
775 event_data->sensor_event_class_type = sensor_event_class;
776
777 struct pldm_sensor_event_state_sensor_state *const state_data =
778 (struct pldm_sensor_event_state_sensor_state *)
779 event_data->event_class;
780
781 state_data->sensor_offset = sensor_offset;
782 state_data->event_state = event_state;
783 state_data->previous_event_state = previous_event_state;
784
785 return PLDM_SUCCESS;
786}
787
788int decode_platform_event_message_req(const struct pldm_msg *msg,
789 size_t payload_length,
790 uint8_t *format_version, uint8_t *tid,
791 uint8_t *event_class,
792 size_t *event_data_offset)
793{
794
795 if (msg == NULL || format_version == NULL || tid == NULL ||
796 event_class == NULL || event_data_offset == NULL) {
797 return PLDM_ERROR_INVALID_DATA;
798 }
799
800 if (payload_length <= PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) {
801 return PLDM_ERROR_INVALID_LENGTH;
802 }
803 struct pldm_platform_event_message_req *response =
804 (struct pldm_platform_event_message_req *)msg->payload;
805
806 *format_version = response->format_version;
807 *tid = response->tid;
808 *event_class = response->event_class;
809 *event_data_offset =
810 sizeof(*format_version) + sizeof(*tid) + sizeof(*event_class);
811
812 return PLDM_SUCCESS;
813}
814
815int encode_platform_event_message_resp(uint8_t instance_id,
816 uint8_t completion_code,
817 uint8_t platform_event_status,
818 struct pldm_msg *msg)
819{
820 if (msg == NULL) {
821 return PLDM_ERROR_INVALID_DATA;
822 }
823
824 if (platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
825 return PLDM_ERROR_INVALID_DATA;
826 }
827
828 struct pldm_header_info header = {0};
829 header.msg_type = PLDM_RESPONSE;
830 header.instance = instance_id;
831 header.pldm_type = PLDM_PLATFORM;
832 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
833
834 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
835 if (rc != PLDM_SUCCESS) {
836 return rc;
837 }
838
839 struct pldm_platform_event_message_resp *response =
840 (struct pldm_platform_event_message_resp *)msg->payload;
841 response->completion_code = completion_code;
842 response->platform_event_status = platform_event_status;
843
844 return PLDM_SUCCESS;
845}
846
847int encode_platform_event_message_req(
848 uint8_t instance_id, uint8_t format_version, uint8_t tid,
849 uint8_t event_class, const uint8_t *event_data, size_t event_data_length,
850 struct pldm_msg *msg, size_t payload_length)
851
852{
853 if (format_version != 1) {
854 return PLDM_ERROR_INVALID_DATA;
855 }
856
857 if (msg == NULL || event_data == NULL) {
858 return PLDM_ERROR_INVALID_DATA;
859 }
860
861 if (event_data_length == 0) {
862 return PLDM_ERROR_INVALID_DATA;
863 }
864
865 if (payload_length !=
866 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) {
867 return PLDM_ERROR_INVALID_LENGTH;
868 }
869
870 if (event_class > PLDM_HEARTBEAT_TIMER_ELAPSED_EVENT &&
871 !(event_class >= 0xF0 && event_class <= 0xFE)) {
872 return PLDM_ERROR_INVALID_DATA;
873 }
874
875 struct pldm_header_info header = {0};
876 header.msg_type = PLDM_REQUEST;
877 header.instance = instance_id;
878 header.pldm_type = PLDM_PLATFORM;
879 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
880
881 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
882 if (rc != PLDM_SUCCESS) {
883 return rc;
884 }
885
886 struct pldm_platform_event_message_req *request =
887 (struct pldm_platform_event_message_req *)msg->payload;
888 request->format_version = format_version;
889 request->tid = tid;
890 request->event_class = event_class;
891 memcpy(request->event_data, event_data, event_data_length);
892
893 return PLDM_SUCCESS;
894}
895
896int decode_platform_event_message_resp(const struct pldm_msg *msg,
897 size_t payload_length,
898 uint8_t *completion_code,
899 uint8_t *platform_event_status)
900{
901 if (msg == NULL || completion_code == NULL ||
902 platform_event_status == NULL) {
903 return PLDM_ERROR_INVALID_DATA;
904 }
905
906 *completion_code = msg->payload[0];
907 if (PLDM_SUCCESS != *completion_code) {
908 return PLDM_SUCCESS;
909 }
910 if (payload_length != PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES) {
911 return PLDM_ERROR_INVALID_LENGTH;
912 }
913
914 struct pldm_platform_event_message_resp *response =
915 (struct pldm_platform_event_message_resp *)msg->payload;
916 *platform_event_status = response->platform_event_status;
917
918 if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
919 return PLDM_ERROR_INVALID_DATA;
920 }
921
922 return PLDM_SUCCESS;
923}
924
Dung Caod6ae8982022-11-02 10:00:10 +0700925int encode_event_message_buffer_size_req(
926 uint8_t instance_id, uint16_t event_receiver_max_buffer_size,
927 struct pldm_msg *msg)
928{
929 struct pldm_header_info header = {0};
930 header.msg_type = PLDM_REQUEST;
931 header.instance = instance_id;
932 header.pldm_type = PLDM_PLATFORM;
933 header.command = PLDM_EVENT_MESSAGE_BUFFER_SIZE;
934
935 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
936 if (rc != PLDM_SUCCESS) {
937 return rc;
938 }
939
940 struct pldm_event_message_buffer_size_req *request =
941 (struct pldm_event_message_buffer_size_req *)msg->payload;
942 request->event_receiver_max_buffer_size =
943 event_receiver_max_buffer_size;
944
945 return PLDM_SUCCESS;
946}
947
948int decode_event_message_buffer_size_resp(const struct pldm_msg *msg,
949 size_t payload_length,
950 uint8_t *completion_code,
951 uint16_t *terminus_max_buffer_size)
952{
953 if (msg == NULL || completion_code == NULL ||
954 terminus_max_buffer_size == NULL) {
955 return PLDM_ERROR_INVALID_DATA;
956 }
957
958 *completion_code = msg->payload[0];
959 if (PLDM_SUCCESS != *completion_code) {
960 return PLDM_SUCCESS;
961 }
962 if (payload_length != PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES) {
963 return PLDM_ERROR_INVALID_LENGTH;
964 }
965
966 struct pldm_event_message_buffer_size_resp *response =
967 (struct pldm_event_message_buffer_size_resp *)msg->payload;
968
969 *terminus_max_buffer_size = response->terminus_max_buffer_size;
970
971 return PLDM_SUCCESS;
972}
973
Andrew Jeffery9c766792022-08-10 23:12:49 +0930974int decode_sensor_event_data(const uint8_t *event_data,
975 size_t event_data_length, uint16_t *sensor_id,
976 uint8_t *sensor_event_class_type,
977 size_t *event_class_data_offset)
978{
979 if (event_data == NULL) {
980 return PLDM_ERROR_INVALID_DATA;
981 }
982 if (event_data_length < PLDM_SENSOR_EVENT_DATA_MIN_LENGTH) {
983 return PLDM_ERROR_INVALID_LENGTH;
984 }
985
986 size_t event_class_data_length =
987 event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES;
988
989 struct pldm_sensor_event_data *sensor_event_data =
990 (struct pldm_sensor_event_data *)event_data;
991 *sensor_id = sensor_event_data->sensor_id;
992 *sensor_event_class_type = sensor_event_data->sensor_event_class_type;
993 if (sensor_event_data->sensor_event_class_type ==
994 PLDM_SENSOR_OP_STATE) {
995 if (event_class_data_length !=
996 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
997 return PLDM_ERROR_INVALID_LENGTH;
998 }
999 } else if (sensor_event_data->sensor_event_class_type ==
1000 PLDM_STATE_SENSOR_STATE) {
1001 if (event_class_data_length !=
1002 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
1003 return PLDM_ERROR_INVALID_LENGTH;
1004 }
1005 } else if (sensor_event_data->sensor_event_class_type ==
1006 PLDM_NUMERIC_SENSOR_STATE) {
1007 if (event_class_data_length <
1008 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
1009 event_class_data_length >
1010 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
1011 return PLDM_ERROR_INVALID_LENGTH;
1012 }
1013 } else {
1014 return PLDM_ERROR_INVALID_DATA;
1015 }
1016 *event_class_data_offset =
1017 sizeof(*sensor_id) + sizeof(*sensor_event_class_type);
1018 return PLDM_SUCCESS;
1019}
1020
1021int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length,
1022 uint8_t *present_op_state, uint8_t *previous_op_state)
1023{
1024 if (sensor_data == NULL || present_op_state == NULL ||
1025 previous_op_state == NULL) {
1026 return PLDM_ERROR_INVALID_DATA;
1027 }
1028 if (sensor_data_length !=
1029 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
1030 return PLDM_ERROR_INVALID_LENGTH;
1031 }
1032
1033 struct pldm_sensor_event_sensor_op_state *sensor_op_data =
1034 (struct pldm_sensor_event_sensor_op_state *)sensor_data;
1035 *present_op_state = sensor_op_data->present_op_state;
1036 *previous_op_state = sensor_op_data->previous_op_state;
1037 return PLDM_SUCCESS;
1038}
1039
1040int decode_state_sensor_data(const uint8_t *sensor_data,
1041 size_t sensor_data_length, uint8_t *sensor_offset,
1042 uint8_t *event_state,
1043 uint8_t *previous_event_state)
1044{
1045 if (sensor_data == NULL || sensor_offset == NULL ||
1046 event_state == NULL || previous_event_state == NULL) {
1047 return PLDM_ERROR_INVALID_DATA;
1048 }
1049 if (sensor_data_length !=
1050 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
1051 return PLDM_ERROR_INVALID_LENGTH;
1052 }
1053
1054 struct pldm_sensor_event_state_sensor_state *sensor_state_data =
1055 (struct pldm_sensor_event_state_sensor_state *)sensor_data;
1056 *sensor_offset = sensor_state_data->sensor_offset;
1057 *event_state = sensor_state_data->event_state;
1058 *previous_event_state = sensor_state_data->previous_event_state;
1059 return PLDM_SUCCESS;
1060}
1061
1062int decode_numeric_sensor_data(const uint8_t *sensor_data,
1063 size_t sensor_data_length, uint8_t *event_state,
1064 uint8_t *previous_event_state,
1065 uint8_t *sensor_data_size,
1066 uint32_t *present_reading)
1067{
1068 if (sensor_data == NULL || sensor_data_size == NULL ||
1069 event_state == NULL || previous_event_state == NULL ||
1070 present_reading == NULL) {
1071 return PLDM_ERROR_INVALID_DATA;
1072 }
1073 if (sensor_data_length <
1074 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
1075 sensor_data_length >
1076 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
1077 return PLDM_ERROR_INVALID_LENGTH;
1078 }
1079 struct pldm_sensor_event_numeric_sensor_state *numeric_sensor_data =
1080 (struct pldm_sensor_event_numeric_sensor_state *)sensor_data;
1081 *event_state = numeric_sensor_data->event_state;
1082 *previous_event_state = numeric_sensor_data->previous_event_state;
1083 *sensor_data_size = numeric_sensor_data->sensor_data_size;
1084 uint8_t *present_reading_ptr = numeric_sensor_data->present_reading;
1085
1086 switch (*sensor_data_size) {
1087 case PLDM_SENSOR_DATA_SIZE_UINT8:
1088 case PLDM_SENSOR_DATA_SIZE_SINT8:
1089 if (sensor_data_length !=
1090 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_8BIT_DATA_LENGTH) {
1091 return PLDM_ERROR_INVALID_LENGTH;
1092 }
1093 *present_reading = present_reading_ptr[0];
1094 break;
1095 case PLDM_SENSOR_DATA_SIZE_UINT16:
1096 case PLDM_SENSOR_DATA_SIZE_SINT16:
1097 if (sensor_data_length !=
1098 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_16BIT_DATA_LENGTH) {
1099 return PLDM_ERROR_INVALID_LENGTH;
1100 }
1101 *present_reading = le16toh(present_reading_ptr[1] |
1102 (present_reading_ptr[0] << 8));
1103 break;
1104 case PLDM_SENSOR_DATA_SIZE_UINT32:
1105 case PLDM_SENSOR_DATA_SIZE_SINT32:
1106 if (sensor_data_length !=
1107 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_32BIT_DATA_LENGTH) {
1108 return PLDM_ERROR_INVALID_LENGTH;
1109 }
1110 *present_reading = le32toh(present_reading_ptr[3] |
1111 (present_reading_ptr[2] << 8) |
1112 (present_reading_ptr[1] << 16) |
1113 (present_reading_ptr[0] << 24));
1114 break;
1115 default:
1116 return PLDM_ERROR_INVALID_DATA;
1117 }
1118 return PLDM_SUCCESS;
1119}
1120
1121int encode_get_numeric_effecter_value_req(uint8_t instance_id,
1122 uint16_t effecter_id,
1123 struct pldm_msg *msg)
1124{
1125 if (msg == NULL) {
1126 return PLDM_ERROR_INVALID_DATA;
1127 }
1128
1129 struct pldm_header_info header = {0};
1130 header.msg_type = PLDM_REQUEST;
1131 header.instance = instance_id;
1132 header.pldm_type = PLDM_PLATFORM;
1133 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1134
1135 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1136 if (rc != PLDM_SUCCESS) {
1137 return rc;
1138 }
1139
1140 struct pldm_get_numeric_effecter_value_req *request =
1141 (struct pldm_get_numeric_effecter_value_req *)msg->payload;
1142 request->effecter_id = htole16(effecter_id);
1143
1144 return PLDM_SUCCESS;
1145}
1146
1147int encode_get_numeric_effecter_value_resp(
1148 uint8_t instance_id, uint8_t completion_code, uint8_t effecter_data_size,
1149 uint8_t effecter_oper_state, uint8_t *pending_value, uint8_t *present_value,
1150 struct pldm_msg *msg, size_t payload_length)
1151{
1152 if (msg == NULL || pending_value == NULL || present_value == NULL) {
1153 return PLDM_ERROR_INVALID_DATA;
1154 }
1155
1156 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1157 return PLDM_ERROR_INVALID_DATA;
1158 }
1159
1160 if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1161 return PLDM_ERROR_INVALID_DATA;
1162 }
1163
1164 struct pldm_header_info header = {0};
1165 header.msg_type = PLDM_RESPONSE;
1166 header.instance = instance_id;
1167 header.pldm_type = PLDM_PLATFORM;
1168 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1169
1170 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1171 if (rc != PLDM_SUCCESS) {
1172 return rc;
1173 }
1174
1175 struct pldm_get_numeric_effecter_value_resp *response =
1176 (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
1177
1178 response->completion_code = completion_code;
1179 response->effecter_data_size = effecter_data_size;
1180 response->effecter_oper_state = effecter_oper_state;
1181
1182 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1183 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1184 if (payload_length !=
1185 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1186 return PLDM_ERROR_INVALID_LENGTH;
1187 }
1188 response->pending_and_present_values[0] = *pending_value;
1189 response->pending_and_present_values[1] = *present_value;
1190
1191 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1192 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1193 if (payload_length !=
1194 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
1195 return PLDM_ERROR_INVALID_LENGTH;
1196 }
1197 uint16_t val_pending = *(uint16_t *)pending_value;
1198 val_pending = htole16(val_pending);
1199 memcpy(response->pending_and_present_values, &val_pending,
1200 sizeof(uint16_t));
1201 uint16_t val_present = *(uint16_t *)present_value;
1202 val_present = htole16(val_present);
1203 memcpy(
1204 (response->pending_and_present_values + sizeof(uint16_t)),
1205 &val_present, sizeof(uint16_t));
1206
1207 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1208 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1209 if (payload_length !=
1210 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
1211 return PLDM_ERROR_INVALID_LENGTH;
1212 }
1213 uint32_t val_pending = *(uint32_t *)pending_value;
1214 val_pending = htole32(val_pending);
1215 memcpy(response->pending_and_present_values, &val_pending,
1216 sizeof(uint32_t));
1217 uint32_t val_present = *(uint32_t *)present_value;
1218 val_present = htole32(val_present);
1219 memcpy(
1220 (response->pending_and_present_values + sizeof(uint32_t)),
1221 &val_present, sizeof(uint32_t));
1222 }
1223 return PLDM_SUCCESS;
1224}
1225
1226int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg,
1227 size_t payload_length,
1228 uint16_t *effecter_id)
1229{
1230 if (msg == NULL || effecter_id == NULL) {
1231 return PLDM_ERROR_INVALID_DATA;
1232 }
1233
1234 if (payload_length != PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES) {
1235 return PLDM_ERROR_INVALID_LENGTH;
1236 }
1237
1238 struct pldm_get_numeric_effecter_value_req *request =
1239 (struct pldm_get_numeric_effecter_value_req *)msg->payload;
1240
1241 *effecter_id = le16toh(request->effecter_id);
1242
1243 return PLDM_SUCCESS;
1244}
1245
1246int decode_get_numeric_effecter_value_resp(
1247 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
1248 uint8_t *effecter_data_size, uint8_t *effecter_oper_state,
1249 uint8_t *pending_value, uint8_t *present_value)
1250{
1251 if (msg == NULL || effecter_data_size == NULL ||
1252 effecter_oper_state == NULL || pending_value == NULL ||
1253 present_value == NULL) {
1254 return PLDM_ERROR_INVALID_DATA;
1255 }
1256
1257 *completion_code = msg->payload[0];
1258 if (PLDM_SUCCESS != *completion_code) {
1259 return PLDM_SUCCESS;
1260 }
1261
1262 if (payload_length < PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1263 return PLDM_ERROR_INVALID_LENGTH;
1264 }
1265
1266 struct pldm_get_numeric_effecter_value_resp *response =
1267 (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
1268
1269 *effecter_data_size = response->effecter_data_size;
1270 *effecter_oper_state = response->effecter_oper_state;
1271
1272 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1273 return PLDM_ERROR_INVALID_DATA;
1274 }
1275
1276 if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1277 return PLDM_ERROR_INVALID_DATA;
1278 }
1279
1280 if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1281 *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1282 if (payload_length !=
1283 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1284 return PLDM_ERROR_INVALID_LENGTH;
1285 }
1286 memcpy(pending_value, response->pending_and_present_values, 1);
1287 memcpy(present_value, &response->pending_and_present_values[1],
1288 1);
1289
1290 } else if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1291 *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1292 if (payload_length !=
1293 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
1294 return PLDM_ERROR_INVALID_LENGTH;
1295 }
1296 memcpy(pending_value, response->pending_and_present_values,
1297 sizeof(uint16_t));
1298 uint16_t *val_pending = (uint16_t *)pending_value;
1299 *val_pending = le16toh(*val_pending);
1300 memcpy(
1301 present_value,
1302 (response->pending_and_present_values + sizeof(uint16_t)),
1303 sizeof(uint16_t));
1304 uint16_t *val_present = (uint16_t *)present_value;
1305 *val_present = le16toh(*val_present);
1306
1307 } else if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1308 *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1309 if (payload_length !=
1310 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
1311 return PLDM_ERROR_INVALID_LENGTH;
1312 }
1313 memcpy(pending_value, response->pending_and_present_values,
1314 sizeof(uint32_t));
1315 uint32_t *val_pending = (uint32_t *)pending_value;
1316 *val_pending = le32toh(*val_pending);
1317 memcpy(
1318 present_value,
1319 (response->pending_and_present_values + sizeof(uint32_t)),
1320 sizeof(uint32_t));
1321 uint32_t *val_present = (uint32_t *)present_value;
1322 *val_present = le32toh(*val_present);
1323 }
1324 return PLDM_SUCCESS;
1325}
1326
1327int encode_pldm_pdr_repository_chg_event_data(
1328 uint8_t event_data_format, uint8_t number_of_change_records,
1329 const uint8_t *event_data_operations,
1330 const uint8_t *numbers_of_change_entries,
1331 const uint32_t *const *change_entries,
1332 struct pldm_pdr_repository_chg_event_data *event_data,
1333 size_t *actual_change_records_size, size_t max_change_records_size)
1334{
1335 if (event_data_operations == NULL ||
1336 numbers_of_change_entries == NULL || change_entries == NULL) {
1337 return PLDM_ERROR_INVALID_DATA;
1338 }
1339
1340 size_t expected_size =
1341 sizeof(event_data_format) + sizeof(number_of_change_records);
1342
1343 expected_size +=
1344 sizeof(*event_data_operations) * number_of_change_records;
1345 expected_size +=
1346 sizeof(*numbers_of_change_entries) * number_of_change_records;
1347
1348 for (uint8_t i = 0; i < number_of_change_records; ++i) {
1349 expected_size +=
1350 sizeof(*change_entries[0]) * numbers_of_change_entries[i];
1351 }
1352
1353 *actual_change_records_size = expected_size;
1354
1355 if (event_data == NULL) {
1356 return PLDM_SUCCESS;
1357 }
1358
1359 if (max_change_records_size < expected_size) {
1360 return PLDM_ERROR_INVALID_LENGTH;
1361 }
1362
1363 event_data->event_data_format = event_data_format;
1364 event_data->number_of_change_records = number_of_change_records;
1365
1366 struct pldm_pdr_repository_change_record_data *record_data =
1367 (struct pldm_pdr_repository_change_record_data *)
1368 event_data->change_records;
1369
1370 for (uint8_t i = 0; i < number_of_change_records; ++i) {
1371 record_data->event_data_operation = event_data_operations[i];
1372 record_data->number_of_change_entries =
1373 numbers_of_change_entries[i];
1374
1375 for (uint8_t j = 0; j < record_data->number_of_change_entries;
1376 ++j) {
1377 record_data->change_entry[j] =
1378 htole32(change_entries[i][j]);
1379 }
1380
1381 record_data = (struct pldm_pdr_repository_change_record_data
1382 *)(record_data->change_entry +
1383 record_data->number_of_change_entries);
1384 }
1385
1386 return PLDM_SUCCESS;
1387}
1388
1389int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data,
1390 size_t event_data_size,
1391 uint8_t *event_data_format,
1392 uint8_t *number_of_change_records,
1393 size_t *change_record_data_offset)
1394{
1395 if (event_data == NULL || event_data_format == NULL ||
1396 number_of_change_records == NULL ||
1397 change_record_data_offset == NULL) {
1398 return PLDM_ERROR_INVALID_DATA;
1399 }
1400 if (event_data_size < PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH) {
1401 return PLDM_ERROR_INVALID_LENGTH;
1402 }
1403
1404 struct pldm_pdr_repository_chg_event_data
1405 *pdr_repository_chg_event_data =
1406 (struct pldm_pdr_repository_chg_event_data *)event_data;
1407
1408 *event_data_format = pdr_repository_chg_event_data->event_data_format;
1409 *number_of_change_records =
1410 pdr_repository_chg_event_data->number_of_change_records;
1411 *change_record_data_offset =
1412 sizeof(*event_data_format) + sizeof(*number_of_change_records);
1413
1414 return PLDM_SUCCESS;
1415}
1416
1417int decode_pldm_pdr_repository_change_record_data(
1418 const uint8_t *change_record_data, size_t change_record_data_size,
1419 uint8_t *event_data_operation, uint8_t *number_of_change_entries,
1420 size_t *change_entry_data_offset)
1421{
1422 if (change_record_data == NULL || event_data_operation == NULL ||
1423 number_of_change_entries == NULL ||
1424 change_entry_data_offset == NULL) {
1425 return PLDM_ERROR_INVALID_DATA;
1426 }
1427 if (change_record_data_size <
1428 PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH) {
1429 return PLDM_ERROR_INVALID_LENGTH;
1430 }
1431
1432 struct pldm_pdr_repository_change_record_data
1433 *pdr_repository_change_record_data =
1434 (struct pldm_pdr_repository_change_record_data *)
1435 change_record_data;
1436
1437 *event_data_operation =
1438 pdr_repository_change_record_data->event_data_operation;
1439 *number_of_change_entries =
1440 pdr_repository_change_record_data->number_of_change_entries;
1441 *change_entry_data_offset =
1442 sizeof(*event_data_operation) + sizeof(*number_of_change_entries);
1443
1444 return PLDM_SUCCESS;
1445}
1446
1447int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id,
1448 uint8_t rearm_event_state,
1449 struct pldm_msg *msg)
1450{
1451 if (msg == NULL) {
1452 return PLDM_ERROR_INVALID_DATA;
1453 }
1454
1455 struct pldm_header_info header = {0};
1456 header.msg_type = PLDM_REQUEST;
1457 header.instance = instance_id;
1458 header.pldm_type = PLDM_PLATFORM;
1459 header.command = PLDM_GET_SENSOR_READING;
1460
1461 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1462 if (rc != PLDM_SUCCESS) {
1463 return rc;
1464 }
1465
1466 struct pldm_get_sensor_reading_req *request =
1467 (struct pldm_get_sensor_reading_req *)msg->payload;
1468
1469 request->sensor_id = htole16(sensor_id);
1470 request->rearm_event_state = rearm_event_state;
1471
1472 return PLDM_SUCCESS;
1473}
1474
1475int decode_get_sensor_reading_resp(
1476 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
1477 uint8_t *sensor_data_size, uint8_t *sensor_operational_state,
1478 uint8_t *sensor_event_message_enable, uint8_t *present_state,
1479 uint8_t *previous_state, uint8_t *event_state, uint8_t *present_reading)
1480{
1481 if (msg == NULL || completion_code == NULL ||
1482 sensor_data_size == NULL || sensor_operational_state == NULL ||
1483 sensor_event_message_enable == NULL || present_state == NULL ||
1484 previous_state == NULL || event_state == NULL ||
1485 present_reading == NULL) {
1486 return PLDM_ERROR_INVALID_DATA;
1487 }
1488
1489 *completion_code = msg->payload[0];
1490 if (PLDM_SUCCESS != *completion_code) {
1491 return PLDM_SUCCESS;
1492 }
1493
1494 if (payload_length < PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
1495 return PLDM_ERROR_INVALID_LENGTH;
1496 }
1497
1498 struct pldm_get_sensor_reading_resp *response =
1499 (struct pldm_get_sensor_reading_resp *)msg->payload;
1500
1501 if (response->sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) {
1502 return PLDM_ERROR_INVALID_DATA;
1503 }
1504
1505 *sensor_data_size = response->sensor_data_size;
1506 *sensor_operational_state = response->sensor_operational_state;
1507 *sensor_event_message_enable = response->sensor_event_message_enable;
1508 *present_state = response->present_state;
1509 *previous_state = response->previous_state;
1510 *event_state = response->event_state;
1511
1512 if (*sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1513 *sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1514 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
1515 return PLDM_ERROR_INVALID_LENGTH;
1516 }
1517 *present_reading = response->present_reading[0];
1518
1519 } else if (*sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1520 *sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1521 if (payload_length !=
1522 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
1523 return PLDM_ERROR_INVALID_LENGTH;
1524 }
1525 memcpy(present_reading, response->present_reading, 2);
1526 uint16_t *val = (uint16_t *)(present_reading);
1527 *val = le16toh(*val);
1528
1529 } else if (*sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1530 *sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1531 if (payload_length !=
1532 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
1533 return PLDM_ERROR_INVALID_LENGTH;
1534 }
1535 memcpy(present_reading, response->present_reading, 4);
1536 uint32_t *val = (uint32_t *)(present_reading);
1537 *val = le32toh(*val);
1538 }
1539
1540 return PLDM_SUCCESS;
1541}
1542
1543int encode_get_sensor_reading_resp(
1544 uint8_t instance_id, uint8_t completion_code, uint8_t sensor_data_size,
1545 uint8_t sensor_operational_state, uint8_t sensor_event_message_enable,
1546 uint8_t present_state, uint8_t previous_state, uint8_t event_state,
1547 uint8_t *present_reading, struct pldm_msg *msg, size_t payload_length)
1548{
1549 if (msg == NULL || present_reading == NULL) {
1550 return PLDM_ERROR_INVALID_DATA;
1551 }
1552
1553 if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1554 return PLDM_ERROR_INVALID_DATA;
1555 }
1556
1557 struct pldm_header_info header = {0};
1558 header.msg_type = PLDM_RESPONSE;
1559 header.instance = instance_id;
1560 header.pldm_type = PLDM_PLATFORM;
1561 header.command = PLDM_GET_SENSOR_READING;
1562
1563 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1564 if (rc != PLDM_SUCCESS) {
1565 return rc;
1566 }
1567
1568 struct pldm_get_sensor_reading_resp *response =
1569 (struct pldm_get_sensor_reading_resp *)msg->payload;
1570
1571 response->completion_code = completion_code;
1572 response->sensor_data_size = sensor_data_size;
1573 response->sensor_operational_state = sensor_operational_state;
1574 response->sensor_event_message_enable = sensor_event_message_enable;
1575 response->present_state = present_state;
1576 response->previous_state = previous_state;
1577 response->event_state = event_state;
1578
1579 if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1580 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1581 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
1582 return PLDM_ERROR_INVALID_LENGTH;
1583 }
1584 response->present_reading[0] = *present_reading;
1585
1586 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1587 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1588 if (payload_length !=
1589 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
1590 return PLDM_ERROR_INVALID_LENGTH;
1591 }
1592 uint16_t val = *(uint16_t *)present_reading;
1593 val = htole16(val);
1594 memcpy(response->present_reading, &val, 2);
1595
1596 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1597 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1598 if (payload_length !=
1599 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
1600 return PLDM_ERROR_INVALID_LENGTH;
1601 }
1602 uint32_t val = *(uint32_t *)present_reading;
1603 val = htole32(val);
1604 memcpy(response->present_reading, &val, 4);
1605 }
1606
1607 return PLDM_SUCCESS;
1608}
1609
1610int decode_get_sensor_reading_req(const struct pldm_msg *msg,
1611 size_t payload_length, uint16_t *sensor_id,
1612 uint8_t *rearm_event_state)
1613{
1614 if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) {
1615 return PLDM_ERROR_INVALID_DATA;
1616 }
1617
1618 if (payload_length != PLDM_GET_SENSOR_READING_REQ_BYTES) {
1619 return PLDM_ERROR_INVALID_LENGTH;
1620 }
1621
1622 struct pldm_get_sensor_reading_req *request =
1623 (struct pldm_get_sensor_reading_req *)msg->payload;
1624
1625 *sensor_id = le16toh(request->sensor_id);
1626 *rearm_event_state = request->rearm_event_state;
1627
1628 return PLDM_SUCCESS;
1629}
1630
1631int encode_set_event_receiver_req(uint8_t instance_id,
1632 uint8_t event_message_global_enable,
1633 uint8_t transport_protocol_type,
1634 uint8_t event_receiver_address_info,
1635 uint16_t heartbeat_timer,
1636 struct pldm_msg *msg)
1637{
1638 if (msg == NULL) {
1639 return PLDM_ERROR_INVALID_DATA;
1640 }
1641
1642 if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
1643 return PLDM_ERROR_INVALID_DATA;
1644 }
1645
1646 struct pldm_header_info header = {0};
1647 header.msg_type = PLDM_REQUEST;
1648 header.instance = instance_id;
1649 header.pldm_type = PLDM_PLATFORM;
1650 header.command = PLDM_SET_EVENT_RECEIVER;
1651
1652 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1653 if (rc != PLDM_SUCCESS) {
1654 return rc;
1655 }
1656
1657 struct pldm_set_event_receiver_req *request =
1658 (struct pldm_set_event_receiver_req *)msg->payload;
1659 request->event_message_global_enable = event_message_global_enable;
1660
1661 request->transport_protocol_type = transport_protocol_type;
1662 request->event_receiver_address_info = event_receiver_address_info;
1663
1664 if (event_message_global_enable ==
1665 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {
1666 if (heartbeat_timer == 0) {
1667 return PLDM_ERROR_INVALID_DATA;
1668 }
1669 request->heartbeat_timer = htole16(heartbeat_timer);
1670 }
1671
1672 return PLDM_SUCCESS;
1673}
1674
1675int decode_set_event_receiver_resp(const struct pldm_msg *msg,
1676 size_t payload_length,
1677 uint8_t *completion_code)
1678{
1679 if (msg == NULL || completion_code == NULL) {
1680 return PLDM_ERROR_INVALID_DATA;
1681 }
1682
1683 *completion_code = msg->payload[0];
1684 if (PLDM_SUCCESS != *completion_code) {
1685 return PLDM_SUCCESS;
1686 }
1687
1688 if (payload_length > PLDM_SET_EVENT_RECEIVER_RESP_BYTES) {
1689 return PLDM_ERROR_INVALID_LENGTH;
1690 }
1691
1692 return PLDM_SUCCESS;
1693}
1694
1695int decode_set_event_receiver_req(const struct pldm_msg *msg,
1696 size_t payload_length,
1697 uint8_t *event_message_global_enable,
1698 uint8_t *transport_protocol_type,
1699 uint8_t *event_receiver_address_info,
1700 uint16_t *heartbeat_timer)
1701
1702{
1703 if (msg == NULL || event_message_global_enable == NULL ||
1704 transport_protocol_type == NULL ||
1705 event_receiver_address_info == NULL || heartbeat_timer == NULL) {
1706 return PLDM_ERROR_INVALID_DATA;
1707 }
1708
1709 if (payload_length != PLDM_SET_EVENT_RECEIVER_REQ_BYTES) {
1710 return PLDM_ERROR_INVALID_LENGTH;
1711 }
1712
1713 struct pldm_set_event_receiver_req *request =
1714 (struct pldm_set_event_receiver_req *)msg->payload;
1715
1716 if ((*event_message_global_enable ==
1717 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) &&
1718 (*heartbeat_timer == 0)) {
1719 return PLDM_ERROR_INVALID_DATA;
1720 }
1721
1722 *event_message_global_enable = request->event_message_global_enable,
1723 *transport_protocol_type = request->transport_protocol_type,
1724 *event_receiver_address_info = request->event_receiver_address_info,
1725 *heartbeat_timer = le16toh(request->heartbeat_timer);
1726
1727 return PLDM_SUCCESS;
1728}
1729
1730int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code,
1731 struct pldm_msg *msg)
1732
1733{
1734 if (msg == NULL) {
1735 return PLDM_ERROR_INVALID_DATA;
1736 }
1737
1738 struct pldm_header_info header = {0};
1739 header.instance = instance_id;
1740 header.msg_type = PLDM_RESPONSE;
1741 header.pldm_type = PLDM_PLATFORM;
1742 header.command = PLDM_SET_EVENT_RECEIVER;
1743
1744 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1745 if (rc != PLDM_SUCCESS) {
1746 return rc;
1747 }
1748
1749 msg->payload[0] = completion_code;
1750
1751 return PLDM_SUCCESS;
1752}