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