blob: 0abd6e89dadd42198f139360cdd25e3a4e7efa0f [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:
1220 case PLDM_SENSOR_DATA_SIZE_SINT8:
1221 if (sensor_data_length !=
1222 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_8BIT_DATA_LENGTH) {
1223 return PLDM_ERROR_INVALID_LENGTH;
1224 }
1225 *present_reading = present_reading_ptr[0];
1226 break;
1227 case PLDM_SENSOR_DATA_SIZE_UINT16:
1228 case PLDM_SENSOR_DATA_SIZE_SINT16:
1229 if (sensor_data_length !=
1230 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_16BIT_DATA_LENGTH) {
1231 return PLDM_ERROR_INVALID_LENGTH;
1232 }
1233 *present_reading = le16toh(present_reading_ptr[1] |
1234 (present_reading_ptr[0] << 8));
1235 break;
1236 case PLDM_SENSOR_DATA_SIZE_UINT32:
1237 case PLDM_SENSOR_DATA_SIZE_SINT32:
1238 if (sensor_data_length !=
1239 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_32BIT_DATA_LENGTH) {
1240 return PLDM_ERROR_INVALID_LENGTH;
1241 }
1242 *present_reading = le32toh(present_reading_ptr[3] |
1243 (present_reading_ptr[2] << 8) |
1244 (present_reading_ptr[1] << 16) |
1245 (present_reading_ptr[0] << 24));
1246 break;
1247 default:
1248 return PLDM_ERROR_INVALID_DATA;
1249 }
1250 return PLDM_SUCCESS;
1251}
1252
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301253#define PLDM_NUMERIC_SENSOR_VALUE_PDR_MIN_SIZE 69
1254int decode_numeric_sensor_pdr_data(
1255 const void *pdr_data, size_t pdr_data_length,
1256 struct pldm_numeric_sensor_value_pdr *pdr_value)
1257{
1258 struct pldm_msgbuf _buf;
1259 struct pldm_msgbuf *buf = &_buf;
1260 int rc;
1261
1262 rc = pldm_msgbuf_init(buf, PLDM_NUMERIC_SENSOR_VALUE_PDR_MIN_SIZE,
1263 pdr_data, pdr_data_length);
1264 if (rc) {
1265 return rc;
1266 }
1267
1268 rc = pldm_msgbuf_extract_value_pdr_hdr(buf, &pdr_value->hdr);
1269 if (rc) {
1270 return rc;
1271 }
1272
1273 rc = pldm_platform_pdr_hdr_validate(
1274 &pdr_value->hdr, PLDM_NUMERIC_SENSOR_VALUE_PDR_MIN_SIZE,
1275 pdr_data_length);
1276 if (rc) {
1277 return rc;
1278 }
1279
1280 pldm_msgbuf_extract(buf, &pdr_value->terminus_handle);
1281 pldm_msgbuf_extract(buf, &pdr_value->sensor_id);
1282 pldm_msgbuf_extract(buf, &pdr_value->entity_type);
1283 pldm_msgbuf_extract(buf, &pdr_value->entity_instance_num);
1284 pldm_msgbuf_extract(buf, &pdr_value->container_id);
1285 pldm_msgbuf_extract(buf, &pdr_value->sensor_init);
1286 pldm_msgbuf_extract(buf, &pdr_value->sensor_auxiliary_names_pdr);
1287 pldm_msgbuf_extract(buf, &pdr_value->base_unit);
1288 pldm_msgbuf_extract(buf, &pdr_value->unit_modifier);
1289 pldm_msgbuf_extract(buf, &pdr_value->rate_unit);
1290 pldm_msgbuf_extract(buf, &pdr_value->base_oem_unit_handle);
1291 pldm_msgbuf_extract(buf, &pdr_value->aux_unit);
1292 pldm_msgbuf_extract(buf, &pdr_value->aux_unit_modifier);
1293 pldm_msgbuf_extract(buf, &pdr_value->aux_rate_unit);
1294 pldm_msgbuf_extract(buf, &pdr_value->rel);
1295 pldm_msgbuf_extract(buf, &pdr_value->aux_oem_unit_handle);
1296 pldm_msgbuf_extract(buf, &pdr_value->is_linear);
1297
1298 rc = pldm_msgbuf_extract(buf, &pdr_value->sensor_data_size);
1299 if (rc) {
1300 return rc;
1301 }
1302 if (pdr_value->sensor_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
1303 return PLDM_ERROR_INVALID_DATA;
1304 }
1305
1306 pldm_msgbuf_extract(buf, &pdr_value->resolution);
1307 pldm_msgbuf_extract(buf, &pdr_value->offset);
1308 pldm_msgbuf_extract(buf, &pdr_value->accuracy);
1309 pldm_msgbuf_extract(buf, &pdr_value->plus_tolerance);
1310 pldm_msgbuf_extract(buf, &pdr_value->minus_tolerance);
1311 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1312 &pdr_value->hysteresis);
1313 pldm_msgbuf_extract(buf, &pdr_value->supported_thresholds.byte);
1314 pldm_msgbuf_extract(
1315 buf, &pdr_value->threshold_and_hysteresis_volatility.byte);
1316 pldm_msgbuf_extract(buf, &pdr_value->state_transition_interval);
1317 pldm_msgbuf_extract(buf, &pdr_value->update_interval);
1318 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1319 &pdr_value->max_readable);
1320 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1321 &pdr_value->min_readable);
1322
1323 rc = pldm_msgbuf_extract(buf, &pdr_value->range_field_format);
1324 if (rc) {
1325 return rc;
1326 }
1327 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
1328 return PLDM_ERROR_INVALID_DATA;
1329 }
1330
1331 pldm_msgbuf_extract(buf, &pdr_value->range_field_support.byte);
1332 pldm_msgbuf_extract_range_field_format(
1333 buf, pdr_value->range_field_format, &pdr_value->nominal_value);
1334 pldm_msgbuf_extract_range_field_format(
1335 buf, pdr_value->range_field_format, &pdr_value->normal_max);
1336 pldm_msgbuf_extract_range_field_format(
1337 buf, pdr_value->range_field_format, &pdr_value->normal_min);
1338 pldm_msgbuf_extract_range_field_format(
1339 buf, pdr_value->range_field_format, &pdr_value->warning_high);
1340 pldm_msgbuf_extract_range_field_format(
1341 buf, pdr_value->range_field_format, &pdr_value->warning_low);
1342 pldm_msgbuf_extract_range_field_format(
1343 buf, pdr_value->range_field_format, &pdr_value->critical_high);
1344 pldm_msgbuf_extract_range_field_format(
1345 buf, pdr_value->range_field_format, &pdr_value->critical_low);
1346 pldm_msgbuf_extract_range_field_format(
1347 buf, pdr_value->range_field_format, &pdr_value->fatal_high);
1348 pldm_msgbuf_extract_range_field_format(
1349 buf, pdr_value->range_field_format, &pdr_value->fatal_low);
1350
1351 return pldm_msgbuf_destroy(buf);
1352}
1353
Andrew Jeffery9c766792022-08-10 23:12:49 +09301354int encode_get_numeric_effecter_value_req(uint8_t instance_id,
1355 uint16_t effecter_id,
1356 struct pldm_msg *msg)
1357{
1358 if (msg == NULL) {
1359 return PLDM_ERROR_INVALID_DATA;
1360 }
1361
1362 struct pldm_header_info header = {0};
1363 header.msg_type = PLDM_REQUEST;
1364 header.instance = instance_id;
1365 header.pldm_type = PLDM_PLATFORM;
1366 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1367
1368 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1369 if (rc != PLDM_SUCCESS) {
1370 return rc;
1371 }
1372
1373 struct pldm_get_numeric_effecter_value_req *request =
1374 (struct pldm_get_numeric_effecter_value_req *)msg->payload;
1375 request->effecter_id = htole16(effecter_id);
1376
1377 return PLDM_SUCCESS;
1378}
1379
1380int encode_get_numeric_effecter_value_resp(
1381 uint8_t instance_id, uint8_t completion_code, uint8_t effecter_data_size,
Andrew Jefferydebe6b32023-04-05 20:30:46 +09301382 uint8_t effecter_oper_state, const uint8_t *pending_value,
1383 const uint8_t *present_value, struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301384{
1385 if (msg == NULL || pending_value == NULL || present_value == NULL) {
1386 return PLDM_ERROR_INVALID_DATA;
1387 }
1388
1389 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1390 return PLDM_ERROR_INVALID_DATA;
1391 }
1392
1393 if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1394 return PLDM_ERROR_INVALID_DATA;
1395 }
1396
1397 struct pldm_header_info header = {0};
1398 header.msg_type = PLDM_RESPONSE;
1399 header.instance = instance_id;
1400 header.pldm_type = PLDM_PLATFORM;
1401 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1402
1403 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1404 if (rc != PLDM_SUCCESS) {
1405 return rc;
1406 }
1407
1408 struct pldm_get_numeric_effecter_value_resp *response =
1409 (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
1410
1411 response->completion_code = completion_code;
1412 response->effecter_data_size = effecter_data_size;
1413 response->effecter_oper_state = effecter_oper_state;
1414
1415 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1416 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1417 if (payload_length !=
1418 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1419 return PLDM_ERROR_INVALID_LENGTH;
1420 }
1421 response->pending_and_present_values[0] = *pending_value;
1422 response->pending_and_present_values[1] = *present_value;
1423
1424 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1425 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1426 if (payload_length !=
1427 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
1428 return PLDM_ERROR_INVALID_LENGTH;
1429 }
1430 uint16_t val_pending = *(uint16_t *)pending_value;
1431 val_pending = htole16(val_pending);
1432 memcpy(response->pending_and_present_values, &val_pending,
1433 sizeof(uint16_t));
1434 uint16_t val_present = *(uint16_t *)present_value;
1435 val_present = htole16(val_present);
1436 memcpy(
1437 (response->pending_and_present_values + sizeof(uint16_t)),
1438 &val_present, sizeof(uint16_t));
1439
1440 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1441 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1442 if (payload_length !=
1443 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
1444 return PLDM_ERROR_INVALID_LENGTH;
1445 }
1446 uint32_t val_pending = *(uint32_t *)pending_value;
1447 val_pending = htole32(val_pending);
1448 memcpy(response->pending_and_present_values, &val_pending,
1449 sizeof(uint32_t));
1450 uint32_t val_present = *(uint32_t *)present_value;
1451 val_present = htole32(val_present);
1452 memcpy(
1453 (response->pending_and_present_values + sizeof(uint32_t)),
1454 &val_present, sizeof(uint32_t));
1455 }
1456 return PLDM_SUCCESS;
1457}
1458
1459int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg,
1460 size_t payload_length,
1461 uint16_t *effecter_id)
1462{
1463 if (msg == NULL || effecter_id == NULL) {
1464 return PLDM_ERROR_INVALID_DATA;
1465 }
1466
1467 if (payload_length != PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES) {
1468 return PLDM_ERROR_INVALID_LENGTH;
1469 }
1470
1471 struct pldm_get_numeric_effecter_value_req *request =
1472 (struct pldm_get_numeric_effecter_value_req *)msg->payload;
1473
1474 *effecter_id = le16toh(request->effecter_id);
1475
1476 return PLDM_SUCCESS;
1477}
1478
1479int decode_get_numeric_effecter_value_resp(
1480 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
1481 uint8_t *effecter_data_size, uint8_t *effecter_oper_state,
1482 uint8_t *pending_value, uint8_t *present_value)
1483{
1484 if (msg == NULL || effecter_data_size == NULL ||
1485 effecter_oper_state == NULL || pending_value == NULL ||
1486 present_value == NULL) {
1487 return PLDM_ERROR_INVALID_DATA;
1488 }
1489
1490 *completion_code = msg->payload[0];
1491 if (PLDM_SUCCESS != *completion_code) {
1492 return PLDM_SUCCESS;
1493 }
1494
1495 if (payload_length < PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1496 return PLDM_ERROR_INVALID_LENGTH;
1497 }
1498
1499 struct pldm_get_numeric_effecter_value_resp *response =
1500 (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
1501
1502 *effecter_data_size = response->effecter_data_size;
1503 *effecter_oper_state = response->effecter_oper_state;
1504
1505 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1506 return PLDM_ERROR_INVALID_DATA;
1507 }
1508
1509 if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1510 return PLDM_ERROR_INVALID_DATA;
1511 }
1512
1513 if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1514 *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1515 if (payload_length !=
1516 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1517 return PLDM_ERROR_INVALID_LENGTH;
1518 }
1519 memcpy(pending_value, response->pending_and_present_values, 1);
1520 memcpy(present_value, &response->pending_and_present_values[1],
1521 1);
1522
1523 } else if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1524 *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1525 if (payload_length !=
1526 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
1527 return PLDM_ERROR_INVALID_LENGTH;
1528 }
1529 memcpy(pending_value, response->pending_and_present_values,
1530 sizeof(uint16_t));
1531 uint16_t *val_pending = (uint16_t *)pending_value;
1532 *val_pending = le16toh(*val_pending);
1533 memcpy(
1534 present_value,
1535 (response->pending_and_present_values + sizeof(uint16_t)),
1536 sizeof(uint16_t));
1537 uint16_t *val_present = (uint16_t *)present_value;
1538 *val_present = le16toh(*val_present);
1539
1540 } else if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1541 *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1542 if (payload_length !=
1543 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
1544 return PLDM_ERROR_INVALID_LENGTH;
1545 }
1546 memcpy(pending_value, response->pending_and_present_values,
1547 sizeof(uint32_t));
1548 uint32_t *val_pending = (uint32_t *)pending_value;
1549 *val_pending = le32toh(*val_pending);
1550 memcpy(
1551 present_value,
1552 (response->pending_and_present_values + sizeof(uint32_t)),
1553 sizeof(uint32_t));
1554 uint32_t *val_present = (uint32_t *)present_value;
1555 *val_present = le32toh(*val_present);
1556 }
1557 return PLDM_SUCCESS;
1558}
1559
1560int encode_pldm_pdr_repository_chg_event_data(
1561 uint8_t event_data_format, uint8_t number_of_change_records,
1562 const uint8_t *event_data_operations,
1563 const uint8_t *numbers_of_change_entries,
1564 const uint32_t *const *change_entries,
1565 struct pldm_pdr_repository_chg_event_data *event_data,
1566 size_t *actual_change_records_size, size_t max_change_records_size)
1567{
1568 if (event_data_operations == NULL ||
1569 numbers_of_change_entries == NULL || change_entries == NULL) {
1570 return PLDM_ERROR_INVALID_DATA;
1571 }
1572
1573 size_t expected_size =
1574 sizeof(event_data_format) + sizeof(number_of_change_records);
1575
1576 expected_size +=
1577 sizeof(*event_data_operations) * number_of_change_records;
1578 expected_size +=
1579 sizeof(*numbers_of_change_entries) * number_of_change_records;
1580
1581 for (uint8_t i = 0; i < number_of_change_records; ++i) {
1582 expected_size +=
1583 sizeof(*change_entries[0]) * numbers_of_change_entries[i];
1584 }
1585
1586 *actual_change_records_size = expected_size;
1587
1588 if (event_data == NULL) {
1589 return PLDM_SUCCESS;
1590 }
1591
1592 if (max_change_records_size < expected_size) {
1593 return PLDM_ERROR_INVALID_LENGTH;
1594 }
1595
1596 event_data->event_data_format = event_data_format;
1597 event_data->number_of_change_records = number_of_change_records;
1598
1599 struct pldm_pdr_repository_change_record_data *record_data =
1600 (struct pldm_pdr_repository_change_record_data *)
1601 event_data->change_records;
1602
1603 for (uint8_t i = 0; i < number_of_change_records; ++i) {
1604 record_data->event_data_operation = event_data_operations[i];
1605 record_data->number_of_change_entries =
1606 numbers_of_change_entries[i];
1607
1608 for (uint8_t j = 0; j < record_data->number_of_change_entries;
1609 ++j) {
1610 record_data->change_entry[j] =
1611 htole32(change_entries[i][j]);
1612 }
1613
1614 record_data = (struct pldm_pdr_repository_change_record_data
1615 *)(record_data->change_entry +
1616 record_data->number_of_change_entries);
1617 }
1618
1619 return PLDM_SUCCESS;
1620}
1621
1622int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data,
1623 size_t event_data_size,
1624 uint8_t *event_data_format,
1625 uint8_t *number_of_change_records,
1626 size_t *change_record_data_offset)
1627{
1628 if (event_data == NULL || event_data_format == NULL ||
1629 number_of_change_records == NULL ||
1630 change_record_data_offset == NULL) {
1631 return PLDM_ERROR_INVALID_DATA;
1632 }
1633 if (event_data_size < PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH) {
1634 return PLDM_ERROR_INVALID_LENGTH;
1635 }
1636
1637 struct pldm_pdr_repository_chg_event_data
1638 *pdr_repository_chg_event_data =
1639 (struct pldm_pdr_repository_chg_event_data *)event_data;
1640
1641 *event_data_format = pdr_repository_chg_event_data->event_data_format;
1642 *number_of_change_records =
1643 pdr_repository_chg_event_data->number_of_change_records;
1644 *change_record_data_offset =
1645 sizeof(*event_data_format) + sizeof(*number_of_change_records);
1646
1647 return PLDM_SUCCESS;
1648}
1649
1650int decode_pldm_pdr_repository_change_record_data(
1651 const uint8_t *change_record_data, size_t change_record_data_size,
1652 uint8_t *event_data_operation, uint8_t *number_of_change_entries,
1653 size_t *change_entry_data_offset)
1654{
1655 if (change_record_data == NULL || event_data_operation == NULL ||
1656 number_of_change_entries == NULL ||
1657 change_entry_data_offset == NULL) {
1658 return PLDM_ERROR_INVALID_DATA;
1659 }
1660 if (change_record_data_size <
1661 PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH) {
1662 return PLDM_ERROR_INVALID_LENGTH;
1663 }
1664
1665 struct pldm_pdr_repository_change_record_data
1666 *pdr_repository_change_record_data =
1667 (struct pldm_pdr_repository_change_record_data *)
1668 change_record_data;
1669
1670 *event_data_operation =
1671 pdr_repository_change_record_data->event_data_operation;
1672 *number_of_change_entries =
1673 pdr_repository_change_record_data->number_of_change_entries;
1674 *change_entry_data_offset =
1675 sizeof(*event_data_operation) + sizeof(*number_of_change_entries);
1676
1677 return PLDM_SUCCESS;
1678}
1679
1680int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id,
1681 uint8_t rearm_event_state,
1682 struct pldm_msg *msg)
1683{
1684 if (msg == NULL) {
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_GET_SENSOR_READING;
1693
1694 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1695 if (rc != PLDM_SUCCESS) {
1696 return rc;
1697 }
1698
1699 struct pldm_get_sensor_reading_req *request =
1700 (struct pldm_get_sensor_reading_req *)msg->payload;
1701
1702 request->sensor_id = htole16(sensor_id);
1703 request->rearm_event_state = rearm_event_state;
1704
1705 return PLDM_SUCCESS;
1706}
1707
1708int decode_get_sensor_reading_resp(
1709 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
1710 uint8_t *sensor_data_size, uint8_t *sensor_operational_state,
1711 uint8_t *sensor_event_message_enable, uint8_t *present_state,
1712 uint8_t *previous_state, uint8_t *event_state, uint8_t *present_reading)
1713{
1714 if (msg == NULL || completion_code == NULL ||
1715 sensor_data_size == NULL || sensor_operational_state == NULL ||
1716 sensor_event_message_enable == NULL || present_state == NULL ||
1717 previous_state == NULL || event_state == NULL ||
1718 present_reading == NULL) {
1719 return PLDM_ERROR_INVALID_DATA;
1720 }
1721
1722 *completion_code = msg->payload[0];
1723 if (PLDM_SUCCESS != *completion_code) {
1724 return PLDM_SUCCESS;
1725 }
1726
1727 if (payload_length < PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
1728 return PLDM_ERROR_INVALID_LENGTH;
1729 }
1730
1731 struct pldm_get_sensor_reading_resp *response =
1732 (struct pldm_get_sensor_reading_resp *)msg->payload;
1733
1734 if (response->sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) {
1735 return PLDM_ERROR_INVALID_DATA;
1736 }
1737
1738 *sensor_data_size = response->sensor_data_size;
1739 *sensor_operational_state = response->sensor_operational_state;
1740 *sensor_event_message_enable = response->sensor_event_message_enable;
1741 *present_state = response->present_state;
1742 *previous_state = response->previous_state;
1743 *event_state = response->event_state;
1744
1745 if (*sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1746 *sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1747 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
1748 return PLDM_ERROR_INVALID_LENGTH;
1749 }
1750 *present_reading = response->present_reading[0];
1751
1752 } else if (*sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1753 *sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1754 if (payload_length !=
1755 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
1756 return PLDM_ERROR_INVALID_LENGTH;
1757 }
1758 memcpy(present_reading, response->present_reading, 2);
1759 uint16_t *val = (uint16_t *)(present_reading);
1760 *val = le16toh(*val);
1761
1762 } else if (*sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1763 *sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1764 if (payload_length !=
1765 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
1766 return PLDM_ERROR_INVALID_LENGTH;
1767 }
1768 memcpy(present_reading, response->present_reading, 4);
1769 uint32_t *val = (uint32_t *)(present_reading);
1770 *val = le32toh(*val);
1771 }
1772
1773 return PLDM_SUCCESS;
1774}
1775
1776int encode_get_sensor_reading_resp(
1777 uint8_t instance_id, uint8_t completion_code, uint8_t sensor_data_size,
1778 uint8_t sensor_operational_state, uint8_t sensor_event_message_enable,
1779 uint8_t present_state, uint8_t previous_state, uint8_t event_state,
Andrew Jefferydebe6b32023-04-05 20:30:46 +09301780 const uint8_t *present_reading, struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301781{
1782 if (msg == NULL || present_reading == NULL) {
1783 return PLDM_ERROR_INVALID_DATA;
1784 }
1785
1786 if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1787 return PLDM_ERROR_INVALID_DATA;
1788 }
1789
1790 struct pldm_header_info header = {0};
1791 header.msg_type = PLDM_RESPONSE;
1792 header.instance = instance_id;
1793 header.pldm_type = PLDM_PLATFORM;
1794 header.command = PLDM_GET_SENSOR_READING;
1795
1796 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1797 if (rc != PLDM_SUCCESS) {
1798 return rc;
1799 }
1800
1801 struct pldm_get_sensor_reading_resp *response =
1802 (struct pldm_get_sensor_reading_resp *)msg->payload;
1803
1804 response->completion_code = completion_code;
1805 response->sensor_data_size = sensor_data_size;
1806 response->sensor_operational_state = sensor_operational_state;
1807 response->sensor_event_message_enable = sensor_event_message_enable;
1808 response->present_state = present_state;
1809 response->previous_state = previous_state;
1810 response->event_state = event_state;
1811
1812 if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1813 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1814 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
1815 return PLDM_ERROR_INVALID_LENGTH;
1816 }
1817 response->present_reading[0] = *present_reading;
1818
1819 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1820 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1821 if (payload_length !=
1822 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
1823 return PLDM_ERROR_INVALID_LENGTH;
1824 }
1825 uint16_t val = *(uint16_t *)present_reading;
1826 val = htole16(val);
1827 memcpy(response->present_reading, &val, 2);
1828
1829 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1830 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1831 if (payload_length !=
1832 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
1833 return PLDM_ERROR_INVALID_LENGTH;
1834 }
1835 uint32_t val = *(uint32_t *)present_reading;
1836 val = htole32(val);
1837 memcpy(response->present_reading, &val, 4);
1838 }
1839
1840 return PLDM_SUCCESS;
1841}
1842
1843int decode_get_sensor_reading_req(const struct pldm_msg *msg,
1844 size_t payload_length, uint16_t *sensor_id,
1845 uint8_t *rearm_event_state)
1846{
1847 if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) {
1848 return PLDM_ERROR_INVALID_DATA;
1849 }
1850
1851 if (payload_length != PLDM_GET_SENSOR_READING_REQ_BYTES) {
1852 return PLDM_ERROR_INVALID_LENGTH;
1853 }
1854
1855 struct pldm_get_sensor_reading_req *request =
1856 (struct pldm_get_sensor_reading_req *)msg->payload;
1857
1858 *sensor_id = le16toh(request->sensor_id);
1859 *rearm_event_state = request->rearm_event_state;
1860
1861 return PLDM_SUCCESS;
1862}
1863
1864int encode_set_event_receiver_req(uint8_t instance_id,
1865 uint8_t event_message_global_enable,
1866 uint8_t transport_protocol_type,
1867 uint8_t event_receiver_address_info,
1868 uint16_t heartbeat_timer,
1869 struct pldm_msg *msg)
1870{
1871 if (msg == NULL) {
1872 return PLDM_ERROR_INVALID_DATA;
1873 }
1874
1875 if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
1876 return PLDM_ERROR_INVALID_DATA;
1877 }
1878
1879 struct pldm_header_info header = {0};
1880 header.msg_type = PLDM_REQUEST;
1881 header.instance = instance_id;
1882 header.pldm_type = PLDM_PLATFORM;
1883 header.command = PLDM_SET_EVENT_RECEIVER;
1884
1885 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1886 if (rc != PLDM_SUCCESS) {
1887 return rc;
1888 }
1889
1890 struct pldm_set_event_receiver_req *request =
1891 (struct pldm_set_event_receiver_req *)msg->payload;
1892 request->event_message_global_enable = event_message_global_enable;
1893
1894 request->transport_protocol_type = transport_protocol_type;
1895 request->event_receiver_address_info = event_receiver_address_info;
1896
1897 if (event_message_global_enable ==
1898 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {
1899 if (heartbeat_timer == 0) {
1900 return PLDM_ERROR_INVALID_DATA;
1901 }
1902 request->heartbeat_timer = htole16(heartbeat_timer);
1903 }
1904
1905 return PLDM_SUCCESS;
1906}
1907
1908int decode_set_event_receiver_resp(const struct pldm_msg *msg,
1909 size_t payload_length,
1910 uint8_t *completion_code)
1911{
1912 if (msg == NULL || completion_code == NULL) {
1913 return PLDM_ERROR_INVALID_DATA;
1914 }
1915
1916 *completion_code = msg->payload[0];
1917 if (PLDM_SUCCESS != *completion_code) {
1918 return PLDM_SUCCESS;
1919 }
1920
1921 if (payload_length > PLDM_SET_EVENT_RECEIVER_RESP_BYTES) {
1922 return PLDM_ERROR_INVALID_LENGTH;
1923 }
1924
1925 return PLDM_SUCCESS;
1926}
1927
1928int decode_set_event_receiver_req(const struct pldm_msg *msg,
1929 size_t payload_length,
1930 uint8_t *event_message_global_enable,
1931 uint8_t *transport_protocol_type,
1932 uint8_t *event_receiver_address_info,
1933 uint16_t *heartbeat_timer)
1934
1935{
1936 if (msg == NULL || event_message_global_enable == NULL ||
1937 transport_protocol_type == NULL ||
1938 event_receiver_address_info == NULL || heartbeat_timer == NULL) {
1939 return PLDM_ERROR_INVALID_DATA;
1940 }
1941
1942 if (payload_length != PLDM_SET_EVENT_RECEIVER_REQ_BYTES) {
1943 return PLDM_ERROR_INVALID_LENGTH;
1944 }
1945
1946 struct pldm_set_event_receiver_req *request =
1947 (struct pldm_set_event_receiver_req *)msg->payload;
1948
1949 if ((*event_message_global_enable ==
1950 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) &&
1951 (*heartbeat_timer == 0)) {
1952 return PLDM_ERROR_INVALID_DATA;
1953 }
1954
1955 *event_message_global_enable = request->event_message_global_enable,
1956 *transport_protocol_type = request->transport_protocol_type,
1957 *event_receiver_address_info = request->event_receiver_address_info,
1958 *heartbeat_timer = le16toh(request->heartbeat_timer);
1959
1960 return PLDM_SUCCESS;
1961}
1962
1963int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code,
1964 struct pldm_msg *msg)
1965
1966{
1967 if (msg == NULL) {
1968 return PLDM_ERROR_INVALID_DATA;
1969 }
1970
1971 struct pldm_header_info header = {0};
1972 header.instance = instance_id;
1973 header.msg_type = PLDM_RESPONSE;
1974 header.pldm_type = PLDM_PLATFORM;
1975 header.command = PLDM_SET_EVENT_RECEIVER;
1976
1977 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1978 if (rc != PLDM_SUCCESS) {
1979 return rc;
1980 }
1981
1982 msg->payload[0] = completion_code;
1983
1984 return PLDM_SUCCESS;
1985}