blob: 492fe650741d9da6af1102ac25ad11b2effe043d [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
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800363int decode_get_pdr_repository_info_resp(
364 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
365 uint8_t *repository_state, uint8_t *update_time, uint8_t *oem_update_time,
366 uint32_t *record_count, uint32_t *repository_size,
367 uint32_t *largest_record_size, uint8_t *data_transfer_handle_timeout)
368{
369 if (msg == NULL || completion_code == NULL ||
370 repository_state == NULL || update_time == NULL ||
371 oem_update_time == NULL || record_count == NULL ||
372 repository_size == NULL || largest_record_size == NULL ||
373 data_transfer_handle_timeout == NULL) {
374 return PLDM_ERROR_INVALID_DATA;
375 }
376
377 *completion_code = msg->payload[0];
378 if (PLDM_SUCCESS != *completion_code) {
379 return PLDM_SUCCESS;
380 }
381
382 if (payload_length < PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES) {
383 return PLDM_ERROR_INVALID_LENGTH;
384 }
385
386 struct pldm_pdr_repository_info_resp *response =
387 (struct pldm_pdr_repository_info_resp *)msg->payload;
388
389 *repository_state = response->repository_state;
390 if (*repository_state > PLDM_FAILED) {
391 return PLDM_ERROR_INVALID_DATA;
392 }
393
394 memcpy(update_time, response->update_time, PLDM_TIMESTAMP104_SIZE);
395 memcpy(oem_update_time, response->oem_update_time,
396 PLDM_TIMESTAMP104_SIZE);
397 *record_count = le32toh(response->record_count);
398 *repository_size = le32toh(response->repository_size);
399 *largest_record_size = le32toh(response->largest_record_size);
400 *data_transfer_handle_timeout = response->data_transfer_handle_timeout;
401
402 return PLDM_SUCCESS;
403}
404
Andrew Jeffery9c766792022-08-10 23:12:49 +0930405int encode_get_pdr_req(uint8_t instance_id, uint32_t record_hndl,
406 uint32_t data_transfer_hndl, uint8_t transfer_op_flag,
407 uint16_t request_cnt, uint16_t record_chg_num,
408 struct pldm_msg *msg, size_t payload_length)
409{
410 if (msg == NULL) {
411 return PLDM_ERROR_INVALID_DATA;
412 }
413
414 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
415 return PLDM_ERROR_INVALID_LENGTH;
416 }
417
418 struct pldm_header_info header = {0};
419 header.msg_type = PLDM_REQUEST;
420 header.instance = instance_id;
421 header.pldm_type = PLDM_PLATFORM;
422 header.command = PLDM_GET_PDR;
423
424 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
425 if (rc != PLDM_SUCCESS) {
426 return rc;
427 }
428
429 struct pldm_get_pdr_req *request =
430 (struct pldm_get_pdr_req *)msg->payload;
431 request->record_handle = htole32(record_hndl);
432 request->data_transfer_handle = htole32(data_transfer_hndl);
433 request->transfer_op_flag = transfer_op_flag;
434 request->request_count = htole16(request_cnt);
435 request->record_change_number = htole16(record_chg_num);
436
437 return PLDM_SUCCESS;
438}
439
440int decode_get_pdr_resp(const struct pldm_msg *msg, size_t payload_length,
441 uint8_t *completion_code, uint32_t *next_record_hndl,
442 uint32_t *next_data_transfer_hndl,
443 uint8_t *transfer_flag, uint16_t *resp_cnt,
444 uint8_t *record_data, size_t record_data_length,
445 uint8_t *transfer_crc)
446{
447 if (msg == NULL || completion_code == NULL ||
448 next_record_hndl == NULL || next_data_transfer_hndl == NULL ||
449 transfer_flag == NULL || resp_cnt == NULL || transfer_crc == NULL) {
450 return PLDM_ERROR_INVALID_DATA;
451 }
452
453 *completion_code = msg->payload[0];
454 if (PLDM_SUCCESS != *completion_code) {
455 return PLDM_SUCCESS;
456 }
457
458 if (payload_length < PLDM_GET_PDR_MIN_RESP_BYTES) {
459 return PLDM_ERROR_INVALID_LENGTH;
460 }
461
462 struct pldm_get_pdr_resp *response =
463 (struct pldm_get_pdr_resp *)msg->payload;
464
465 *next_record_hndl = le32toh(response->next_record_handle);
466 *next_data_transfer_hndl = le32toh(response->next_data_transfer_handle);
467 *transfer_flag = response->transfer_flag;
468 *resp_cnt = le16toh(response->response_count);
469
470 if (*transfer_flag != PLDM_END &&
471 (int)payload_length != PLDM_GET_PDR_MIN_RESP_BYTES + *resp_cnt) {
472 return PLDM_ERROR_INVALID_LENGTH;
473 }
474
475 if (*transfer_flag == PLDM_END &&
476 (int)payload_length !=
477 PLDM_GET_PDR_MIN_RESP_BYTES + *resp_cnt + 1) {
478 return PLDM_ERROR_INVALID_LENGTH;
479 }
480
481 if (*resp_cnt > 0 && record_data != NULL) {
482 if (record_data_length < *resp_cnt) {
483 return PLDM_ERROR_INVALID_LENGTH;
484 }
485 memcpy(record_data, response->record_data, *resp_cnt);
486 }
487
488 if (*transfer_flag == PLDM_END) {
489 *transfer_crc =
490 msg->payload[PLDM_GET_PDR_MIN_RESP_BYTES + *resp_cnt];
491 }
492
493 return PLDM_SUCCESS;
494}
495
496int decode_set_numeric_effecter_value_req(const struct pldm_msg *msg,
497 size_t payload_length,
498 uint16_t *effecter_id,
499 uint8_t *effecter_data_size,
500 uint8_t *effecter_value)
501{
502 if (msg == NULL || effecter_id == NULL || effecter_data_size == NULL ||
503 effecter_value == NULL) {
504 return PLDM_ERROR_INVALID_DATA;
505 }
506
507 if (payload_length < PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) {
508 return PLDM_ERROR_INVALID_LENGTH;
509 }
510
511 struct pldm_set_numeric_effecter_value_req *request =
512 (struct pldm_set_numeric_effecter_value_req *)msg->payload;
513 *effecter_id = le16toh(request->effecter_id);
514 *effecter_data_size = request->effecter_data_size;
515
516 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
517 return PLDM_ERROR_INVALID_DATA;
518 }
519
520 if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
521 *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
522
523 if (payload_length !=
524 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) {
525 return PLDM_ERROR_INVALID_LENGTH;
526 }
527
528 *effecter_value = request->effecter_value[0];
529 }
530
531 if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
532 *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
533
534 if (payload_length !=
535 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1) {
536 return PLDM_ERROR_INVALID_LENGTH;
537 }
538
539 memcpy(effecter_value, request->effecter_value, 2);
540 uint16_t *val = (uint16_t *)(effecter_value);
541 *val = le16toh(*val);
542 }
543
544 if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
545 *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
546
547 if (payload_length !=
548 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3) {
549 return PLDM_ERROR_INVALID_LENGTH;
550 }
551
552 memcpy(effecter_value, request->effecter_value, 4);
553 uint32_t *val = (uint32_t *)(effecter_value);
554 *val = le32toh(*val);
555 }
556
557 return PLDM_SUCCESS;
558}
559
560int encode_set_numeric_effecter_value_resp(uint8_t instance_id,
561 uint8_t completion_code,
562 struct pldm_msg *msg,
563 size_t payload_length)
564{
565 if (msg == NULL) {
566 return PLDM_ERROR_INVALID_DATA;
567 }
568
569 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
570 return PLDM_ERROR_INVALID_LENGTH;
571 }
572
573 struct pldm_header_info header = {0};
574 header.msg_type = PLDM_RESPONSE;
575 header.instance = instance_id;
576 header.pldm_type = PLDM_PLATFORM;
577 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
578
579 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
580 if (rc != PLDM_SUCCESS) {
581 return rc;
582 }
583
584 msg->payload[0] = completion_code;
585
586 return rc;
587}
588
589int encode_set_numeric_effecter_value_req(
590 uint8_t instance_id, uint16_t effecter_id, uint8_t effecter_data_size,
591 uint8_t *effecter_value, struct pldm_msg *msg, size_t payload_length)
592{
593 if (msg == NULL || effecter_value == NULL) {
594 return PLDM_ERROR_INVALID_DATA;
595 }
596
597 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
598 return PLDM_ERROR_INVALID_DATA;
599 }
600
601 struct pldm_header_info header = {0};
602 header.msg_type = PLDM_REQUEST;
603 header.instance = instance_id;
604 header.pldm_type = PLDM_PLATFORM;
605 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
606
607 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
608 if (rc != PLDM_SUCCESS) {
609 return rc;
610 }
611
612 struct pldm_set_numeric_effecter_value_req *request =
613 (struct pldm_set_numeric_effecter_value_req *)msg->payload;
614 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
615 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
616 if (payload_length !=
617 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) {
618 return PLDM_ERROR_INVALID_LENGTH;
619 }
620 request->effecter_value[0] = *effecter_value;
621 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
622 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
623 if (payload_length !=
624 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1) {
625 return PLDM_ERROR_INVALID_LENGTH;
626 }
627
628 uint16_t val = *(uint16_t *)(effecter_value);
629 val = htole16(val);
630 memcpy(request->effecter_value, &val, sizeof(uint16_t));
631
632 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
633 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
634 if (payload_length !=
635 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3) {
636 return PLDM_ERROR_INVALID_LENGTH;
637 }
638
639 uint32_t val = *(uint32_t *)(effecter_value);
640 val = htole32(val);
641 memcpy(request->effecter_value, &val, sizeof(uint32_t));
642 }
643
644 request->effecter_id = htole16(effecter_id);
645 request->effecter_data_size = effecter_data_size;
646
647 return PLDM_SUCCESS;
648}
649
650int decode_set_numeric_effecter_value_resp(const struct pldm_msg *msg,
651 size_t payload_length,
652 uint8_t *completion_code)
653{
654 if (msg == NULL || completion_code == NULL) {
655 return PLDM_ERROR_INVALID_DATA;
656 }
657
658 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
659 return PLDM_ERROR_INVALID_LENGTH;
660 }
661
662 *completion_code = msg->payload[0];
663
664 return PLDM_SUCCESS;
665}
666
667int encode_get_state_sensor_readings_resp(uint8_t instance_id,
668 uint8_t completion_code,
669 uint8_t comp_sensor_count,
670 get_sensor_state_field *field,
671 struct pldm_msg *msg)
672{
673 if (msg == NULL) {
674 return PLDM_ERROR_INVALID_DATA;
675 }
676
677 if (comp_sensor_count < 0x1 || comp_sensor_count > 0x8) {
678 return PLDM_ERROR_INVALID_DATA;
679 }
680
681 struct pldm_header_info header = {0};
682 header.msg_type = PLDM_RESPONSE;
683 header.instance = instance_id;
684 header.pldm_type = PLDM_PLATFORM;
685 header.command = PLDM_GET_STATE_SENSOR_READINGS;
686
687 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
688 if (rc != PLDM_SUCCESS) {
689 return rc;
690 }
691
692 struct pldm_get_state_sensor_readings_resp *response =
693 (struct pldm_get_state_sensor_readings_resp *)msg->payload;
694
695 response->completion_code = completion_code;
696 response->comp_sensor_count = comp_sensor_count;
697 memcpy(response->field, field,
698 (sizeof(get_sensor_state_field) * comp_sensor_count));
699
700 return PLDM_SUCCESS;
701}
702
703int encode_get_state_sensor_readings_req(uint8_t instance_id,
704 uint16_t sensor_id,
705 bitfield8_t sensor_rearm,
706 uint8_t reserved, struct pldm_msg *msg)
707{
708 if (msg == NULL) {
709 return PLDM_ERROR_INVALID_DATA;
710 }
711
712 struct pldm_header_info header = {0};
713 header.msg_type = PLDM_REQUEST;
714 header.instance = instance_id;
715 header.pldm_type = PLDM_PLATFORM;
716 header.command = PLDM_GET_STATE_SENSOR_READINGS;
717
718 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
719 if (rc != PLDM_SUCCESS) {
720 return rc;
721 }
722
723 struct pldm_get_state_sensor_readings_req *request =
724 (struct pldm_get_state_sensor_readings_req *)msg->payload;
725
726 request->sensor_id = htole16(sensor_id);
727 request->reserved = reserved;
728 request->sensor_rearm = sensor_rearm;
729
730 return PLDM_SUCCESS;
731}
732
733int decode_get_state_sensor_readings_resp(const struct pldm_msg *msg,
734 size_t payload_length,
735 uint8_t *completion_code,
736 uint8_t *comp_sensor_count,
737 get_sensor_state_field *field)
738{
739 if (msg == NULL || completion_code == NULL ||
740 comp_sensor_count == NULL || field == NULL) {
741 return PLDM_ERROR_INVALID_DATA;
742 }
743
744 *completion_code = msg->payload[0];
745 if (PLDM_SUCCESS != *completion_code) {
746 return PLDM_SUCCESS;
747 }
748
749 struct pldm_get_state_sensor_readings_resp *response =
750 (struct pldm_get_state_sensor_readings_resp *)msg->payload;
751
752 if (response->comp_sensor_count < 0x1 ||
753 response->comp_sensor_count > 0x8) {
754 return PLDM_ERROR_INVALID_DATA;
755 }
756
757 if (payload_length >
758 PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES +
759 sizeof(get_sensor_state_field) * response->comp_sensor_count) {
760 return PLDM_ERROR_INVALID_LENGTH;
761 }
762
763 *comp_sensor_count = response->comp_sensor_count;
764
765 memcpy(field, response->field,
766 (sizeof(get_sensor_state_field) * (*comp_sensor_count)));
767
768 return PLDM_SUCCESS;
769}
770
771int decode_get_state_sensor_readings_req(const struct pldm_msg *msg,
772 size_t payload_length,
773 uint16_t *sensor_id,
774 bitfield8_t *sensor_rearm,
775 uint8_t *reserved)
776{
777 if (msg == NULL || sensor_id == NULL || sensor_rearm == NULL) {
778 return PLDM_ERROR_INVALID_DATA;
779 }
780
781 if (payload_length != PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES) {
782 return PLDM_ERROR_INVALID_LENGTH;
783 }
784
785 struct pldm_get_state_sensor_readings_req *request =
786 (struct pldm_get_state_sensor_readings_req *)msg->payload;
787
788 *sensor_id = le16toh(request->sensor_id);
789 *reserved = request->reserved;
790 memcpy(&(sensor_rearm->byte), &(request->sensor_rearm.byte),
791 sizeof(request->sensor_rearm.byte));
792
793 return PLDM_SUCCESS;
794}
795
796int encode_sensor_event_data(
797 struct pldm_sensor_event_data *const event_data,
798 const size_t event_data_size, const uint16_t sensor_id,
799 const enum sensor_event_class_states sensor_event_class,
800 const uint8_t sensor_offset, const uint8_t event_state,
801 const uint8_t previous_event_state, size_t *const actual_event_data_size)
802{
803 *actual_event_data_size =
804 (sizeof(*event_data) - sizeof(event_data->event_class) +
805 sizeof(struct pldm_sensor_event_state_sensor_state));
806
807 if (!event_data) {
808 return PLDM_SUCCESS;
809 }
810
811 if (event_data_size < *actual_event_data_size) {
812 *actual_event_data_size = 0;
813 return PLDM_ERROR_INVALID_LENGTH;
814 }
815
816 event_data->sensor_id = htole16(sensor_id);
817 event_data->sensor_event_class_type = sensor_event_class;
818
819 struct pldm_sensor_event_state_sensor_state *const state_data =
820 (struct pldm_sensor_event_state_sensor_state *)
821 event_data->event_class;
822
823 state_data->sensor_offset = sensor_offset;
824 state_data->event_state = event_state;
825 state_data->previous_event_state = previous_event_state;
826
827 return PLDM_SUCCESS;
828}
829
830int decode_platform_event_message_req(const struct pldm_msg *msg,
831 size_t payload_length,
832 uint8_t *format_version, uint8_t *tid,
833 uint8_t *event_class,
834 size_t *event_data_offset)
835{
836
837 if (msg == NULL || format_version == NULL || tid == NULL ||
838 event_class == NULL || event_data_offset == NULL) {
839 return PLDM_ERROR_INVALID_DATA;
840 }
841
842 if (payload_length <= PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) {
843 return PLDM_ERROR_INVALID_LENGTH;
844 }
845 struct pldm_platform_event_message_req *response =
846 (struct pldm_platform_event_message_req *)msg->payload;
847
848 *format_version = response->format_version;
849 *tid = response->tid;
850 *event_class = response->event_class;
851 *event_data_offset =
852 sizeof(*format_version) + sizeof(*tid) + sizeof(*event_class);
853
854 return PLDM_SUCCESS;
855}
856
857int encode_platform_event_message_resp(uint8_t instance_id,
858 uint8_t completion_code,
859 uint8_t platform_event_status,
860 struct pldm_msg *msg)
861{
862 if (msg == NULL) {
863 return PLDM_ERROR_INVALID_DATA;
864 }
865
866 if (platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
867 return PLDM_ERROR_INVALID_DATA;
868 }
869
870 struct pldm_header_info header = {0};
871 header.msg_type = PLDM_RESPONSE;
872 header.instance = instance_id;
873 header.pldm_type = PLDM_PLATFORM;
874 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
875
876 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
877 if (rc != PLDM_SUCCESS) {
878 return rc;
879 }
880
881 struct pldm_platform_event_message_resp *response =
882 (struct pldm_platform_event_message_resp *)msg->payload;
883 response->completion_code = completion_code;
884 response->platform_event_status = platform_event_status;
885
886 return PLDM_SUCCESS;
887}
888
889int encode_platform_event_message_req(
890 uint8_t instance_id, uint8_t format_version, uint8_t tid,
891 uint8_t event_class, const uint8_t *event_data, size_t event_data_length,
892 struct pldm_msg *msg, size_t payload_length)
893
894{
895 if (format_version != 1) {
896 return PLDM_ERROR_INVALID_DATA;
897 }
898
899 if (msg == NULL || event_data == NULL) {
900 return PLDM_ERROR_INVALID_DATA;
901 }
902
903 if (event_data_length == 0) {
904 return PLDM_ERROR_INVALID_DATA;
905 }
906
907 if (payload_length !=
908 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) {
909 return PLDM_ERROR_INVALID_LENGTH;
910 }
911
912 if (event_class > PLDM_HEARTBEAT_TIMER_ELAPSED_EVENT &&
913 !(event_class >= 0xF0 && event_class <= 0xFE)) {
914 return PLDM_ERROR_INVALID_DATA;
915 }
916
917 struct pldm_header_info header = {0};
918 header.msg_type = PLDM_REQUEST;
919 header.instance = instance_id;
920 header.pldm_type = PLDM_PLATFORM;
921 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
922
923 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
924 if (rc != PLDM_SUCCESS) {
925 return rc;
926 }
927
928 struct pldm_platform_event_message_req *request =
929 (struct pldm_platform_event_message_req *)msg->payload;
930 request->format_version = format_version;
931 request->tid = tid;
932 request->event_class = event_class;
933 memcpy(request->event_data, event_data, event_data_length);
934
935 return PLDM_SUCCESS;
936}
937
938int decode_platform_event_message_resp(const struct pldm_msg *msg,
939 size_t payload_length,
940 uint8_t *completion_code,
941 uint8_t *platform_event_status)
942{
943 if (msg == NULL || completion_code == NULL ||
944 platform_event_status == NULL) {
945 return PLDM_ERROR_INVALID_DATA;
946 }
947
948 *completion_code = msg->payload[0];
949 if (PLDM_SUCCESS != *completion_code) {
950 return PLDM_SUCCESS;
951 }
952 if (payload_length != PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES) {
953 return PLDM_ERROR_INVALID_LENGTH;
954 }
955
956 struct pldm_platform_event_message_resp *response =
957 (struct pldm_platform_event_message_resp *)msg->payload;
958 *platform_event_status = response->platform_event_status;
959
960 if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
961 return PLDM_ERROR_INVALID_DATA;
962 }
963
964 return PLDM_SUCCESS;
965}
966
Dung Caod6ae8982022-11-02 10:00:10 +0700967int encode_event_message_buffer_size_req(
968 uint8_t instance_id, uint16_t event_receiver_max_buffer_size,
969 struct pldm_msg *msg)
970{
971 struct pldm_header_info header = {0};
972 header.msg_type = PLDM_REQUEST;
973 header.instance = instance_id;
974 header.pldm_type = PLDM_PLATFORM;
975 header.command = PLDM_EVENT_MESSAGE_BUFFER_SIZE;
976
977 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
978 if (rc != PLDM_SUCCESS) {
979 return rc;
980 }
981
982 struct pldm_event_message_buffer_size_req *request =
983 (struct pldm_event_message_buffer_size_req *)msg->payload;
984 request->event_receiver_max_buffer_size =
985 event_receiver_max_buffer_size;
986
987 return PLDM_SUCCESS;
988}
989
990int decode_event_message_buffer_size_resp(const struct pldm_msg *msg,
991 size_t payload_length,
992 uint8_t *completion_code,
993 uint16_t *terminus_max_buffer_size)
994{
995 if (msg == NULL || completion_code == NULL ||
996 terminus_max_buffer_size == NULL) {
997 return PLDM_ERROR_INVALID_DATA;
998 }
999
1000 *completion_code = msg->payload[0];
1001 if (PLDM_SUCCESS != *completion_code) {
1002 return PLDM_SUCCESS;
1003 }
1004 if (payload_length != PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES) {
1005 return PLDM_ERROR_INVALID_LENGTH;
1006 }
1007
1008 struct pldm_event_message_buffer_size_resp *response =
1009 (struct pldm_event_message_buffer_size_resp *)msg->payload;
1010
1011 *terminus_max_buffer_size = response->terminus_max_buffer_size;
1012
1013 return PLDM_SUCCESS;
1014}
1015
Andrew Jeffery9c766792022-08-10 23:12:49 +09301016int decode_sensor_event_data(const uint8_t *event_data,
1017 size_t event_data_length, uint16_t *sensor_id,
1018 uint8_t *sensor_event_class_type,
1019 size_t *event_class_data_offset)
1020{
1021 if (event_data == NULL) {
1022 return PLDM_ERROR_INVALID_DATA;
1023 }
1024 if (event_data_length < PLDM_SENSOR_EVENT_DATA_MIN_LENGTH) {
1025 return PLDM_ERROR_INVALID_LENGTH;
1026 }
1027
1028 size_t event_class_data_length =
1029 event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES;
1030
1031 struct pldm_sensor_event_data *sensor_event_data =
1032 (struct pldm_sensor_event_data *)event_data;
1033 *sensor_id = sensor_event_data->sensor_id;
1034 *sensor_event_class_type = sensor_event_data->sensor_event_class_type;
1035 if (sensor_event_data->sensor_event_class_type ==
1036 PLDM_SENSOR_OP_STATE) {
1037 if (event_class_data_length !=
1038 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
1039 return PLDM_ERROR_INVALID_LENGTH;
1040 }
1041 } else if (sensor_event_data->sensor_event_class_type ==
1042 PLDM_STATE_SENSOR_STATE) {
1043 if (event_class_data_length !=
1044 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
1045 return PLDM_ERROR_INVALID_LENGTH;
1046 }
1047 } else if (sensor_event_data->sensor_event_class_type ==
1048 PLDM_NUMERIC_SENSOR_STATE) {
1049 if (event_class_data_length <
1050 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
1051 event_class_data_length >
1052 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
1053 return PLDM_ERROR_INVALID_LENGTH;
1054 }
1055 } else {
1056 return PLDM_ERROR_INVALID_DATA;
1057 }
1058 *event_class_data_offset =
1059 sizeof(*sensor_id) + sizeof(*sensor_event_class_type);
1060 return PLDM_SUCCESS;
1061}
1062
1063int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length,
1064 uint8_t *present_op_state, uint8_t *previous_op_state)
1065{
1066 if (sensor_data == NULL || present_op_state == NULL ||
1067 previous_op_state == NULL) {
1068 return PLDM_ERROR_INVALID_DATA;
1069 }
1070 if (sensor_data_length !=
1071 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
1072 return PLDM_ERROR_INVALID_LENGTH;
1073 }
1074
1075 struct pldm_sensor_event_sensor_op_state *sensor_op_data =
1076 (struct pldm_sensor_event_sensor_op_state *)sensor_data;
1077 *present_op_state = sensor_op_data->present_op_state;
1078 *previous_op_state = sensor_op_data->previous_op_state;
1079 return PLDM_SUCCESS;
1080}
1081
1082int decode_state_sensor_data(const uint8_t *sensor_data,
1083 size_t sensor_data_length, uint8_t *sensor_offset,
1084 uint8_t *event_state,
1085 uint8_t *previous_event_state)
1086{
1087 if (sensor_data == NULL || sensor_offset == NULL ||
1088 event_state == NULL || previous_event_state == NULL) {
1089 return PLDM_ERROR_INVALID_DATA;
1090 }
1091 if (sensor_data_length !=
1092 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
1093 return PLDM_ERROR_INVALID_LENGTH;
1094 }
1095
1096 struct pldm_sensor_event_state_sensor_state *sensor_state_data =
1097 (struct pldm_sensor_event_state_sensor_state *)sensor_data;
1098 *sensor_offset = sensor_state_data->sensor_offset;
1099 *event_state = sensor_state_data->event_state;
1100 *previous_event_state = sensor_state_data->previous_event_state;
1101 return PLDM_SUCCESS;
1102}
1103
1104int decode_numeric_sensor_data(const uint8_t *sensor_data,
1105 size_t sensor_data_length, uint8_t *event_state,
1106 uint8_t *previous_event_state,
1107 uint8_t *sensor_data_size,
1108 uint32_t *present_reading)
1109{
1110 if (sensor_data == NULL || sensor_data_size == NULL ||
1111 event_state == NULL || previous_event_state == NULL ||
1112 present_reading == NULL) {
1113 return PLDM_ERROR_INVALID_DATA;
1114 }
1115 if (sensor_data_length <
1116 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
1117 sensor_data_length >
1118 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
1119 return PLDM_ERROR_INVALID_LENGTH;
1120 }
1121 struct pldm_sensor_event_numeric_sensor_state *numeric_sensor_data =
1122 (struct pldm_sensor_event_numeric_sensor_state *)sensor_data;
1123 *event_state = numeric_sensor_data->event_state;
1124 *previous_event_state = numeric_sensor_data->previous_event_state;
1125 *sensor_data_size = numeric_sensor_data->sensor_data_size;
1126 uint8_t *present_reading_ptr = numeric_sensor_data->present_reading;
1127
1128 switch (*sensor_data_size) {
1129 case PLDM_SENSOR_DATA_SIZE_UINT8:
1130 case PLDM_SENSOR_DATA_SIZE_SINT8:
1131 if (sensor_data_length !=
1132 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_8BIT_DATA_LENGTH) {
1133 return PLDM_ERROR_INVALID_LENGTH;
1134 }
1135 *present_reading = present_reading_ptr[0];
1136 break;
1137 case PLDM_SENSOR_DATA_SIZE_UINT16:
1138 case PLDM_SENSOR_DATA_SIZE_SINT16:
1139 if (sensor_data_length !=
1140 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_16BIT_DATA_LENGTH) {
1141 return PLDM_ERROR_INVALID_LENGTH;
1142 }
1143 *present_reading = le16toh(present_reading_ptr[1] |
1144 (present_reading_ptr[0] << 8));
1145 break;
1146 case PLDM_SENSOR_DATA_SIZE_UINT32:
1147 case PLDM_SENSOR_DATA_SIZE_SINT32:
1148 if (sensor_data_length !=
1149 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_32BIT_DATA_LENGTH) {
1150 return PLDM_ERROR_INVALID_LENGTH;
1151 }
1152 *present_reading = le32toh(present_reading_ptr[3] |
1153 (present_reading_ptr[2] << 8) |
1154 (present_reading_ptr[1] << 16) |
1155 (present_reading_ptr[0] << 24));
1156 break;
1157 default:
1158 return PLDM_ERROR_INVALID_DATA;
1159 }
1160 return PLDM_SUCCESS;
1161}
1162
1163int encode_get_numeric_effecter_value_req(uint8_t instance_id,
1164 uint16_t effecter_id,
1165 struct pldm_msg *msg)
1166{
1167 if (msg == NULL) {
1168 return PLDM_ERROR_INVALID_DATA;
1169 }
1170
1171 struct pldm_header_info header = {0};
1172 header.msg_type = PLDM_REQUEST;
1173 header.instance = instance_id;
1174 header.pldm_type = PLDM_PLATFORM;
1175 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1176
1177 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1178 if (rc != PLDM_SUCCESS) {
1179 return rc;
1180 }
1181
1182 struct pldm_get_numeric_effecter_value_req *request =
1183 (struct pldm_get_numeric_effecter_value_req *)msg->payload;
1184 request->effecter_id = htole16(effecter_id);
1185
1186 return PLDM_SUCCESS;
1187}
1188
1189int encode_get_numeric_effecter_value_resp(
1190 uint8_t instance_id, uint8_t completion_code, uint8_t effecter_data_size,
1191 uint8_t effecter_oper_state, uint8_t *pending_value, uint8_t *present_value,
1192 struct pldm_msg *msg, size_t payload_length)
1193{
1194 if (msg == NULL || pending_value == NULL || present_value == NULL) {
1195 return PLDM_ERROR_INVALID_DATA;
1196 }
1197
1198 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1199 return PLDM_ERROR_INVALID_DATA;
1200 }
1201
1202 if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1203 return PLDM_ERROR_INVALID_DATA;
1204 }
1205
1206 struct pldm_header_info header = {0};
1207 header.msg_type = PLDM_RESPONSE;
1208 header.instance = instance_id;
1209 header.pldm_type = PLDM_PLATFORM;
1210 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1211
1212 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1213 if (rc != PLDM_SUCCESS) {
1214 return rc;
1215 }
1216
1217 struct pldm_get_numeric_effecter_value_resp *response =
1218 (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
1219
1220 response->completion_code = completion_code;
1221 response->effecter_data_size = effecter_data_size;
1222 response->effecter_oper_state = effecter_oper_state;
1223
1224 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1225 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1226 if (payload_length !=
1227 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1228 return PLDM_ERROR_INVALID_LENGTH;
1229 }
1230 response->pending_and_present_values[0] = *pending_value;
1231 response->pending_and_present_values[1] = *present_value;
1232
1233 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1234 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1235 if (payload_length !=
1236 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
1237 return PLDM_ERROR_INVALID_LENGTH;
1238 }
1239 uint16_t val_pending = *(uint16_t *)pending_value;
1240 val_pending = htole16(val_pending);
1241 memcpy(response->pending_and_present_values, &val_pending,
1242 sizeof(uint16_t));
1243 uint16_t val_present = *(uint16_t *)present_value;
1244 val_present = htole16(val_present);
1245 memcpy(
1246 (response->pending_and_present_values + sizeof(uint16_t)),
1247 &val_present, sizeof(uint16_t));
1248
1249 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1250 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1251 if (payload_length !=
1252 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
1253 return PLDM_ERROR_INVALID_LENGTH;
1254 }
1255 uint32_t val_pending = *(uint32_t *)pending_value;
1256 val_pending = htole32(val_pending);
1257 memcpy(response->pending_and_present_values, &val_pending,
1258 sizeof(uint32_t));
1259 uint32_t val_present = *(uint32_t *)present_value;
1260 val_present = htole32(val_present);
1261 memcpy(
1262 (response->pending_and_present_values + sizeof(uint32_t)),
1263 &val_present, sizeof(uint32_t));
1264 }
1265 return PLDM_SUCCESS;
1266}
1267
1268int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg,
1269 size_t payload_length,
1270 uint16_t *effecter_id)
1271{
1272 if (msg == NULL || effecter_id == NULL) {
1273 return PLDM_ERROR_INVALID_DATA;
1274 }
1275
1276 if (payload_length != PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES) {
1277 return PLDM_ERROR_INVALID_LENGTH;
1278 }
1279
1280 struct pldm_get_numeric_effecter_value_req *request =
1281 (struct pldm_get_numeric_effecter_value_req *)msg->payload;
1282
1283 *effecter_id = le16toh(request->effecter_id);
1284
1285 return PLDM_SUCCESS;
1286}
1287
1288int decode_get_numeric_effecter_value_resp(
1289 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
1290 uint8_t *effecter_data_size, uint8_t *effecter_oper_state,
1291 uint8_t *pending_value, uint8_t *present_value)
1292{
1293 if (msg == NULL || effecter_data_size == NULL ||
1294 effecter_oper_state == NULL || pending_value == NULL ||
1295 present_value == NULL) {
1296 return PLDM_ERROR_INVALID_DATA;
1297 }
1298
1299 *completion_code = msg->payload[0];
1300 if (PLDM_SUCCESS != *completion_code) {
1301 return PLDM_SUCCESS;
1302 }
1303
1304 if (payload_length < PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1305 return PLDM_ERROR_INVALID_LENGTH;
1306 }
1307
1308 struct pldm_get_numeric_effecter_value_resp *response =
1309 (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
1310
1311 *effecter_data_size = response->effecter_data_size;
1312 *effecter_oper_state = response->effecter_oper_state;
1313
1314 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1315 return PLDM_ERROR_INVALID_DATA;
1316 }
1317
1318 if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1319 return PLDM_ERROR_INVALID_DATA;
1320 }
1321
1322 if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1323 *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1324 if (payload_length !=
1325 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1326 return PLDM_ERROR_INVALID_LENGTH;
1327 }
1328 memcpy(pending_value, response->pending_and_present_values, 1);
1329 memcpy(present_value, &response->pending_and_present_values[1],
1330 1);
1331
1332 } else if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1333 *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1334 if (payload_length !=
1335 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
1336 return PLDM_ERROR_INVALID_LENGTH;
1337 }
1338 memcpy(pending_value, response->pending_and_present_values,
1339 sizeof(uint16_t));
1340 uint16_t *val_pending = (uint16_t *)pending_value;
1341 *val_pending = le16toh(*val_pending);
1342 memcpy(
1343 present_value,
1344 (response->pending_and_present_values + sizeof(uint16_t)),
1345 sizeof(uint16_t));
1346 uint16_t *val_present = (uint16_t *)present_value;
1347 *val_present = le16toh(*val_present);
1348
1349 } else if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1350 *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1351 if (payload_length !=
1352 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
1353 return PLDM_ERROR_INVALID_LENGTH;
1354 }
1355 memcpy(pending_value, response->pending_and_present_values,
1356 sizeof(uint32_t));
1357 uint32_t *val_pending = (uint32_t *)pending_value;
1358 *val_pending = le32toh(*val_pending);
1359 memcpy(
1360 present_value,
1361 (response->pending_and_present_values + sizeof(uint32_t)),
1362 sizeof(uint32_t));
1363 uint32_t *val_present = (uint32_t *)present_value;
1364 *val_present = le32toh(*val_present);
1365 }
1366 return PLDM_SUCCESS;
1367}
1368
1369int encode_pldm_pdr_repository_chg_event_data(
1370 uint8_t event_data_format, uint8_t number_of_change_records,
1371 const uint8_t *event_data_operations,
1372 const uint8_t *numbers_of_change_entries,
1373 const uint32_t *const *change_entries,
1374 struct pldm_pdr_repository_chg_event_data *event_data,
1375 size_t *actual_change_records_size, size_t max_change_records_size)
1376{
1377 if (event_data_operations == NULL ||
1378 numbers_of_change_entries == NULL || change_entries == NULL) {
1379 return PLDM_ERROR_INVALID_DATA;
1380 }
1381
1382 size_t expected_size =
1383 sizeof(event_data_format) + sizeof(number_of_change_records);
1384
1385 expected_size +=
1386 sizeof(*event_data_operations) * number_of_change_records;
1387 expected_size +=
1388 sizeof(*numbers_of_change_entries) * number_of_change_records;
1389
1390 for (uint8_t i = 0; i < number_of_change_records; ++i) {
1391 expected_size +=
1392 sizeof(*change_entries[0]) * numbers_of_change_entries[i];
1393 }
1394
1395 *actual_change_records_size = expected_size;
1396
1397 if (event_data == NULL) {
1398 return PLDM_SUCCESS;
1399 }
1400
1401 if (max_change_records_size < expected_size) {
1402 return PLDM_ERROR_INVALID_LENGTH;
1403 }
1404
1405 event_data->event_data_format = event_data_format;
1406 event_data->number_of_change_records = number_of_change_records;
1407
1408 struct pldm_pdr_repository_change_record_data *record_data =
1409 (struct pldm_pdr_repository_change_record_data *)
1410 event_data->change_records;
1411
1412 for (uint8_t i = 0; i < number_of_change_records; ++i) {
1413 record_data->event_data_operation = event_data_operations[i];
1414 record_data->number_of_change_entries =
1415 numbers_of_change_entries[i];
1416
1417 for (uint8_t j = 0; j < record_data->number_of_change_entries;
1418 ++j) {
1419 record_data->change_entry[j] =
1420 htole32(change_entries[i][j]);
1421 }
1422
1423 record_data = (struct pldm_pdr_repository_change_record_data
1424 *)(record_data->change_entry +
1425 record_data->number_of_change_entries);
1426 }
1427
1428 return PLDM_SUCCESS;
1429}
1430
1431int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data,
1432 size_t event_data_size,
1433 uint8_t *event_data_format,
1434 uint8_t *number_of_change_records,
1435 size_t *change_record_data_offset)
1436{
1437 if (event_data == NULL || event_data_format == NULL ||
1438 number_of_change_records == NULL ||
1439 change_record_data_offset == NULL) {
1440 return PLDM_ERROR_INVALID_DATA;
1441 }
1442 if (event_data_size < PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH) {
1443 return PLDM_ERROR_INVALID_LENGTH;
1444 }
1445
1446 struct pldm_pdr_repository_chg_event_data
1447 *pdr_repository_chg_event_data =
1448 (struct pldm_pdr_repository_chg_event_data *)event_data;
1449
1450 *event_data_format = pdr_repository_chg_event_data->event_data_format;
1451 *number_of_change_records =
1452 pdr_repository_chg_event_data->number_of_change_records;
1453 *change_record_data_offset =
1454 sizeof(*event_data_format) + sizeof(*number_of_change_records);
1455
1456 return PLDM_SUCCESS;
1457}
1458
1459int decode_pldm_pdr_repository_change_record_data(
1460 const uint8_t *change_record_data, size_t change_record_data_size,
1461 uint8_t *event_data_operation, uint8_t *number_of_change_entries,
1462 size_t *change_entry_data_offset)
1463{
1464 if (change_record_data == NULL || event_data_operation == NULL ||
1465 number_of_change_entries == NULL ||
1466 change_entry_data_offset == NULL) {
1467 return PLDM_ERROR_INVALID_DATA;
1468 }
1469 if (change_record_data_size <
1470 PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH) {
1471 return PLDM_ERROR_INVALID_LENGTH;
1472 }
1473
1474 struct pldm_pdr_repository_change_record_data
1475 *pdr_repository_change_record_data =
1476 (struct pldm_pdr_repository_change_record_data *)
1477 change_record_data;
1478
1479 *event_data_operation =
1480 pdr_repository_change_record_data->event_data_operation;
1481 *number_of_change_entries =
1482 pdr_repository_change_record_data->number_of_change_entries;
1483 *change_entry_data_offset =
1484 sizeof(*event_data_operation) + sizeof(*number_of_change_entries);
1485
1486 return PLDM_SUCCESS;
1487}
1488
1489int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id,
1490 uint8_t rearm_event_state,
1491 struct pldm_msg *msg)
1492{
1493 if (msg == NULL) {
1494 return PLDM_ERROR_INVALID_DATA;
1495 }
1496
1497 struct pldm_header_info header = {0};
1498 header.msg_type = PLDM_REQUEST;
1499 header.instance = instance_id;
1500 header.pldm_type = PLDM_PLATFORM;
1501 header.command = PLDM_GET_SENSOR_READING;
1502
1503 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1504 if (rc != PLDM_SUCCESS) {
1505 return rc;
1506 }
1507
1508 struct pldm_get_sensor_reading_req *request =
1509 (struct pldm_get_sensor_reading_req *)msg->payload;
1510
1511 request->sensor_id = htole16(sensor_id);
1512 request->rearm_event_state = rearm_event_state;
1513
1514 return PLDM_SUCCESS;
1515}
1516
1517int decode_get_sensor_reading_resp(
1518 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
1519 uint8_t *sensor_data_size, uint8_t *sensor_operational_state,
1520 uint8_t *sensor_event_message_enable, uint8_t *present_state,
1521 uint8_t *previous_state, uint8_t *event_state, uint8_t *present_reading)
1522{
1523 if (msg == NULL || completion_code == NULL ||
1524 sensor_data_size == NULL || sensor_operational_state == NULL ||
1525 sensor_event_message_enable == NULL || present_state == NULL ||
1526 previous_state == NULL || event_state == NULL ||
1527 present_reading == NULL) {
1528 return PLDM_ERROR_INVALID_DATA;
1529 }
1530
1531 *completion_code = msg->payload[0];
1532 if (PLDM_SUCCESS != *completion_code) {
1533 return PLDM_SUCCESS;
1534 }
1535
1536 if (payload_length < PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
1537 return PLDM_ERROR_INVALID_LENGTH;
1538 }
1539
1540 struct pldm_get_sensor_reading_resp *response =
1541 (struct pldm_get_sensor_reading_resp *)msg->payload;
1542
1543 if (response->sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) {
1544 return PLDM_ERROR_INVALID_DATA;
1545 }
1546
1547 *sensor_data_size = response->sensor_data_size;
1548 *sensor_operational_state = response->sensor_operational_state;
1549 *sensor_event_message_enable = response->sensor_event_message_enable;
1550 *present_state = response->present_state;
1551 *previous_state = response->previous_state;
1552 *event_state = response->event_state;
1553
1554 if (*sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1555 *sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1556 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
1557 return PLDM_ERROR_INVALID_LENGTH;
1558 }
1559 *present_reading = response->present_reading[0];
1560
1561 } else if (*sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1562 *sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1563 if (payload_length !=
1564 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
1565 return PLDM_ERROR_INVALID_LENGTH;
1566 }
1567 memcpy(present_reading, response->present_reading, 2);
1568 uint16_t *val = (uint16_t *)(present_reading);
1569 *val = le16toh(*val);
1570
1571 } else if (*sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1572 *sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1573 if (payload_length !=
1574 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
1575 return PLDM_ERROR_INVALID_LENGTH;
1576 }
1577 memcpy(present_reading, response->present_reading, 4);
1578 uint32_t *val = (uint32_t *)(present_reading);
1579 *val = le32toh(*val);
1580 }
1581
1582 return PLDM_SUCCESS;
1583}
1584
1585int encode_get_sensor_reading_resp(
1586 uint8_t instance_id, uint8_t completion_code, uint8_t sensor_data_size,
1587 uint8_t sensor_operational_state, uint8_t sensor_event_message_enable,
1588 uint8_t present_state, uint8_t previous_state, uint8_t event_state,
1589 uint8_t *present_reading, struct pldm_msg *msg, size_t payload_length)
1590{
1591 if (msg == NULL || present_reading == NULL) {
1592 return PLDM_ERROR_INVALID_DATA;
1593 }
1594
1595 if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1596 return PLDM_ERROR_INVALID_DATA;
1597 }
1598
1599 struct pldm_header_info header = {0};
1600 header.msg_type = PLDM_RESPONSE;
1601 header.instance = instance_id;
1602 header.pldm_type = PLDM_PLATFORM;
1603 header.command = PLDM_GET_SENSOR_READING;
1604
1605 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1606 if (rc != PLDM_SUCCESS) {
1607 return rc;
1608 }
1609
1610 struct pldm_get_sensor_reading_resp *response =
1611 (struct pldm_get_sensor_reading_resp *)msg->payload;
1612
1613 response->completion_code = completion_code;
1614 response->sensor_data_size = sensor_data_size;
1615 response->sensor_operational_state = sensor_operational_state;
1616 response->sensor_event_message_enable = sensor_event_message_enable;
1617 response->present_state = present_state;
1618 response->previous_state = previous_state;
1619 response->event_state = event_state;
1620
1621 if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1622 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1623 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
1624 return PLDM_ERROR_INVALID_LENGTH;
1625 }
1626 response->present_reading[0] = *present_reading;
1627
1628 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1629 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1630 if (payload_length !=
1631 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
1632 return PLDM_ERROR_INVALID_LENGTH;
1633 }
1634 uint16_t val = *(uint16_t *)present_reading;
1635 val = htole16(val);
1636 memcpy(response->present_reading, &val, 2);
1637
1638 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1639 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1640 if (payload_length !=
1641 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
1642 return PLDM_ERROR_INVALID_LENGTH;
1643 }
1644 uint32_t val = *(uint32_t *)present_reading;
1645 val = htole32(val);
1646 memcpy(response->present_reading, &val, 4);
1647 }
1648
1649 return PLDM_SUCCESS;
1650}
1651
1652int decode_get_sensor_reading_req(const struct pldm_msg *msg,
1653 size_t payload_length, uint16_t *sensor_id,
1654 uint8_t *rearm_event_state)
1655{
1656 if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) {
1657 return PLDM_ERROR_INVALID_DATA;
1658 }
1659
1660 if (payload_length != PLDM_GET_SENSOR_READING_REQ_BYTES) {
1661 return PLDM_ERROR_INVALID_LENGTH;
1662 }
1663
1664 struct pldm_get_sensor_reading_req *request =
1665 (struct pldm_get_sensor_reading_req *)msg->payload;
1666
1667 *sensor_id = le16toh(request->sensor_id);
1668 *rearm_event_state = request->rearm_event_state;
1669
1670 return PLDM_SUCCESS;
1671}
1672
1673int encode_set_event_receiver_req(uint8_t instance_id,
1674 uint8_t event_message_global_enable,
1675 uint8_t transport_protocol_type,
1676 uint8_t event_receiver_address_info,
1677 uint16_t heartbeat_timer,
1678 struct pldm_msg *msg)
1679{
1680 if (msg == NULL) {
1681 return PLDM_ERROR_INVALID_DATA;
1682 }
1683
1684 if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
1685 return PLDM_ERROR_INVALID_DATA;
1686 }
1687
1688 struct pldm_header_info header = {0};
1689 header.msg_type = PLDM_REQUEST;
1690 header.instance = instance_id;
1691 header.pldm_type = PLDM_PLATFORM;
1692 header.command = PLDM_SET_EVENT_RECEIVER;
1693
1694 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1695 if (rc != PLDM_SUCCESS) {
1696 return rc;
1697 }
1698
1699 struct pldm_set_event_receiver_req *request =
1700 (struct pldm_set_event_receiver_req *)msg->payload;
1701 request->event_message_global_enable = event_message_global_enable;
1702
1703 request->transport_protocol_type = transport_protocol_type;
1704 request->event_receiver_address_info = event_receiver_address_info;
1705
1706 if (event_message_global_enable ==
1707 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {
1708 if (heartbeat_timer == 0) {
1709 return PLDM_ERROR_INVALID_DATA;
1710 }
1711 request->heartbeat_timer = htole16(heartbeat_timer);
1712 }
1713
1714 return PLDM_SUCCESS;
1715}
1716
1717int decode_set_event_receiver_resp(const struct pldm_msg *msg,
1718 size_t payload_length,
1719 uint8_t *completion_code)
1720{
1721 if (msg == NULL || completion_code == NULL) {
1722 return PLDM_ERROR_INVALID_DATA;
1723 }
1724
1725 *completion_code = msg->payload[0];
1726 if (PLDM_SUCCESS != *completion_code) {
1727 return PLDM_SUCCESS;
1728 }
1729
1730 if (payload_length > PLDM_SET_EVENT_RECEIVER_RESP_BYTES) {
1731 return PLDM_ERROR_INVALID_LENGTH;
1732 }
1733
1734 return PLDM_SUCCESS;
1735}
1736
1737int decode_set_event_receiver_req(const struct pldm_msg *msg,
1738 size_t payload_length,
1739 uint8_t *event_message_global_enable,
1740 uint8_t *transport_protocol_type,
1741 uint8_t *event_receiver_address_info,
1742 uint16_t *heartbeat_timer)
1743
1744{
1745 if (msg == NULL || event_message_global_enable == NULL ||
1746 transport_protocol_type == NULL ||
1747 event_receiver_address_info == NULL || heartbeat_timer == NULL) {
1748 return PLDM_ERROR_INVALID_DATA;
1749 }
1750
1751 if (payload_length != PLDM_SET_EVENT_RECEIVER_REQ_BYTES) {
1752 return PLDM_ERROR_INVALID_LENGTH;
1753 }
1754
1755 struct pldm_set_event_receiver_req *request =
1756 (struct pldm_set_event_receiver_req *)msg->payload;
1757
1758 if ((*event_message_global_enable ==
1759 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) &&
1760 (*heartbeat_timer == 0)) {
1761 return PLDM_ERROR_INVALID_DATA;
1762 }
1763
1764 *event_message_global_enable = request->event_message_global_enable,
1765 *transport_protocol_type = request->transport_protocol_type,
1766 *event_receiver_address_info = request->event_receiver_address_info,
1767 *heartbeat_timer = le16toh(request->heartbeat_timer);
1768
1769 return PLDM_SUCCESS;
1770}
1771
1772int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code,
1773 struct pldm_msg *msg)
1774
1775{
1776 if (msg == NULL) {
1777 return PLDM_ERROR_INVALID_DATA;
1778 }
1779
1780 struct pldm_header_info header = {0};
1781 header.instance = instance_id;
1782 header.msg_type = PLDM_RESPONSE;
1783 header.pldm_type = PLDM_PLATFORM;
1784 header.command = PLDM_SET_EVENT_RECEIVER;
1785
1786 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1787 if (rc != PLDM_SUCCESS) {
1788 return rc;
1789 }
1790
1791 msg->payload[0] = completion_code;
1792
1793 return PLDM_SUCCESS;
1794}