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