blob: 7bcd5023a65f3c19662451c567981b5c510123e3 [file] [log] [blame]
Sampa Misra0db1dfa2019-03-19 00:15:31 -05001#include <endian.h>
2#include <string.h>
3
4#include "platform.h"
5
Zach Clarkb728eee2020-06-18 10:01:31 -05006int encode_state_effecter_pdr(
7 struct pldm_state_effecter_pdr *const effecter,
8 const size_t allocation_size,
9 const struct state_effecter_possible_states *const possible_states,
10 const size_t possible_states_size, size_t *const actual_size)
11{
12 // Encode possible states
13
14 size_t calculated_possible_states_size = 0;
15
16 {
17 char *states_ptr = (char *)possible_states;
18 char *const begin_states_ptr = states_ptr;
19
20 for (int i = 0; i < effecter->composite_effecter_count; ++i) {
21 struct state_effecter_possible_states *states =
22 (struct state_effecter_possible_states *)states_ptr;
23
24 HTOLE16(states->state_set_id);
25
26 states_ptr +=
27 (sizeof(*states) - sizeof(states->states) +
28 states->possible_states_size);
29 }
30
31 calculated_possible_states_size = states_ptr - begin_states_ptr;
32 }
33
34 // Check lengths
35
36 if (possible_states_size != calculated_possible_states_size) {
37 *actual_size = 0;
38 return PLDM_ERROR;
39 }
40
41 *actual_size =
42 (sizeof(struct pldm_state_effecter_pdr) + possible_states_size -
43 sizeof(effecter->possible_states));
44
45 if (allocation_size < *actual_size) {
46 *actual_size = 0;
47 return PLDM_ERROR_INVALID_LENGTH;
48 }
49
50 // Encode rest of PDR
51
52 effecter->hdr.version = 1;
53 effecter->hdr.type = PLDM_STATE_EFFECTER_PDR;
54 effecter->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
55
56 memcpy(effecter->possible_states, possible_states,
57 possible_states_size);
58
59 // Convert effecter PDR body
60 HTOLE16(effecter->terminus_handle);
61 HTOLE16(effecter->effecter_id);
62 HTOLE16(effecter->entity_type);
63 HTOLE16(effecter->entity_instance);
64 HTOLE16(effecter->container_id);
65 HTOLE16(effecter->effecter_semantic_id);
66
67 // Convert header
68 HTOLE32(effecter->hdr.record_handle);
69 HTOLE16(effecter->hdr.record_change_num);
70 HTOLE16(effecter->hdr.length);
71
72 return PLDM_SUCCESS;
73}
74
75int encode_state_sensor_pdr(
76 struct pldm_state_sensor_pdr *const sensor, const size_t allocation_size,
77 const struct state_sensor_possible_states *const possible_states,
78 const size_t possible_states_size, size_t *const actual_size)
79{
80 // Encode possible states
81
82 size_t calculated_possible_states_size = 0;
83
84 {
85 char *states_ptr = (char *)possible_states,
86 *const begin_states_ptr = states_ptr;
87
88 for (int i = 0; i < sensor->composite_sensor_count; ++i) {
89 struct state_sensor_possible_states *states =
90 (struct state_sensor_possible_states *)states_ptr;
91
92 HTOLE16(states->state_set_id);
93
94 states_ptr +=
95 (sizeof(*states) - sizeof(states->states) +
96 states->possible_states_size);
97 }
98
99 calculated_possible_states_size = states_ptr - begin_states_ptr;
100 }
101
102 // Check lengths
103
104 if (possible_states_size != calculated_possible_states_size) {
105 *actual_size = 0;
106 return PLDM_ERROR;
107 }
108
109 *actual_size = (sizeof(struct pldm_state_sensor_pdr) +
110 possible_states_size - sizeof(sensor->possible_states));
111
112 if (allocation_size < *actual_size) {
113 *actual_size = 0;
114 return PLDM_ERROR_INVALID_LENGTH;
115 }
116
117 // Encode rest of PDR
118
119 sensor->hdr.version = 1;
120 sensor->hdr.type = PLDM_STATE_SENSOR_PDR;
121 sensor->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
122
123 memcpy(sensor->possible_states, possible_states, possible_states_size);
124
125 // Convert sensor PDR body
126 HTOLE16(sensor->terminus_handle);
127 HTOLE16(sensor->sensor_id);
128 HTOLE16(sensor->entity_type);
129 HTOLE16(sensor->entity_instance);
130 HTOLE16(sensor->container_id);
131
132 // Convert header
133 HTOLE32(sensor->hdr.record_handle);
134 HTOLE16(sensor->hdr.record_change_num);
135 HTOLE16(sensor->hdr.length);
136
137 return PLDM_SUCCESS;
138}
139
Sampa Misra0db1dfa2019-03-19 00:15:31 -0500140int encode_set_state_effecter_states_resp(uint8_t instance_id,
141 uint8_t completion_code,
142 struct pldm_msg *msg)
143{
144 struct pldm_header_info header = {0};
145 int rc = PLDM_SUCCESS;
146
vkaverapa6575b82019-04-03 05:33:52 -0500147 msg->payload[0] = completion_code;
Sampa Misra0db1dfa2019-03-19 00:15:31 -0500148
149 header.msg_type = PLDM_RESPONSE;
150 header.instance = instance_id;
151 header.pldm_type = PLDM_PLATFORM;
152 header.command = PLDM_SET_STATE_EFFECTER_STATES;
153
154 rc = pack_pldm_header(&header, &(msg->hdr));
155
156 return rc;
157}
158
vkaverap98a2c192019-04-03 05:33:52 -0500159int encode_set_state_effecter_states_req(uint8_t instance_id,
160 uint16_t effecter_id,
161 uint8_t comp_effecter_count,
162 set_effecter_state_field *field,
163 struct pldm_msg *msg)
164{
165 struct pldm_header_info header = {0};
166 int rc = PLDM_SUCCESS;
167
168 header.msg_type = PLDM_REQUEST;
169 header.instance = instance_id;
170 header.pldm_type = PLDM_PLATFORM;
171 header.command = PLDM_SET_STATE_EFFECTER_STATES;
172
173 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
174 return rc;
175 }
176
Tom Joseph250c4752020-04-15 10:32:45 +0530177 if (comp_effecter_count < 0x1 || comp_effecter_count > 0x8 ||
178 field == NULL) {
vkaverap98a2c192019-04-03 05:33:52 -0500179 return PLDM_ERROR_INVALID_DATA;
180 }
181
Priyanga7257fdf2019-06-10 01:59:45 -0500182 struct pldm_set_state_effecter_states_req *request =
183 (struct pldm_set_state_effecter_states_req *)msg->payload;
vkaverap98a2c192019-04-03 05:33:52 -0500184 effecter_id = htole16(effecter_id);
Priyanga7257fdf2019-06-10 01:59:45 -0500185 request->effecter_id = effecter_id;
186 request->comp_effecter_count = comp_effecter_count;
187 memcpy(request->field, field,
vkaverap98a2c192019-04-03 05:33:52 -0500188 (sizeof(set_effecter_state_field) * comp_effecter_count));
189
190 return PLDM_SUCCESS;
191}
192
Zahed Hossain223a73d2019-07-04 12:46:18 -0500193int decode_set_state_effecter_states_resp(const struct pldm_msg *msg,
vkaverapa6575b82019-04-03 05:33:52 -0500194 size_t payload_length,
vkaverap98a2c192019-04-03 05:33:52 -0500195 uint8_t *completion_code)
196{
197 if (msg == NULL || completion_code == NULL) {
198 return PLDM_ERROR_INVALID_DATA;
199 }
200
George Liu684a7162019-12-06 15:10:52 +0800201 *completion_code = msg->payload[0];
202 if (PLDM_SUCCESS != *completion_code) {
203 return PLDM_SUCCESS;
204 }
205
vkaverapa6575b82019-04-03 05:33:52 -0500206 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES) {
207 return PLDM_ERROR_INVALID_LENGTH;
208 }
209
vkaverap98a2c192019-04-03 05:33:52 -0500210 return PLDM_SUCCESS;
211}
212
Zahed Hossain223a73d2019-07-04 12:46:18 -0500213int decode_set_state_effecter_states_req(const struct pldm_msg *msg,
vkaverapa6575b82019-04-03 05:33:52 -0500214 size_t payload_length,
Sampa Misra0db1dfa2019-03-19 00:15:31 -0500215 uint16_t *effecter_id,
216 uint8_t *comp_effecter_count,
217 set_effecter_state_field *field)
218{
219 if (msg == NULL || effecter_id == NULL || comp_effecter_count == NULL ||
220 field == NULL) {
221 return PLDM_ERROR_INVALID_DATA;
222 }
vkaverapa6575b82019-04-03 05:33:52 -0500223
224 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) {
225 return PLDM_ERROR_INVALID_LENGTH;
226 }
227
Priyanga7257fdf2019-06-10 01:59:45 -0500228 struct pldm_set_state_effecter_states_req *request =
Zahed Hossain223a73d2019-07-04 12:46:18 -0500229 (struct pldm_set_state_effecter_states_req *)msg->payload;
Priyanga7257fdf2019-06-10 01:59:45 -0500230
231 *effecter_id = le16toh(request->effecter_id);
232 *comp_effecter_count = request->comp_effecter_count;
233 memcpy(field, request->field,
Sampa Misra0db1dfa2019-03-19 00:15:31 -0500234 (sizeof(set_effecter_state_field) * (*comp_effecter_count)));
235
236 return PLDM_SUCCESS;
237}
Sampa Misra7fcfb662019-05-08 13:13:53 -0500238
239int decode_get_pdr_req(const struct pldm_msg *msg, size_t payload_length,
240 uint32_t *record_hndl, uint32_t *data_transfer_hndl,
241 uint8_t *transfer_op_flag, uint16_t *request_cnt,
242 uint16_t *record_chg_num)
243{
244 if (msg == NULL || record_hndl == NULL || data_transfer_hndl == NULL ||
245 transfer_op_flag == NULL || request_cnt == NULL ||
246 record_chg_num == NULL) {
247 return PLDM_ERROR_INVALID_DATA;
248 }
249 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
250 return PLDM_ERROR_INVALID_LENGTH;
251 }
252
253 struct pldm_get_pdr_req *request =
254 (struct pldm_get_pdr_req *)msg->payload;
255 *record_hndl = le32toh(request->record_handle);
256 *data_transfer_hndl = le32toh(request->data_transfer_handle);
257 *transfer_op_flag = request->transfer_op_flag;
258 *request_cnt = le16toh(request->request_count);
259 *record_chg_num = le16toh(request->record_change_number);
260
261 return PLDM_SUCCESS;
262}
263
264int encode_get_pdr_resp(uint8_t instance_id, uint8_t completion_code,
265 uint32_t next_record_hndl,
266 uint32_t next_data_transfer_hndl, uint8_t transfer_flag,
267 uint16_t resp_cnt, const uint8_t *record_data,
268 uint8_t transfer_crc, struct pldm_msg *msg)
269{
270 struct pldm_header_info header = {0};
271 int rc = PLDM_SUCCESS;
272
273 if (msg == NULL) {
274 return PLDM_ERROR_INVALID_DATA;
275 }
276 struct pldm_get_pdr_resp *response =
277 (struct pldm_get_pdr_resp *)msg->payload;
278
279 response->completion_code = completion_code;
280
281 header.msg_type = PLDM_RESPONSE;
282 header.instance = instance_id;
283 header.pldm_type = PLDM_PLATFORM;
284 header.command = PLDM_GET_PDR;
285 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
286 return rc;
287 }
288
289 if (response->completion_code == PLDM_SUCCESS) {
290 response->next_record_handle = htole32(next_record_hndl);
291 response->next_data_transfer_handle =
292 htole32(next_data_transfer_hndl);
293 response->transfer_flag = transfer_flag;
294 response->response_count = htole16(resp_cnt);
295 if (record_data != NULL && resp_cnt > 0) {
296 memcpy(response->record_data, record_data, resp_cnt);
297 }
Deepak Kodihallie4b16ee2019-08-14 06:54:38 -0500298 if (transfer_flag == PLDM_END) {
299 uint8_t *dst = msg->payload;
300 dst +=
301 (sizeof(struct pldm_get_pdr_resp) - 1) + resp_cnt;
302 *dst = transfer_crc;
303 }
Sampa Misra7fcfb662019-05-08 13:13:53 -0500304 }
305
306 return PLDM_SUCCESS;
307}
George Liu820a9a52019-11-26 14:43:59 +0800308
309int encode_get_pdr_req(uint8_t instance_id, uint32_t record_hndl,
310 uint32_t data_transfer_hndl, uint8_t transfer_op_flag,
311 uint16_t request_cnt, uint16_t record_chg_num,
312 struct pldm_msg *msg, size_t payload_length)
313{
314 struct pldm_header_info header = {0};
315 int rc = PLDM_SUCCESS;
316
317 if (msg == NULL) {
318 return PLDM_ERROR_INVALID_DATA;
319 }
320 struct pldm_get_pdr_req *request =
321 (struct pldm_get_pdr_req *)msg->payload;
322
323 header.msg_type = PLDM_REQUEST;
324 header.instance = instance_id;
325 header.pldm_type = PLDM_PLATFORM;
326 header.command = PLDM_GET_PDR;
327
328 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
329 return rc;
330 }
331
332 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
333 return PLDM_ERROR_INVALID_LENGTH;
334 }
335
336 request->record_handle = htole32(record_hndl);
337 request->data_transfer_handle = htole32(data_transfer_hndl);
338 request->transfer_op_flag = transfer_op_flag;
339 request->request_count = htole16(request_cnt);
340 request->record_change_number = htole16(record_chg_num);
341
342 return PLDM_SUCCESS;
343}
344
345int decode_get_pdr_resp(const struct pldm_msg *msg, size_t payload_length,
346 uint8_t *completion_code, uint32_t *next_record_hndl,
347 uint32_t *next_data_transfer_hndl,
348 uint8_t *transfer_flag, uint16_t *resp_cnt,
349 uint8_t *record_data, size_t record_data_length,
350 uint8_t *transfer_crc)
351{
352 if (msg == NULL || completion_code == NULL ||
353 next_record_hndl == NULL || next_data_transfer_hndl == NULL ||
Zach Clark3dba2bf2020-03-31 10:58:03 -0500354 transfer_flag == NULL || resp_cnt == NULL || transfer_crc == NULL) {
George Liu820a9a52019-11-26 14:43:59 +0800355 return PLDM_ERROR_INVALID_DATA;
356 }
357
358 *completion_code = msg->payload[0];
359 if (PLDM_SUCCESS != *completion_code) {
George Liu684a7162019-12-06 15:10:52 +0800360 return PLDM_SUCCESS;
George Liu820a9a52019-11-26 14:43:59 +0800361 }
362
363 if (payload_length < PLDM_GET_PDR_MIN_RESP_BYTES) {
364 return PLDM_ERROR_INVALID_LENGTH;
365 }
366
367 struct pldm_get_pdr_resp *response =
368 (struct pldm_get_pdr_resp *)msg->payload;
369
370 *next_record_hndl = le32toh(response->next_record_handle);
371 *next_data_transfer_hndl = le32toh(response->next_data_transfer_handle);
372 *transfer_flag = response->transfer_flag;
373 *resp_cnt = le16toh(response->response_count);
374
375 if (*transfer_flag != PLDM_END &&
376 (int)payload_length != PLDM_GET_PDR_MIN_RESP_BYTES + *resp_cnt) {
377 return PLDM_ERROR_INVALID_LENGTH;
378 }
379
380 if (*transfer_flag == PLDM_END &&
381 (int)payload_length !=
382 PLDM_GET_PDR_MIN_RESP_BYTES + *resp_cnt + 1) {
383 return PLDM_ERROR_INVALID_LENGTH;
384 }
385
Zach Clark3dba2bf2020-03-31 10:58:03 -0500386 if (*resp_cnt > 0 && record_data != NULL) {
George Liu820a9a52019-11-26 14:43:59 +0800387 if (record_data_length < *resp_cnt) {
388 return PLDM_ERROR_INVALID_LENGTH;
389 }
390 memcpy(record_data, response->record_data, *resp_cnt);
391 }
392
393 if (*transfer_flag == PLDM_END) {
394 *transfer_crc =
395 msg->payload[PLDM_GET_PDR_MIN_RESP_BYTES + *resp_cnt];
396 }
397
398 return PLDM_SUCCESS;
399}
George Liu30b859f2020-01-07 15:03:22 +0800400
401int decode_set_numeric_effecter_value_req(const struct pldm_msg *msg,
402 size_t payload_length,
403 uint16_t *effecter_id,
404 uint8_t *effecter_data_size,
405 uint8_t *effecter_value)
406{
407 if (msg == NULL || effecter_id == NULL || effecter_data_size == NULL ||
408 effecter_value == NULL) {
409 return PLDM_ERROR_INVALID_DATA;
410 }
411
412 if (payload_length < PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) {
413 return PLDM_ERROR_INVALID_LENGTH;
414 }
415
416 struct pldm_set_numeric_effecter_value_req *request =
417 (struct pldm_set_numeric_effecter_value_req *)msg->payload;
418 *effecter_id = le16toh(request->effecter_id);
419 *effecter_data_size = request->effecter_data_size;
420
421 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
422 return PLDM_ERROR_INVALID_DATA;
423 }
424
425 if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
426 *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
427
428 if (payload_length !=
429 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) {
430 return PLDM_ERROR_INVALID_LENGTH;
431 }
432
433 *effecter_value = request->effecter_value[0];
434 }
435
436 if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
437 *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
438
439 if (payload_length !=
440 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1) {
441 return PLDM_ERROR_INVALID_LENGTH;
442 }
443
444 memcpy(effecter_value, request->effecter_value, 2);
George Liuda75abe2020-04-09 13:36:13 +0800445 uint16_t *val = (uint16_t *)(effecter_value);
446 *val = le16toh(*val);
George Liu30b859f2020-01-07 15:03:22 +0800447 }
448
449 if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
450 *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
451
452 if (payload_length !=
453 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3) {
454 return PLDM_ERROR_INVALID_LENGTH;
455 }
456
457 memcpy(effecter_value, request->effecter_value, 4);
George Liuda75abe2020-04-09 13:36:13 +0800458 uint32_t *val = (uint32_t *)(effecter_value);
459 *val = le32toh(*val);
George Liu30b859f2020-01-07 15:03:22 +0800460 }
461
462 return PLDM_SUCCESS;
463}
464
465int encode_set_numeric_effecter_value_resp(uint8_t instance_id,
466 uint8_t completion_code,
467 struct pldm_msg *msg,
468 size_t payload_length)
469{
470 struct pldm_header_info header = {0};
471 int rc = PLDM_SUCCESS;
472
473 if (msg == NULL) {
474 return PLDM_ERROR_INVALID_DATA;
475 }
476
477 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
478 return PLDM_ERROR_INVALID_LENGTH;
479 }
480
481 msg->payload[0] = completion_code;
482
483 header.msg_type = PLDM_RESPONSE;
484 header.instance = instance_id;
485 header.pldm_type = PLDM_PLATFORM;
486 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
487
488 rc = pack_pldm_header(&header, &(msg->hdr));
489
490 return rc;
491}
492
493int encode_set_numeric_effecter_value_req(
494 uint8_t instance_id, uint16_t effecter_id, uint8_t effecter_data_size,
495 uint8_t *effecter_value, struct pldm_msg *msg, size_t payload_length)
496{
497 struct pldm_header_info header = {0};
498 int rc = PLDM_SUCCESS;
499
500 if (msg == NULL || effecter_value == NULL) {
501 return PLDM_ERROR_INVALID_DATA;
502 }
503 struct pldm_set_numeric_effecter_value_req *request =
504 (struct pldm_set_numeric_effecter_value_req *)msg->payload;
505
506 header.msg_type = PLDM_REQUEST;
507 header.instance = instance_id;
508 header.pldm_type = PLDM_PLATFORM;
509 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
510
511 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
512 return rc;
513 }
514
515 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
516 return PLDM_ERROR_INVALID_DATA;
517 }
518
519 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
520 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
521 if (payload_length !=
522 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) {
523 return PLDM_ERROR_INVALID_LENGTH;
524 }
525 request->effecter_value[0] = *effecter_value;
526 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
527 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
528 if (payload_length !=
529 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1) {
530 return PLDM_ERROR_INVALID_LENGTH;
531 }
532
George Liuab749502020-04-15 13:16:35 +0800533 uint16_t val = *(uint16_t *)(effecter_value);
534 val = htole16(val);
535 memcpy(request->effecter_value, &val, sizeof(uint16_t));
536
George Liu30b859f2020-01-07 15:03:22 +0800537 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
538 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
539 if (payload_length !=
540 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3) {
541 return PLDM_ERROR_INVALID_LENGTH;
542 }
543
George Liuab749502020-04-15 13:16:35 +0800544 uint32_t val = *(uint32_t *)(effecter_value);
545 val = htole32(val);
546 memcpy(request->effecter_value, &val, sizeof(uint32_t));
George Liu30b859f2020-01-07 15:03:22 +0800547 }
548
549 request->effecter_id = htole16(effecter_id);
550 request->effecter_data_size = effecter_data_size;
551
552 return PLDM_SUCCESS;
553}
554
555int decode_set_numeric_effecter_value_resp(const struct pldm_msg *msg,
556 size_t payload_length,
557 uint8_t *completion_code)
558{
559 if (msg == NULL || completion_code == NULL) {
560 return PLDM_ERROR_INVALID_DATA;
561 }
562
563 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
564 return PLDM_ERROR_INVALID_LENGTH;
565 }
566
567 *completion_code = msg->payload[0];
568
569 return PLDM_SUCCESS;
570}
Jolie Ku3557bad2020-03-02 16:22:57 +0800571
572int encode_get_state_sensor_readings_resp(uint8_t instance_id,
573 uint8_t completion_code,
574 uint8_t comp_sensor_count,
575 get_sensor_state_field *field,
576 struct pldm_msg *msg)
577{
578 struct pldm_header_info header = {0};
579 int rc = PLDM_SUCCESS;
580
581 header.msg_type = PLDM_RESPONSE;
582 header.instance = instance_id;
583 header.pldm_type = PLDM_PLATFORM;
584 header.command = PLDM_GET_STATE_SENSOR_READINGS;
585
586 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
587 return rc;
588 }
589
590 if (comp_sensor_count < 0x1 || comp_sensor_count > 0x8) {
591 return PLDM_ERROR_INVALID_DATA;
592 }
593
594 struct pldm_get_state_sensor_readings_resp *response =
595 (struct pldm_get_state_sensor_readings_resp *)msg->payload;
596
597 response->completion_code = completion_code;
598 response->comp_sensor_count = comp_sensor_count;
599 memcpy(response->field, field,
600 (sizeof(get_sensor_state_field) * comp_sensor_count));
601
602 return rc;
603}
604
605int encode_get_state_sensor_readings_req(uint8_t instance_id,
606 uint16_t sensor_id,
607 bitfield8_t sensor_rearm,
608 uint8_t reserved, struct pldm_msg *msg)
609{
610 struct pldm_header_info header = {0};
611 int rc = PLDM_SUCCESS;
612
613 header.msg_type = PLDM_REQUEST;
614 header.instance = instance_id;
615 header.pldm_type = PLDM_PLATFORM;
616 header.command = PLDM_GET_STATE_SENSOR_READINGS;
617
618 if (msg == NULL) {
619 return PLDM_ERROR_INVALID_DATA;
620 }
621
622 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
623 return rc;
624 }
625
626 struct pldm_get_state_sensor_readings_req *request =
627 (struct pldm_get_state_sensor_readings_req *)msg->payload;
628
629 request->sensor_id = htole16(sensor_id);
630 request->reserved = reserved;
631 request->sensor_rearm = sensor_rearm;
632
633 return PLDM_SUCCESS;
634}
635
636int decode_get_state_sensor_readings_resp(const struct pldm_msg *msg,
637 size_t payload_length,
638 uint8_t *completion_code,
639 uint8_t *comp_sensor_count,
640 get_sensor_state_field *field)
641{
642 if (msg == NULL || completion_code == NULL ||
643 comp_sensor_count == NULL || field == NULL) {
644 return PLDM_ERROR_INVALID_DATA;
645 }
646
647 *completion_code = msg->payload[0];
648 if (PLDM_SUCCESS != *completion_code) {
649 return PLDM_SUCCESS;
650 }
651
Jolie Ku3557bad2020-03-02 16:22:57 +0800652 struct pldm_get_state_sensor_readings_resp *response =
653 (struct pldm_get_state_sensor_readings_resp *)msg->payload;
654
655 if (response->comp_sensor_count < 0x1 ||
656 response->comp_sensor_count > 0x8) {
657 return PLDM_ERROR_INVALID_DATA;
658 }
George Liu38eaa272021-01-21 19:30:15 +0800659
660 if (payload_length >
661 PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES +
662 sizeof(get_sensor_state_field) * response->comp_sensor_count) {
Jolie Ku3557bad2020-03-02 16:22:57 +0800663 return PLDM_ERROR_INVALID_LENGTH;
664 }
George Liu38eaa272021-01-21 19:30:15 +0800665
Jolie Ku3557bad2020-03-02 16:22:57 +0800666 *comp_sensor_count = response->comp_sensor_count;
667
668 memcpy(field, response->field,
669 (sizeof(get_sensor_state_field) * (*comp_sensor_count)));
670
671 return PLDM_SUCCESS;
672}
673
674int decode_get_state_sensor_readings_req(const struct pldm_msg *msg,
675 size_t payload_length,
676 uint16_t *sensor_id,
677 bitfield8_t *sensor_rearm,
678 uint8_t *reserved)
679{
680 if (msg == NULL || sensor_id == NULL || sensor_rearm == NULL) {
681 return PLDM_ERROR_INVALID_DATA;
682 }
683
684 if (payload_length != PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES) {
685 return PLDM_ERROR_INVALID_LENGTH;
686 }
687
688 struct pldm_get_state_sensor_readings_req *request =
689 (struct pldm_get_state_sensor_readings_req *)msg->payload;
690
691 *sensor_id = le16toh(request->sensor_id);
692 *reserved = request->reserved;
693 memcpy(&(sensor_rearm->byte), &(request->sensor_rearm.byte),
694 sizeof(request->sensor_rearm.byte));
695
696 return PLDM_SUCCESS;
697}
Zahed Hossaind4abab12020-02-06 03:36:43 -0600698
Zach Clarkb728eee2020-06-18 10:01:31 -0500699int encode_sensor_event_data(
700 struct pldm_sensor_event_data *const event_data,
701 const size_t event_data_size, const uint16_t sensor_id,
702 const enum sensor_event_class_states sensor_event_class,
703 const uint8_t sensor_offset, const uint8_t event_state,
704 const uint8_t previous_event_state, size_t *const actual_event_data_size)
705{
706 *actual_event_data_size =
707 (sizeof(*event_data) - sizeof(event_data->event_class) +
708 sizeof(struct pldm_sensor_event_state_sensor_state));
709
710 if (!event_data) {
711 return PLDM_SUCCESS;
712 }
713
714 if (event_data_size < *actual_event_data_size) {
715 *actual_event_data_size = 0;
716 return PLDM_ERROR_INVALID_LENGTH;
717 }
718
Christian Geddes1aad2f92021-02-08 10:03:43 -0600719 event_data->sensor_id = htole16(sensor_id);
Zach Clarkb728eee2020-06-18 10:01:31 -0500720 event_data->sensor_event_class_type = sensor_event_class;
721
722 struct pldm_sensor_event_state_sensor_state *const state_data =
723 (struct pldm_sensor_event_state_sensor_state *)
724 event_data->event_class;
725
726 state_data->sensor_offset = sensor_offset;
727 state_data->event_state = event_state;
728 state_data->previous_event_state = previous_event_state;
729
730 return PLDM_SUCCESS;
731}
732
Zahed Hossaind4abab12020-02-06 03:36:43 -0600733int decode_platform_event_message_req(const struct pldm_msg *msg,
734 size_t payload_length,
735 uint8_t *format_version, uint8_t *tid,
736 uint8_t *event_class,
737 size_t *event_data_offset)
738{
739
740 if (msg == NULL || format_version == NULL || tid == NULL ||
741 event_class == NULL || event_data_offset == NULL) {
742 return PLDM_ERROR_INVALID_DATA;
743 }
744
745 if (payload_length <= PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) {
746 return PLDM_ERROR_INVALID_LENGTH;
747 }
748 struct pldm_platform_event_message_req *response =
749 (struct pldm_platform_event_message_req *)msg->payload;
750
751 *format_version = response->format_version;
752 *tid = response->tid;
753 *event_class = response->event_class;
754 *event_data_offset =
755 sizeof(*format_version) + sizeof(*tid) + sizeof(*event_class);
756
757 return PLDM_SUCCESS;
758}
759
760int encode_platform_event_message_resp(uint8_t instance_id,
Pavithra Barithaya2ea1f072020-04-03 09:30:23 -0500761 uint8_t completion_code,
762 uint8_t platform_event_status,
Zahed Hossaind4abab12020-02-06 03:36:43 -0600763 struct pldm_msg *msg)
764{
765 int rc = PLDM_SUCCESS;
766
767 if (msg == NULL) {
768 return PLDM_ERROR_INVALID_DATA;
769 }
770
Pavithra Barithaya2ea1f072020-04-03 09:30:23 -0500771 if (platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
772 return PLDM_ERROR_INVALID_DATA;
773 }
774
Zahed Hossaind4abab12020-02-06 03:36:43 -0600775 struct pldm_platform_event_message_resp *response =
776 (struct pldm_platform_event_message_resp *)msg->payload;
777 response->completion_code = completion_code;
Pavithra Barithaya2ea1f072020-04-03 09:30:23 -0500778 response->platform_event_status = platform_event_status;
Zahed Hossaind4abab12020-02-06 03:36:43 -0600779
780 struct pldm_header_info header = {0};
781 header.msg_type = PLDM_RESPONSE;
782 header.instance = instance_id;
783 header.pldm_type = PLDM_PLATFORM;
784 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
785
786 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
787 return rc;
788 }
789 return PLDM_SUCCESS;
790}
Zahed Hossain1c861712020-03-04 08:55:19 -0600791
Christian Geddes3bdb3c22020-05-01 14:55:39 -0500792int encode_platform_event_message_req(
793 uint8_t instance_id, uint8_t format_version, uint8_t tid,
794 uint8_t event_class, const uint8_t *event_data, size_t event_data_length,
795 struct pldm_msg *msg, size_t payload_length)
Pavithra Barithaya35f2b2c2020-04-08 01:35:56 -0500796
797{
798 struct pldm_header_info header = {0};
799 int rc = PLDM_SUCCESS;
800
801 header.msg_type = PLDM_REQUEST;
802 header.instance = instance_id;
803 header.pldm_type = PLDM_PLATFORM;
804 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
805
806 if (format_version != 1) {
807 return PLDM_ERROR_INVALID_DATA;
808 }
809
810 if (msg == NULL || event_data == NULL) {
811 return PLDM_ERROR_INVALID_DATA;
812 }
813
814 if (event_data_length == 0) {
815 return PLDM_ERROR_INVALID_DATA;
816 }
817
Christian Geddes3bdb3c22020-05-01 14:55:39 -0500818 if (payload_length !=
819 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) {
820 return PLDM_ERROR_INVALID_LENGTH;
821 }
822
Pavithra Barithaya35f2b2c2020-04-08 01:35:56 -0500823 if (event_class > PLDM_HEARTBEAT_TIMER_ELAPSED_EVENT &&
824 !(event_class >= 0xF0 && event_class <= 0xFE)) {
825 return PLDM_ERROR_INVALID_DATA;
826 }
827
828 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
829 return rc;
830 }
831
832 struct pldm_platform_event_message_req *request =
833 (struct pldm_platform_event_message_req *)msg->payload;
834 request->format_version = format_version;
835 request->tid = tid;
836 request->event_class = event_class;
837 memcpy(request->event_data, event_data, event_data_length);
838
839 return PLDM_SUCCESS;
840}
841
842int decode_platform_event_message_resp(const struct pldm_msg *msg,
843 size_t payload_length,
844 uint8_t *completion_code,
845 uint8_t *platform_event_status)
846{
847 if (msg == NULL || completion_code == NULL ||
848 platform_event_status == NULL) {
849 return PLDM_ERROR_INVALID_DATA;
850 }
851
852 *completion_code = msg->payload[0];
853 if (PLDM_SUCCESS != *completion_code) {
854 return PLDM_SUCCESS;
855 }
856 if (payload_length != PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES) {
857 return PLDM_ERROR_INVALID_LENGTH;
858 }
859
860 struct pldm_platform_event_message_resp *response =
861 (struct pldm_platform_event_message_resp *)msg->payload;
862 *platform_event_status = response->platform_event_status;
863
864 if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
865 return PLDM_ERROR_INVALID_DATA;
866 }
867
868 return PLDM_SUCCESS;
869}
870
Zahed Hossain1c861712020-03-04 08:55:19 -0600871int decode_sensor_event_data(const uint8_t *event_data,
872 size_t event_data_length, uint16_t *sensor_id,
873 uint8_t *sensor_event_class_type,
874 size_t *event_class_data_offset)
875{
876 if (event_data == NULL) {
877 return PLDM_ERROR_INVALID_DATA;
878 }
879 if (event_data_length < PLDM_SENSOR_EVENT_DATA_MIN_LENGTH) {
880 return PLDM_ERROR_INVALID_LENGTH;
881 }
882
883 size_t event_class_data_length =
884 event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES;
885
886 struct pldm_sensor_event_data *sensor_event_data =
887 (struct pldm_sensor_event_data *)event_data;
888 *sensor_id = sensor_event_data->sensor_id;
889 *sensor_event_class_type = sensor_event_data->sensor_event_class_type;
890 if (sensor_event_data->sensor_event_class_type ==
891 PLDM_SENSOR_OP_STATE) {
892 if (event_class_data_length !=
893 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
894 return PLDM_ERROR_INVALID_LENGTH;
895 }
896 } else if (sensor_event_data->sensor_event_class_type ==
897 PLDM_STATE_SENSOR_STATE) {
898 if (event_class_data_length !=
899 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
900 return PLDM_ERROR_INVALID_LENGTH;
901 }
902 } else if (sensor_event_data->sensor_event_class_type ==
903 PLDM_NUMERIC_SENSOR_STATE) {
904 if (event_class_data_length <
905 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
906 event_class_data_length >
907 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
908 return PLDM_ERROR_INVALID_LENGTH;
909 }
910 } else {
911 return PLDM_ERROR_INVALID_DATA;
912 }
913 *event_class_data_offset =
914 sizeof(*sensor_id) + sizeof(*sensor_event_class_type);
915 return PLDM_SUCCESS;
916}
917
918int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length,
919 uint8_t *present_op_state, uint8_t *previous_op_state)
920{
921 if (sensor_data == NULL || present_op_state == NULL ||
922 previous_op_state == NULL) {
923 return PLDM_ERROR_INVALID_DATA;
924 }
925 if (sensor_data_length !=
926 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
927 return PLDM_ERROR_INVALID_LENGTH;
928 }
929
930 struct pldm_sensor_event_sensor_op_state *sensor_op_data =
931 (struct pldm_sensor_event_sensor_op_state *)sensor_data;
932 *present_op_state = sensor_op_data->present_op_state;
933 *previous_op_state = sensor_op_data->previous_op_state;
934 return PLDM_SUCCESS;
935}
936
937int decode_state_sensor_data(const uint8_t *sensor_data,
938 size_t sensor_data_length, uint8_t *sensor_offset,
939 uint8_t *event_state,
940 uint8_t *previous_event_state)
941{
942 if (sensor_data == NULL || sensor_offset == NULL ||
943 event_state == NULL || previous_event_state == NULL) {
944 return PLDM_ERROR_INVALID_DATA;
945 }
946 if (sensor_data_length !=
947 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
948 return PLDM_ERROR_INVALID_LENGTH;
949 }
950
951 struct pldm_sensor_event_state_sensor_state *sensor_state_data =
952 (struct pldm_sensor_event_state_sensor_state *)sensor_data;
953 *sensor_offset = sensor_state_data->sensor_offset;
954 *event_state = sensor_state_data->event_state;
955 *previous_event_state = sensor_state_data->previous_event_state;
956 return PLDM_SUCCESS;
957}
958
959int decode_numeric_sensor_data(const uint8_t *sensor_data,
960 size_t sensor_data_length, uint8_t *event_state,
961 uint8_t *previous_event_state,
962 uint8_t *sensor_data_size,
963 uint32_t *present_reading)
964{
965 if (sensor_data == NULL || sensor_data_size == NULL ||
966 event_state == NULL || previous_event_state == NULL ||
967 present_reading == NULL) {
968 return PLDM_ERROR_INVALID_DATA;
969 }
970 if (sensor_data_length <
971 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
972 sensor_data_length >
973 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
974 return PLDM_ERROR_INVALID_LENGTH;
975 }
976 struct pldm_sensor_event_numeric_sensor_state *numeric_sensor_data =
977 (struct pldm_sensor_event_numeric_sensor_state *)sensor_data;
978 *event_state = numeric_sensor_data->event_state;
979 *previous_event_state = numeric_sensor_data->previous_event_state;
980 *sensor_data_size = numeric_sensor_data->sensor_data_size;
981 uint8_t *present_reading_ptr = numeric_sensor_data->present_reading;
982
983 switch (*sensor_data_size) {
984 case PLDM_SENSOR_DATA_SIZE_UINT8:
985 case PLDM_SENSOR_DATA_SIZE_SINT8:
986 if (sensor_data_length !=
987 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_8BIT_DATA_LENGTH) {
988 return PLDM_ERROR_INVALID_LENGTH;
989 }
990 *present_reading = present_reading_ptr[0];
991 break;
992 case PLDM_SENSOR_DATA_SIZE_UINT16:
993 case PLDM_SENSOR_DATA_SIZE_SINT16:
994 if (sensor_data_length !=
995 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_16BIT_DATA_LENGTH) {
996 return PLDM_ERROR_INVALID_LENGTH;
997 }
998 *present_reading = le16toh(present_reading_ptr[1] |
999 (present_reading_ptr[0] << 8));
1000 break;
1001 case PLDM_SENSOR_DATA_SIZE_UINT32:
1002 case PLDM_SENSOR_DATA_SIZE_SINT32:
1003 if (sensor_data_length !=
1004 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_32BIT_DATA_LENGTH) {
1005 return PLDM_ERROR_INVALID_LENGTH;
1006 }
1007 *present_reading = le32toh(present_reading_ptr[3] |
1008 (present_reading_ptr[2] << 8) |
1009 (present_reading_ptr[1] << 16) |
1010 (present_reading_ptr[0] << 24));
1011 break;
1012 default:
1013 return PLDM_ERROR_INVALID_DATA;
1014 }
1015 return PLDM_SUCCESS;
1016}
Jolie Ku6787f172020-03-19 11:15:53 +08001017
1018int encode_get_numeric_effecter_value_req(uint8_t instance_id,
1019 uint16_t effecter_id,
1020 struct pldm_msg *msg)
1021{
1022 struct pldm_header_info header = {0};
1023 int rc = PLDM_SUCCESS;
1024
1025 if (msg == NULL) {
1026 return PLDM_ERROR_INVALID_DATA;
1027 }
1028
1029 struct pldm_get_numeric_effecter_value_req *request =
1030 (struct pldm_get_numeric_effecter_value_req *)msg->payload;
1031
1032 header.msg_type = PLDM_REQUEST;
1033 header.instance = instance_id;
1034 header.pldm_type = PLDM_PLATFORM;
1035 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1036
1037 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
1038 return rc;
1039 }
1040
1041 request->effecter_id = htole16(effecter_id);
1042
1043 return PLDM_SUCCESS;
1044}
1045
1046int encode_get_numeric_effecter_value_resp(
1047 uint8_t instance_id, uint8_t completion_code, uint8_t effecter_data_size,
1048 uint8_t effecter_oper_state, uint8_t *pending_value, uint8_t *present_value,
1049 struct pldm_msg *msg, size_t payload_length)
1050{
1051 struct pldm_header_info header = {0};
1052 int rc = PLDM_SUCCESS;
1053
1054 if (msg == NULL || pending_value == NULL || present_value == NULL) {
1055 return PLDM_ERROR_INVALID_DATA;
1056 }
1057
1058 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1059 return PLDM_ERROR_INVALID_DATA;
1060 }
1061
1062 if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1063 return PLDM_ERROR_INVALID_DATA;
1064 }
1065
1066 header.msg_type = PLDM_RESPONSE;
1067 header.instance = instance_id;
1068 header.pldm_type = PLDM_PLATFORM;
1069 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1070
1071 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
1072 return rc;
1073 }
1074
1075 struct pldm_get_numeric_effecter_value_resp *response =
1076 (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
1077
1078 response->completion_code = completion_code;
1079 response->effecter_data_size = effecter_data_size;
1080 response->effecter_oper_state = effecter_oper_state;
1081
1082 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1083 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1084 if (payload_length !=
1085 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1086 return PLDM_ERROR_INVALID_LENGTH;
1087 }
1088 response->pending_and_present_values[0] = *pending_value;
1089 response->pending_and_present_values[1] = *present_value;
1090
1091 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1092 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1093 if (payload_length !=
1094 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
1095 return PLDM_ERROR_INVALID_LENGTH;
1096 }
Jolie Ku3cdbcfb2020-04-17 10:30:59 +08001097 uint16_t val_pending = *(uint16_t *)pending_value;
1098 val_pending = htole16(val_pending);
1099 memcpy(response->pending_and_present_values, &val_pending,
1100 sizeof(uint16_t));
1101 uint16_t val_present = *(uint16_t *)present_value;
1102 val_present = htole16(val_present);
1103 memcpy(
1104 (response->pending_and_present_values + sizeof(uint16_t)),
1105 &val_present, sizeof(uint16_t));
Jolie Ku6787f172020-03-19 11:15:53 +08001106
1107 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1108 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1109 if (payload_length !=
1110 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
1111 return PLDM_ERROR_INVALID_LENGTH;
1112 }
Jolie Ku3cdbcfb2020-04-17 10:30:59 +08001113 uint32_t val_pending = *(uint32_t *)pending_value;
1114 val_pending = htole32(val_pending);
1115 memcpy(response->pending_and_present_values, &val_pending,
1116 sizeof(uint32_t));
1117 uint32_t val_present = *(uint32_t *)present_value;
1118 val_present = htole32(val_present);
1119 memcpy(
1120 (response->pending_and_present_values + sizeof(uint32_t)),
1121 &val_present, sizeof(uint32_t));
Jolie Ku6787f172020-03-19 11:15:53 +08001122 }
1123 return PLDM_SUCCESS;
1124}
1125
1126int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg,
1127 size_t payload_length,
1128 uint16_t *effecter_id)
1129{
1130 if (msg == NULL || effecter_id == NULL) {
1131 return PLDM_ERROR_INVALID_DATA;
1132 }
1133
1134 if (payload_length != PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES) {
1135 return PLDM_ERROR_INVALID_LENGTH;
1136 }
1137
1138 struct pldm_get_numeric_effecter_value_req *request =
1139 (struct pldm_get_numeric_effecter_value_req *)msg->payload;
1140
1141 *effecter_id = le16toh(request->effecter_id);
1142
1143 return PLDM_SUCCESS;
1144}
1145
1146int decode_get_numeric_effecter_value_resp(
1147 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
1148 uint8_t *effecter_data_size, uint8_t *effecter_oper_state,
1149 uint8_t *pending_value, uint8_t *present_value)
1150{
1151 if (msg == NULL || effecter_data_size == NULL ||
1152 effecter_oper_state == NULL || pending_value == NULL ||
1153 present_value == NULL) {
1154 return PLDM_ERROR_INVALID_DATA;
1155 }
1156
1157 *completion_code = msg->payload[0];
1158 if (PLDM_SUCCESS != *completion_code) {
1159 return PLDM_SUCCESS;
1160 }
1161
1162 if (payload_length < PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1163 return PLDM_ERROR_INVALID_LENGTH;
1164 }
1165
1166 struct pldm_get_numeric_effecter_value_resp *response =
1167 (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
1168
1169 *effecter_data_size = response->effecter_data_size;
1170 *effecter_oper_state = response->effecter_oper_state;
1171
1172 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1173 return PLDM_ERROR_INVALID_DATA;
1174 }
1175
1176 if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1177 return PLDM_ERROR_INVALID_DATA;
1178 }
1179
1180 if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1181 *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1182 if (payload_length !=
1183 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1184 return PLDM_ERROR_INVALID_LENGTH;
1185 }
1186 memcpy(pending_value, response->pending_and_present_values, 1);
1187 memcpy(present_value, &response->pending_and_present_values[1],
1188 1);
1189
1190 } else if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1191 *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1192 if (payload_length !=
1193 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
1194 return PLDM_ERROR_INVALID_LENGTH;
1195 }
Jolie Ku3cdbcfb2020-04-17 10:30:59 +08001196 memcpy(pending_value, response->pending_and_present_values,
1197 sizeof(uint16_t));
1198 uint16_t *val_pending = (uint16_t *)pending_value;
1199 *val_pending = le16toh(*val_pending);
1200 memcpy(
1201 present_value,
1202 (response->pending_and_present_values + sizeof(uint16_t)),
1203 sizeof(uint16_t));
1204 uint16_t *val_present = (uint16_t *)present_value;
1205 *val_present = le16toh(*val_present);
Jolie Ku6787f172020-03-19 11:15:53 +08001206
1207 } else if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1208 *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1209 if (payload_length !=
1210 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
1211 return PLDM_ERROR_INVALID_LENGTH;
1212 }
Jolie Ku3cdbcfb2020-04-17 10:30:59 +08001213 memcpy(pending_value, response->pending_and_present_values,
1214 sizeof(uint32_t));
1215 uint32_t *val_pending = (uint32_t *)pending_value;
1216 *val_pending = le32toh(*val_pending);
1217 memcpy(
1218 present_value,
1219 (response->pending_and_present_values + sizeof(uint32_t)),
1220 sizeof(uint32_t));
1221 uint32_t *val_present = (uint32_t *)present_value;
1222 *val_present = le32toh(*val_present);
Jolie Ku6787f172020-03-19 11:15:53 +08001223 }
1224 return PLDM_SUCCESS;
Zach Clark3dba2bf2020-03-31 10:58:03 -05001225}
Zahed Hossain9be087c2020-04-02 02:26:41 -05001226
Zach Clark36ad1f52020-04-13 07:04:15 -05001227int encode_pldm_pdr_repository_chg_event_data(
1228 uint8_t event_data_format, uint8_t number_of_change_records,
1229 const uint8_t *event_data_operations,
1230 const uint8_t *numbers_of_change_entries,
1231 const uint32_t *const *change_entries,
1232 struct pldm_pdr_repository_chg_event_data *event_data,
1233 size_t *actual_change_records_size, size_t max_change_records_size)
1234{
1235 if (event_data_operations == NULL ||
1236 numbers_of_change_entries == NULL || change_entries == NULL) {
1237 return PLDM_ERROR_INVALID_DATA;
1238 }
1239
1240 size_t expected_size =
1241 sizeof(event_data_format) + sizeof(number_of_change_records);
1242
1243 expected_size +=
1244 sizeof(*event_data_operations) * number_of_change_records;
1245 expected_size +=
1246 sizeof(*numbers_of_change_entries) * number_of_change_records;
1247
1248 for (uint8_t i = 0; i < number_of_change_records; ++i) {
1249 expected_size +=
1250 sizeof(*change_entries[0]) * numbers_of_change_entries[i];
1251 }
1252
1253 *actual_change_records_size = expected_size;
1254
1255 if (event_data == NULL) {
1256 return PLDM_SUCCESS;
1257 }
1258
1259 if (max_change_records_size < expected_size) {
1260 return PLDM_ERROR_INVALID_LENGTH;
1261 }
1262
1263 event_data->event_data_format = event_data_format;
1264 event_data->number_of_change_records = number_of_change_records;
1265
1266 struct pldm_pdr_repository_change_record_data *record_data =
1267 (struct pldm_pdr_repository_change_record_data *)
1268 event_data->change_records;
1269
1270 for (uint8_t i = 0; i < number_of_change_records; ++i) {
1271 record_data->event_data_operation = event_data_operations[i];
1272 record_data->number_of_change_entries =
1273 numbers_of_change_entries[i];
1274
1275 for (uint8_t j = 0; j < record_data->number_of_change_entries;
1276 ++j) {
1277 record_data->change_entry[j] =
1278 htole32(change_entries[i][j]);
1279 }
1280
1281 record_data = (struct pldm_pdr_repository_change_record_data
1282 *)(record_data->change_entry +
1283 record_data->number_of_change_entries);
1284 }
1285
1286 return PLDM_SUCCESS;
1287}
1288
Zahed Hossain9be087c2020-04-02 02:26:41 -05001289int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data,
1290 size_t event_data_size,
1291 uint8_t *event_data_format,
1292 uint8_t *number_of_change_records,
1293 size_t *change_record_data_offset)
1294{
1295 if (event_data == NULL || event_data_format == NULL ||
1296 number_of_change_records == NULL ||
1297 change_record_data_offset == NULL) {
1298 return PLDM_ERROR_INVALID_DATA;
1299 }
1300 if (event_data_size < PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH) {
1301 return PLDM_ERROR_INVALID_LENGTH;
1302 }
1303
1304 struct pldm_pdr_repository_chg_event_data
1305 *pdr_repository_chg_event_data =
1306 (struct pldm_pdr_repository_chg_event_data *)event_data;
1307
1308 *event_data_format = pdr_repository_chg_event_data->event_data_format;
1309 *number_of_change_records =
1310 pdr_repository_chg_event_data->number_of_change_records;
1311 *change_record_data_offset =
1312 sizeof(*event_data_format) + sizeof(*number_of_change_records);
1313
1314 return PLDM_SUCCESS;
1315}
1316
1317int decode_pldm_pdr_repository_change_record_data(
1318 const uint8_t *change_record_data, size_t change_record_data_size,
1319 uint8_t *event_data_operation, uint8_t *number_of_change_entries,
1320 size_t *change_entry_data_offset)
1321{
1322 if (change_record_data == NULL || event_data_operation == NULL ||
1323 number_of_change_entries == NULL ||
1324 change_entry_data_offset == NULL) {
1325 return PLDM_ERROR_INVALID_DATA;
1326 }
1327 if (change_record_data_size <
1328 PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH) {
1329 return PLDM_ERROR_INVALID_LENGTH;
1330 }
1331
1332 struct pldm_pdr_repository_change_record_data
1333 *pdr_repository_change_record_data =
1334 (struct pldm_pdr_repository_change_record_data *)
1335 change_record_data;
1336
1337 *event_data_operation =
1338 pdr_repository_change_record_data->event_data_operation;
1339 *number_of_change_entries =
1340 pdr_repository_change_record_data->number_of_change_entries;
1341 *change_entry_data_offset =
1342 sizeof(*event_data_operation) + sizeof(*number_of_change_entries);
1343
1344 return PLDM_SUCCESS;
1345}
Jolie Kuf798c8f2020-04-14 11:18:06 +08001346
1347int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id,
1348 uint8_t rearm_event_state,
1349 struct pldm_msg *msg)
1350{
1351 struct pldm_header_info header = {0};
1352 int rc = PLDM_SUCCESS;
1353
1354 header.msg_type = PLDM_REQUEST;
1355 header.instance = instance_id;
1356 header.pldm_type = PLDM_PLATFORM;
1357 header.command = PLDM_GET_SENSOR_READING;
1358
1359 if (msg == NULL) {
1360 return PLDM_ERROR_INVALID_DATA;
1361 }
1362
1363 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
1364 return rc;
1365 }
1366
1367 struct pldm_get_sensor_reading_req *request =
1368 (struct pldm_get_sensor_reading_req *)msg->payload;
1369
1370 request->sensor_id = htole16(sensor_id);
1371 request->rearm_event_state = rearm_event_state;
1372
1373 return PLDM_SUCCESS;
1374}
1375
1376int decode_get_sensor_reading_resp(
1377 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
1378 uint8_t *sensor_data_size, uint8_t *sensor_operational_state,
1379 uint8_t *sensor_event_message_enable, uint8_t *present_state,
1380 uint8_t *previous_state, uint8_t *event_state, uint8_t *present_reading)
1381{
1382 if (msg == NULL || completion_code == NULL ||
1383 sensor_data_size == NULL || sensor_operational_state == NULL ||
1384 sensor_event_message_enable == NULL || present_state == NULL ||
1385 previous_state == NULL || event_state == NULL ||
1386 present_reading == NULL) {
1387 return PLDM_ERROR_INVALID_DATA;
1388 }
1389
1390 *completion_code = msg->payload[0];
1391 if (PLDM_SUCCESS != *completion_code) {
1392 return PLDM_SUCCESS;
1393 }
1394
1395 if (payload_length < PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
1396 return PLDM_ERROR_INVALID_LENGTH;
1397 }
1398
1399 struct pldm_get_sensor_reading_resp *response =
1400 (struct pldm_get_sensor_reading_resp *)msg->payload;
1401
1402 if (response->sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) {
1403 return PLDM_ERROR_INVALID_DATA;
1404 }
1405 if (response->sensor_data_size > *sensor_data_size) {
1406 return PLDM_ERROR_INVALID_LENGTH;
1407 }
1408
1409 *sensor_data_size = response->sensor_data_size;
1410 *sensor_operational_state = response->sensor_operational_state;
1411 *sensor_event_message_enable = response->sensor_event_message_enable;
1412 *present_state = response->present_state;
1413 *previous_state = response->previous_state;
1414 *event_state = response->event_state;
1415
1416 if (*sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1417 *sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1418 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
1419 return PLDM_ERROR_INVALID_LENGTH;
1420 }
1421 *present_reading = response->present_reading[0];
1422
1423 } else if (*sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1424 *sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1425 if (payload_length !=
1426 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
1427 return PLDM_ERROR_INVALID_LENGTH;
1428 }
1429 memcpy(present_reading, response->present_reading, 2);
1430 uint16_t *val = (uint16_t *)(present_reading);
1431 *val = le16toh(*val);
1432
1433 } else if (*sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1434 *sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1435 if (payload_length !=
1436 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
1437 return PLDM_ERROR_INVALID_LENGTH;
1438 }
1439 memcpy(present_reading, response->present_reading, 4);
1440 uint32_t *val = (uint32_t *)(present_reading);
1441 *val = le32toh(*val);
1442 }
1443
1444 return PLDM_SUCCESS;
1445}
1446
1447int encode_get_sensor_reading_resp(
1448 uint8_t instance_id, uint8_t completion_code, uint8_t sensor_data_size,
1449 uint8_t sensor_operational_state, uint8_t sensor_event_message_enable,
1450 uint8_t present_state, uint8_t previous_state, uint8_t event_state,
1451 uint8_t *present_reading, struct pldm_msg *msg, size_t payload_length)
1452{
1453 struct pldm_header_info header = {0};
1454 int rc = PLDM_SUCCESS;
1455
1456 if (msg == NULL || present_reading == NULL) {
1457 return PLDM_ERROR_INVALID_DATA;
1458 }
1459
1460 if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1461 return PLDM_ERROR_INVALID_DATA;
1462 }
1463
1464 header.msg_type = PLDM_RESPONSE;
1465 header.instance = instance_id;
1466 header.pldm_type = PLDM_PLATFORM;
1467 header.command = PLDM_GET_SENSOR_READING;
1468
1469 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
1470 return rc;
1471 }
1472
1473 struct pldm_get_sensor_reading_resp *response =
1474 (struct pldm_get_sensor_reading_resp *)msg->payload;
1475
1476 response->completion_code = completion_code;
1477 response->sensor_data_size = sensor_data_size;
1478 response->sensor_operational_state = sensor_operational_state;
1479 response->sensor_event_message_enable = sensor_event_message_enable;
1480 response->present_state = present_state;
1481 response->previous_state = previous_state;
1482 response->event_state = event_state;
1483
1484 if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1485 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1486 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
1487 return PLDM_ERROR_INVALID_LENGTH;
1488 }
1489 response->present_reading[0] = *present_reading;
1490
1491 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1492 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1493 if (payload_length !=
1494 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
1495 return PLDM_ERROR_INVALID_LENGTH;
1496 }
1497 uint16_t val = *(uint16_t *)present_reading;
1498 val = htole16(val);
1499 memcpy(response->present_reading, &val, 2);
1500
1501 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1502 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1503 if (payload_length !=
1504 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
1505 return PLDM_ERROR_INVALID_LENGTH;
1506 }
1507 uint32_t val = *(uint32_t *)present_reading;
1508 val = htole32(val);
1509 memcpy(response->present_reading, &val, 4);
1510 }
1511
1512 return PLDM_SUCCESS;
1513}
1514
1515int decode_get_sensor_reading_req(const struct pldm_msg *msg,
1516 size_t payload_length, uint16_t *sensor_id,
1517 uint8_t *rearm_event_state)
1518{
1519 if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) {
1520 return PLDM_ERROR_INVALID_DATA;
1521 }
1522
1523 if (payload_length != PLDM_GET_SENSOR_READING_REQ_BYTES) {
1524 return PLDM_ERROR_INVALID_LENGTH;
1525 }
1526
1527 struct pldm_get_sensor_reading_req *request =
1528 (struct pldm_get_sensor_reading_req *)msg->payload;
1529
1530 *sensor_id = le16toh(request->sensor_id);
1531 *rearm_event_state = request->rearm_event_state;
1532
1533 return PLDM_SUCCESS;
1534}