blob: bc45ae0fda9e7a28b8da55d29845b620750e4250 [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
George Liu80237ef2020-07-10 15:16:39 +0800652 if (payload_length >
653 PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES +
654 sizeof(get_sensor_state_field) * *comp_sensor_count) {
Jolie Ku3557bad2020-03-02 16:22:57 +0800655 return PLDM_ERROR_INVALID_LENGTH;
656 }
657
658 struct pldm_get_state_sensor_readings_resp *response =
659 (struct pldm_get_state_sensor_readings_resp *)msg->payload;
660
661 if (response->comp_sensor_count < 0x1 ||
662 response->comp_sensor_count > 0x8) {
663 return PLDM_ERROR_INVALID_DATA;
664 }
665 if (response->comp_sensor_count > *comp_sensor_count) {
666 return PLDM_ERROR_INVALID_LENGTH;
667 }
668 *comp_sensor_count = response->comp_sensor_count;
669
670 memcpy(field, response->field,
671 (sizeof(get_sensor_state_field) * (*comp_sensor_count)));
672
673 return PLDM_SUCCESS;
674}
675
676int decode_get_state_sensor_readings_req(const struct pldm_msg *msg,
677 size_t payload_length,
678 uint16_t *sensor_id,
679 bitfield8_t *sensor_rearm,
680 uint8_t *reserved)
681{
682 if (msg == NULL || sensor_id == NULL || sensor_rearm == NULL) {
683 return PLDM_ERROR_INVALID_DATA;
684 }
685
686 if (payload_length != PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES) {
687 return PLDM_ERROR_INVALID_LENGTH;
688 }
689
690 struct pldm_get_state_sensor_readings_req *request =
691 (struct pldm_get_state_sensor_readings_req *)msg->payload;
692
693 *sensor_id = le16toh(request->sensor_id);
694 *reserved = request->reserved;
695 memcpy(&(sensor_rearm->byte), &(request->sensor_rearm.byte),
696 sizeof(request->sensor_rearm.byte));
697
698 return PLDM_SUCCESS;
699}
Zahed Hossaind4abab12020-02-06 03:36:43 -0600700
Zach Clarkb728eee2020-06-18 10:01:31 -0500701int encode_sensor_event_data(
702 struct pldm_sensor_event_data *const event_data,
703 const size_t event_data_size, const uint16_t sensor_id,
704 const enum sensor_event_class_states sensor_event_class,
705 const uint8_t sensor_offset, const uint8_t event_state,
706 const uint8_t previous_event_state, size_t *const actual_event_data_size)
707{
708 *actual_event_data_size =
709 (sizeof(*event_data) - sizeof(event_data->event_class) +
710 sizeof(struct pldm_sensor_event_state_sensor_state));
711
712 if (!event_data) {
713 return PLDM_SUCCESS;
714 }
715
716 if (event_data_size < *actual_event_data_size) {
717 *actual_event_data_size = 0;
718 return PLDM_ERROR_INVALID_LENGTH;
719 }
720
721 event_data->sensor_id = htole32(sensor_id);
722 event_data->sensor_event_class_type = sensor_event_class;
723
724 struct pldm_sensor_event_state_sensor_state *const state_data =
725 (struct pldm_sensor_event_state_sensor_state *)
726 event_data->event_class;
727
728 state_data->sensor_offset = sensor_offset;
729 state_data->event_state = event_state;
730 state_data->previous_event_state = previous_event_state;
731
732 return PLDM_SUCCESS;
733}
734
Zahed Hossaind4abab12020-02-06 03:36:43 -0600735int decode_platform_event_message_req(const struct pldm_msg *msg,
736 size_t payload_length,
737 uint8_t *format_version, uint8_t *tid,
738 uint8_t *event_class,
739 size_t *event_data_offset)
740{
741
742 if (msg == NULL || format_version == NULL || tid == NULL ||
743 event_class == NULL || event_data_offset == NULL) {
744 return PLDM_ERROR_INVALID_DATA;
745 }
746
747 if (payload_length <= PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) {
748 return PLDM_ERROR_INVALID_LENGTH;
749 }
750 struct pldm_platform_event_message_req *response =
751 (struct pldm_platform_event_message_req *)msg->payload;
752
753 *format_version = response->format_version;
754 *tid = response->tid;
755 *event_class = response->event_class;
756 *event_data_offset =
757 sizeof(*format_version) + sizeof(*tid) + sizeof(*event_class);
758
759 return PLDM_SUCCESS;
760}
761
762int encode_platform_event_message_resp(uint8_t instance_id,
Pavithra Barithaya2ea1f072020-04-03 09:30:23 -0500763 uint8_t completion_code,
764 uint8_t platform_event_status,
Zahed Hossaind4abab12020-02-06 03:36:43 -0600765 struct pldm_msg *msg)
766{
767 int rc = PLDM_SUCCESS;
768
769 if (msg == NULL) {
770 return PLDM_ERROR_INVALID_DATA;
771 }
772
Pavithra Barithaya2ea1f072020-04-03 09:30:23 -0500773 if (platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
774 return PLDM_ERROR_INVALID_DATA;
775 }
776
Zahed Hossaind4abab12020-02-06 03:36:43 -0600777 struct pldm_platform_event_message_resp *response =
778 (struct pldm_platform_event_message_resp *)msg->payload;
779 response->completion_code = completion_code;
Pavithra Barithaya2ea1f072020-04-03 09:30:23 -0500780 response->platform_event_status = platform_event_status;
Zahed Hossaind4abab12020-02-06 03:36:43 -0600781
782 struct pldm_header_info header = {0};
783 header.msg_type = PLDM_RESPONSE;
784 header.instance = instance_id;
785 header.pldm_type = PLDM_PLATFORM;
786 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
787
788 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
789 return rc;
790 }
791 return PLDM_SUCCESS;
792}
Zahed Hossain1c861712020-03-04 08:55:19 -0600793
Christian Geddes3bdb3c22020-05-01 14:55:39 -0500794int encode_platform_event_message_req(
795 uint8_t instance_id, uint8_t format_version, uint8_t tid,
796 uint8_t event_class, const uint8_t *event_data, size_t event_data_length,
797 struct pldm_msg *msg, size_t payload_length)
Pavithra Barithaya35f2b2c2020-04-08 01:35:56 -0500798
799{
800 struct pldm_header_info header = {0};
801 int rc = PLDM_SUCCESS;
802
803 header.msg_type = PLDM_REQUEST;
804 header.instance = instance_id;
805 header.pldm_type = PLDM_PLATFORM;
806 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
807
808 if (format_version != 1) {
809 return PLDM_ERROR_INVALID_DATA;
810 }
811
812 if (msg == NULL || event_data == NULL) {
813 return PLDM_ERROR_INVALID_DATA;
814 }
815
816 if (event_data_length == 0) {
817 return PLDM_ERROR_INVALID_DATA;
818 }
819
Christian Geddes3bdb3c22020-05-01 14:55:39 -0500820 if (payload_length !=
821 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) {
822 return PLDM_ERROR_INVALID_LENGTH;
823 }
824
Pavithra Barithaya35f2b2c2020-04-08 01:35:56 -0500825 if (event_class > PLDM_HEARTBEAT_TIMER_ELAPSED_EVENT &&
826 !(event_class >= 0xF0 && event_class <= 0xFE)) {
827 return PLDM_ERROR_INVALID_DATA;
828 }
829
830 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
831 return rc;
832 }
833
834 struct pldm_platform_event_message_req *request =
835 (struct pldm_platform_event_message_req *)msg->payload;
836 request->format_version = format_version;
837 request->tid = tid;
838 request->event_class = event_class;
839 memcpy(request->event_data, event_data, event_data_length);
840
841 return PLDM_SUCCESS;
842}
843
844int decode_platform_event_message_resp(const struct pldm_msg *msg,
845 size_t payload_length,
846 uint8_t *completion_code,
847 uint8_t *platform_event_status)
848{
849 if (msg == NULL || completion_code == NULL ||
850 platform_event_status == NULL) {
851 return PLDM_ERROR_INVALID_DATA;
852 }
853
854 *completion_code = msg->payload[0];
855 if (PLDM_SUCCESS != *completion_code) {
856 return PLDM_SUCCESS;
857 }
858 if (payload_length != PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES) {
859 return PLDM_ERROR_INVALID_LENGTH;
860 }
861
862 struct pldm_platform_event_message_resp *response =
863 (struct pldm_platform_event_message_resp *)msg->payload;
864 *platform_event_status = response->platform_event_status;
865
866 if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
867 return PLDM_ERROR_INVALID_DATA;
868 }
869
870 return PLDM_SUCCESS;
871}
872
Zahed Hossain1c861712020-03-04 08:55:19 -0600873int decode_sensor_event_data(const uint8_t *event_data,
874 size_t event_data_length, uint16_t *sensor_id,
875 uint8_t *sensor_event_class_type,
876 size_t *event_class_data_offset)
877{
878 if (event_data == NULL) {
879 return PLDM_ERROR_INVALID_DATA;
880 }
881 if (event_data_length < PLDM_SENSOR_EVENT_DATA_MIN_LENGTH) {
882 return PLDM_ERROR_INVALID_LENGTH;
883 }
884
885 size_t event_class_data_length =
886 event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES;
887
888 struct pldm_sensor_event_data *sensor_event_data =
889 (struct pldm_sensor_event_data *)event_data;
890 *sensor_id = sensor_event_data->sensor_id;
891 *sensor_event_class_type = sensor_event_data->sensor_event_class_type;
892 if (sensor_event_data->sensor_event_class_type ==
893 PLDM_SENSOR_OP_STATE) {
894 if (event_class_data_length !=
895 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
896 return PLDM_ERROR_INVALID_LENGTH;
897 }
898 } else if (sensor_event_data->sensor_event_class_type ==
899 PLDM_STATE_SENSOR_STATE) {
900 if (event_class_data_length !=
901 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
902 return PLDM_ERROR_INVALID_LENGTH;
903 }
904 } else if (sensor_event_data->sensor_event_class_type ==
905 PLDM_NUMERIC_SENSOR_STATE) {
906 if (event_class_data_length <
907 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
908 event_class_data_length >
909 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
910 return PLDM_ERROR_INVALID_LENGTH;
911 }
912 } else {
913 return PLDM_ERROR_INVALID_DATA;
914 }
915 *event_class_data_offset =
916 sizeof(*sensor_id) + sizeof(*sensor_event_class_type);
917 return PLDM_SUCCESS;
918}
919
920int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length,
921 uint8_t *present_op_state, uint8_t *previous_op_state)
922{
923 if (sensor_data == NULL || present_op_state == NULL ||
924 previous_op_state == NULL) {
925 return PLDM_ERROR_INVALID_DATA;
926 }
927 if (sensor_data_length !=
928 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
929 return PLDM_ERROR_INVALID_LENGTH;
930 }
931
932 struct pldm_sensor_event_sensor_op_state *sensor_op_data =
933 (struct pldm_sensor_event_sensor_op_state *)sensor_data;
934 *present_op_state = sensor_op_data->present_op_state;
935 *previous_op_state = sensor_op_data->previous_op_state;
936 return PLDM_SUCCESS;
937}
938
939int decode_state_sensor_data(const uint8_t *sensor_data,
940 size_t sensor_data_length, uint8_t *sensor_offset,
941 uint8_t *event_state,
942 uint8_t *previous_event_state)
943{
944 if (sensor_data == NULL || sensor_offset == NULL ||
945 event_state == NULL || previous_event_state == NULL) {
946 return PLDM_ERROR_INVALID_DATA;
947 }
948 if (sensor_data_length !=
949 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
950 return PLDM_ERROR_INVALID_LENGTH;
951 }
952
953 struct pldm_sensor_event_state_sensor_state *sensor_state_data =
954 (struct pldm_sensor_event_state_sensor_state *)sensor_data;
955 *sensor_offset = sensor_state_data->sensor_offset;
956 *event_state = sensor_state_data->event_state;
957 *previous_event_state = sensor_state_data->previous_event_state;
958 return PLDM_SUCCESS;
959}
960
961int decode_numeric_sensor_data(const uint8_t *sensor_data,
962 size_t sensor_data_length, uint8_t *event_state,
963 uint8_t *previous_event_state,
964 uint8_t *sensor_data_size,
965 uint32_t *present_reading)
966{
967 if (sensor_data == NULL || sensor_data_size == NULL ||
968 event_state == NULL || previous_event_state == NULL ||
969 present_reading == NULL) {
970 return PLDM_ERROR_INVALID_DATA;
971 }
972 if (sensor_data_length <
973 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
974 sensor_data_length >
975 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
976 return PLDM_ERROR_INVALID_LENGTH;
977 }
978 struct pldm_sensor_event_numeric_sensor_state *numeric_sensor_data =
979 (struct pldm_sensor_event_numeric_sensor_state *)sensor_data;
980 *event_state = numeric_sensor_data->event_state;
981 *previous_event_state = numeric_sensor_data->previous_event_state;
982 *sensor_data_size = numeric_sensor_data->sensor_data_size;
983 uint8_t *present_reading_ptr = numeric_sensor_data->present_reading;
984
985 switch (*sensor_data_size) {
986 case PLDM_SENSOR_DATA_SIZE_UINT8:
987 case PLDM_SENSOR_DATA_SIZE_SINT8:
988 if (sensor_data_length !=
989 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_8BIT_DATA_LENGTH) {
990 return PLDM_ERROR_INVALID_LENGTH;
991 }
992 *present_reading = present_reading_ptr[0];
993 break;
994 case PLDM_SENSOR_DATA_SIZE_UINT16:
995 case PLDM_SENSOR_DATA_SIZE_SINT16:
996 if (sensor_data_length !=
997 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_16BIT_DATA_LENGTH) {
998 return PLDM_ERROR_INVALID_LENGTH;
999 }
1000 *present_reading = le16toh(present_reading_ptr[1] |
1001 (present_reading_ptr[0] << 8));
1002 break;
1003 case PLDM_SENSOR_DATA_SIZE_UINT32:
1004 case PLDM_SENSOR_DATA_SIZE_SINT32:
1005 if (sensor_data_length !=
1006 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_32BIT_DATA_LENGTH) {
1007 return PLDM_ERROR_INVALID_LENGTH;
1008 }
1009 *present_reading = le32toh(present_reading_ptr[3] |
1010 (present_reading_ptr[2] << 8) |
1011 (present_reading_ptr[1] << 16) |
1012 (present_reading_ptr[0] << 24));
1013 break;
1014 default:
1015 return PLDM_ERROR_INVALID_DATA;
1016 }
1017 return PLDM_SUCCESS;
1018}
Jolie Ku6787f172020-03-19 11:15:53 +08001019
1020int encode_get_numeric_effecter_value_req(uint8_t instance_id,
1021 uint16_t effecter_id,
1022 struct pldm_msg *msg)
1023{
1024 struct pldm_header_info header = {0};
1025 int rc = PLDM_SUCCESS;
1026
1027 if (msg == NULL) {
1028 return PLDM_ERROR_INVALID_DATA;
1029 }
1030
1031 struct pldm_get_numeric_effecter_value_req *request =
1032 (struct pldm_get_numeric_effecter_value_req *)msg->payload;
1033
1034 header.msg_type = PLDM_REQUEST;
1035 header.instance = instance_id;
1036 header.pldm_type = PLDM_PLATFORM;
1037 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1038
1039 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
1040 return rc;
1041 }
1042
1043 request->effecter_id = htole16(effecter_id);
1044
1045 return PLDM_SUCCESS;
1046}
1047
1048int encode_get_numeric_effecter_value_resp(
1049 uint8_t instance_id, uint8_t completion_code, uint8_t effecter_data_size,
1050 uint8_t effecter_oper_state, uint8_t *pending_value, uint8_t *present_value,
1051 struct pldm_msg *msg, size_t payload_length)
1052{
1053 struct pldm_header_info header = {0};
1054 int rc = PLDM_SUCCESS;
1055
1056 if (msg == NULL || pending_value == NULL || present_value == NULL) {
1057 return PLDM_ERROR_INVALID_DATA;
1058 }
1059
1060 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1061 return PLDM_ERROR_INVALID_DATA;
1062 }
1063
1064 if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1065 return PLDM_ERROR_INVALID_DATA;
1066 }
1067
1068 header.msg_type = PLDM_RESPONSE;
1069 header.instance = instance_id;
1070 header.pldm_type = PLDM_PLATFORM;
1071 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1072
1073 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
1074 return rc;
1075 }
1076
1077 struct pldm_get_numeric_effecter_value_resp *response =
1078 (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
1079
1080 response->completion_code = completion_code;
1081 response->effecter_data_size = effecter_data_size;
1082 response->effecter_oper_state = effecter_oper_state;
1083
1084 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1085 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1086 if (payload_length !=
1087 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1088 return PLDM_ERROR_INVALID_LENGTH;
1089 }
1090 response->pending_and_present_values[0] = *pending_value;
1091 response->pending_and_present_values[1] = *present_value;
1092
1093 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1094 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1095 if (payload_length !=
1096 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
1097 return PLDM_ERROR_INVALID_LENGTH;
1098 }
Jolie Ku3cdbcfb2020-04-17 10:30:59 +08001099 uint16_t val_pending = *(uint16_t *)pending_value;
1100 val_pending = htole16(val_pending);
1101 memcpy(response->pending_and_present_values, &val_pending,
1102 sizeof(uint16_t));
1103 uint16_t val_present = *(uint16_t *)present_value;
1104 val_present = htole16(val_present);
1105 memcpy(
1106 (response->pending_and_present_values + sizeof(uint16_t)),
1107 &val_present, sizeof(uint16_t));
Jolie Ku6787f172020-03-19 11:15:53 +08001108
1109 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1110 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1111 if (payload_length !=
1112 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
1113 return PLDM_ERROR_INVALID_LENGTH;
1114 }
Jolie Ku3cdbcfb2020-04-17 10:30:59 +08001115 uint32_t val_pending = *(uint32_t *)pending_value;
1116 val_pending = htole32(val_pending);
1117 memcpy(response->pending_and_present_values, &val_pending,
1118 sizeof(uint32_t));
1119 uint32_t val_present = *(uint32_t *)present_value;
1120 val_present = htole32(val_present);
1121 memcpy(
1122 (response->pending_and_present_values + sizeof(uint32_t)),
1123 &val_present, sizeof(uint32_t));
Jolie Ku6787f172020-03-19 11:15:53 +08001124 }
1125 return PLDM_SUCCESS;
1126}
1127
1128int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg,
1129 size_t payload_length,
1130 uint16_t *effecter_id)
1131{
1132 if (msg == NULL || effecter_id == NULL) {
1133 return PLDM_ERROR_INVALID_DATA;
1134 }
1135
1136 if (payload_length != PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES) {
1137 return PLDM_ERROR_INVALID_LENGTH;
1138 }
1139
1140 struct pldm_get_numeric_effecter_value_req *request =
1141 (struct pldm_get_numeric_effecter_value_req *)msg->payload;
1142
1143 *effecter_id = le16toh(request->effecter_id);
1144
1145 return PLDM_SUCCESS;
1146}
1147
1148int decode_get_numeric_effecter_value_resp(
1149 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
1150 uint8_t *effecter_data_size, uint8_t *effecter_oper_state,
1151 uint8_t *pending_value, uint8_t *present_value)
1152{
1153 if (msg == NULL || effecter_data_size == NULL ||
1154 effecter_oper_state == NULL || pending_value == NULL ||
1155 present_value == NULL) {
1156 return PLDM_ERROR_INVALID_DATA;
1157 }
1158
1159 *completion_code = msg->payload[0];
1160 if (PLDM_SUCCESS != *completion_code) {
1161 return PLDM_SUCCESS;
1162 }
1163
1164 if (payload_length < PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1165 return PLDM_ERROR_INVALID_LENGTH;
1166 }
1167
1168 struct pldm_get_numeric_effecter_value_resp *response =
1169 (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
1170
1171 *effecter_data_size = response->effecter_data_size;
1172 *effecter_oper_state = response->effecter_oper_state;
1173
1174 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1175 return PLDM_ERROR_INVALID_DATA;
1176 }
1177
1178 if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1179 return PLDM_ERROR_INVALID_DATA;
1180 }
1181
1182 if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1183 *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1184 if (payload_length !=
1185 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1186 return PLDM_ERROR_INVALID_LENGTH;
1187 }
1188 memcpy(pending_value, response->pending_and_present_values, 1);
1189 memcpy(present_value, &response->pending_and_present_values[1],
1190 1);
1191
1192 } else if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1193 *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1194 if (payload_length !=
1195 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
1196 return PLDM_ERROR_INVALID_LENGTH;
1197 }
Jolie Ku3cdbcfb2020-04-17 10:30:59 +08001198 memcpy(pending_value, response->pending_and_present_values,
1199 sizeof(uint16_t));
1200 uint16_t *val_pending = (uint16_t *)pending_value;
1201 *val_pending = le16toh(*val_pending);
1202 memcpy(
1203 present_value,
1204 (response->pending_and_present_values + sizeof(uint16_t)),
1205 sizeof(uint16_t));
1206 uint16_t *val_present = (uint16_t *)present_value;
1207 *val_present = le16toh(*val_present);
Jolie Ku6787f172020-03-19 11:15:53 +08001208
1209 } else if (*effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1210 *effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1211 if (payload_length !=
1212 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
1213 return PLDM_ERROR_INVALID_LENGTH;
1214 }
Jolie Ku3cdbcfb2020-04-17 10:30:59 +08001215 memcpy(pending_value, response->pending_and_present_values,
1216 sizeof(uint32_t));
1217 uint32_t *val_pending = (uint32_t *)pending_value;
1218 *val_pending = le32toh(*val_pending);
1219 memcpy(
1220 present_value,
1221 (response->pending_and_present_values + sizeof(uint32_t)),
1222 sizeof(uint32_t));
1223 uint32_t *val_present = (uint32_t *)present_value;
1224 *val_present = le32toh(*val_present);
Jolie Ku6787f172020-03-19 11:15:53 +08001225 }
1226 return PLDM_SUCCESS;
Zach Clark3dba2bf2020-03-31 10:58:03 -05001227}
Zahed Hossain9be087c2020-04-02 02:26:41 -05001228
Zach Clark36ad1f52020-04-13 07:04:15 -05001229int encode_pldm_pdr_repository_chg_event_data(
1230 uint8_t event_data_format, uint8_t number_of_change_records,
1231 const uint8_t *event_data_operations,
1232 const uint8_t *numbers_of_change_entries,
1233 const uint32_t *const *change_entries,
1234 struct pldm_pdr_repository_chg_event_data *event_data,
1235 size_t *actual_change_records_size, size_t max_change_records_size)
1236{
1237 if (event_data_operations == NULL ||
1238 numbers_of_change_entries == NULL || change_entries == NULL) {
1239 return PLDM_ERROR_INVALID_DATA;
1240 }
1241
1242 size_t expected_size =
1243 sizeof(event_data_format) + sizeof(number_of_change_records);
1244
1245 expected_size +=
1246 sizeof(*event_data_operations) * number_of_change_records;
1247 expected_size +=
1248 sizeof(*numbers_of_change_entries) * number_of_change_records;
1249
1250 for (uint8_t i = 0; i < number_of_change_records; ++i) {
1251 expected_size +=
1252 sizeof(*change_entries[0]) * numbers_of_change_entries[i];
1253 }
1254
1255 *actual_change_records_size = expected_size;
1256
1257 if (event_data == NULL) {
1258 return PLDM_SUCCESS;
1259 }
1260
1261 if (max_change_records_size < expected_size) {
1262 return PLDM_ERROR_INVALID_LENGTH;
1263 }
1264
1265 event_data->event_data_format = event_data_format;
1266 event_data->number_of_change_records = number_of_change_records;
1267
1268 struct pldm_pdr_repository_change_record_data *record_data =
1269 (struct pldm_pdr_repository_change_record_data *)
1270 event_data->change_records;
1271
1272 for (uint8_t i = 0; i < number_of_change_records; ++i) {
1273 record_data->event_data_operation = event_data_operations[i];
1274 record_data->number_of_change_entries =
1275 numbers_of_change_entries[i];
1276
1277 for (uint8_t j = 0; j < record_data->number_of_change_entries;
1278 ++j) {
1279 record_data->change_entry[j] =
1280 htole32(change_entries[i][j]);
1281 }
1282
1283 record_data = (struct pldm_pdr_repository_change_record_data
1284 *)(record_data->change_entry +
1285 record_data->number_of_change_entries);
1286 }
1287
1288 return PLDM_SUCCESS;
1289}
1290
Zahed Hossain9be087c2020-04-02 02:26:41 -05001291int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data,
1292 size_t event_data_size,
1293 uint8_t *event_data_format,
1294 uint8_t *number_of_change_records,
1295 size_t *change_record_data_offset)
1296{
1297 if (event_data == NULL || event_data_format == NULL ||
1298 number_of_change_records == NULL ||
1299 change_record_data_offset == NULL) {
1300 return PLDM_ERROR_INVALID_DATA;
1301 }
1302 if (event_data_size < PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH) {
1303 return PLDM_ERROR_INVALID_LENGTH;
1304 }
1305
1306 struct pldm_pdr_repository_chg_event_data
1307 *pdr_repository_chg_event_data =
1308 (struct pldm_pdr_repository_chg_event_data *)event_data;
1309
1310 *event_data_format = pdr_repository_chg_event_data->event_data_format;
1311 *number_of_change_records =
1312 pdr_repository_chg_event_data->number_of_change_records;
1313 *change_record_data_offset =
1314 sizeof(*event_data_format) + sizeof(*number_of_change_records);
1315
1316 return PLDM_SUCCESS;
1317}
1318
1319int decode_pldm_pdr_repository_change_record_data(
1320 const uint8_t *change_record_data, size_t change_record_data_size,
1321 uint8_t *event_data_operation, uint8_t *number_of_change_entries,
1322 size_t *change_entry_data_offset)
1323{
1324 if (change_record_data == NULL || event_data_operation == NULL ||
1325 number_of_change_entries == NULL ||
1326 change_entry_data_offset == NULL) {
1327 return PLDM_ERROR_INVALID_DATA;
1328 }
1329 if (change_record_data_size <
1330 PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH) {
1331 return PLDM_ERROR_INVALID_LENGTH;
1332 }
1333
1334 struct pldm_pdr_repository_change_record_data
1335 *pdr_repository_change_record_data =
1336 (struct pldm_pdr_repository_change_record_data *)
1337 change_record_data;
1338
1339 *event_data_operation =
1340 pdr_repository_change_record_data->event_data_operation;
1341 *number_of_change_entries =
1342 pdr_repository_change_record_data->number_of_change_entries;
1343 *change_entry_data_offset =
1344 sizeof(*event_data_operation) + sizeof(*number_of_change_entries);
1345
1346 return PLDM_SUCCESS;
1347}
Jolie Kuf798c8f2020-04-14 11:18:06 +08001348
1349int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id,
1350 uint8_t rearm_event_state,
1351 struct pldm_msg *msg)
1352{
1353 struct pldm_header_info header = {0};
1354 int rc = PLDM_SUCCESS;
1355
1356 header.msg_type = PLDM_REQUEST;
1357 header.instance = instance_id;
1358 header.pldm_type = PLDM_PLATFORM;
1359 header.command = PLDM_GET_SENSOR_READING;
1360
1361 if (msg == NULL) {
1362 return PLDM_ERROR_INVALID_DATA;
1363 }
1364
1365 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
1366 return rc;
1367 }
1368
1369 struct pldm_get_sensor_reading_req *request =
1370 (struct pldm_get_sensor_reading_req *)msg->payload;
1371
1372 request->sensor_id = htole16(sensor_id);
1373 request->rearm_event_state = rearm_event_state;
1374
1375 return PLDM_SUCCESS;
1376}
1377
1378int decode_get_sensor_reading_resp(
1379 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
1380 uint8_t *sensor_data_size, uint8_t *sensor_operational_state,
1381 uint8_t *sensor_event_message_enable, uint8_t *present_state,
1382 uint8_t *previous_state, uint8_t *event_state, uint8_t *present_reading)
1383{
1384 if (msg == NULL || completion_code == NULL ||
1385 sensor_data_size == NULL || sensor_operational_state == NULL ||
1386 sensor_event_message_enable == NULL || present_state == NULL ||
1387 previous_state == NULL || event_state == NULL ||
1388 present_reading == NULL) {
1389 return PLDM_ERROR_INVALID_DATA;
1390 }
1391
1392 *completion_code = msg->payload[0];
1393 if (PLDM_SUCCESS != *completion_code) {
1394 return PLDM_SUCCESS;
1395 }
1396
1397 if (payload_length < PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
1398 return PLDM_ERROR_INVALID_LENGTH;
1399 }
1400
1401 struct pldm_get_sensor_reading_resp *response =
1402 (struct pldm_get_sensor_reading_resp *)msg->payload;
1403
1404 if (response->sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) {
1405 return PLDM_ERROR_INVALID_DATA;
1406 }
1407 if (response->sensor_data_size > *sensor_data_size) {
1408 return PLDM_ERROR_INVALID_LENGTH;
1409 }
1410
1411 *sensor_data_size = response->sensor_data_size;
1412 *sensor_operational_state = response->sensor_operational_state;
1413 *sensor_event_message_enable = response->sensor_event_message_enable;
1414 *present_state = response->present_state;
1415 *previous_state = response->previous_state;
1416 *event_state = response->event_state;
1417
1418 if (*sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1419 *sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1420 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
1421 return PLDM_ERROR_INVALID_LENGTH;
1422 }
1423 *present_reading = response->present_reading[0];
1424
1425 } else if (*sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1426 *sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1427 if (payload_length !=
1428 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
1429 return PLDM_ERROR_INVALID_LENGTH;
1430 }
1431 memcpy(present_reading, response->present_reading, 2);
1432 uint16_t *val = (uint16_t *)(present_reading);
1433 *val = le16toh(*val);
1434
1435 } else if (*sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1436 *sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1437 if (payload_length !=
1438 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
1439 return PLDM_ERROR_INVALID_LENGTH;
1440 }
1441 memcpy(present_reading, response->present_reading, 4);
1442 uint32_t *val = (uint32_t *)(present_reading);
1443 *val = le32toh(*val);
1444 }
1445
1446 return PLDM_SUCCESS;
1447}
1448
1449int encode_get_sensor_reading_resp(
1450 uint8_t instance_id, uint8_t completion_code, uint8_t sensor_data_size,
1451 uint8_t sensor_operational_state, uint8_t sensor_event_message_enable,
1452 uint8_t present_state, uint8_t previous_state, uint8_t event_state,
1453 uint8_t *present_reading, struct pldm_msg *msg, size_t payload_length)
1454{
1455 struct pldm_header_info header = {0};
1456 int rc = PLDM_SUCCESS;
1457
1458 if (msg == NULL || present_reading == NULL) {
1459 return PLDM_ERROR_INVALID_DATA;
1460 }
1461
1462 if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1463 return PLDM_ERROR_INVALID_DATA;
1464 }
1465
1466 header.msg_type = PLDM_RESPONSE;
1467 header.instance = instance_id;
1468 header.pldm_type = PLDM_PLATFORM;
1469 header.command = PLDM_GET_SENSOR_READING;
1470
1471 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
1472 return rc;
1473 }
1474
1475 struct pldm_get_sensor_reading_resp *response =
1476 (struct pldm_get_sensor_reading_resp *)msg->payload;
1477
1478 response->completion_code = completion_code;
1479 response->sensor_data_size = sensor_data_size;
1480 response->sensor_operational_state = sensor_operational_state;
1481 response->sensor_event_message_enable = sensor_event_message_enable;
1482 response->present_state = present_state;
1483 response->previous_state = previous_state;
1484 response->event_state = event_state;
1485
1486 if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1487 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1488 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
1489 return PLDM_ERROR_INVALID_LENGTH;
1490 }
1491 response->present_reading[0] = *present_reading;
1492
1493 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1494 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1495 if (payload_length !=
1496 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
1497 return PLDM_ERROR_INVALID_LENGTH;
1498 }
1499 uint16_t val = *(uint16_t *)present_reading;
1500 val = htole16(val);
1501 memcpy(response->present_reading, &val, 2);
1502
1503 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1504 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1505 if (payload_length !=
1506 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
1507 return PLDM_ERROR_INVALID_LENGTH;
1508 }
1509 uint32_t val = *(uint32_t *)present_reading;
1510 val = htole32(val);
1511 memcpy(response->present_reading, &val, 4);
1512 }
1513
1514 return PLDM_SUCCESS;
1515}
1516
1517int decode_get_sensor_reading_req(const struct pldm_msg *msg,
1518 size_t payload_length, uint16_t *sensor_id,
1519 uint8_t *rearm_event_state)
1520{
1521 if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) {
1522 return PLDM_ERROR_INVALID_DATA;
1523 }
1524
1525 if (payload_length != PLDM_GET_SENSOR_READING_REQ_BYTES) {
1526 return PLDM_ERROR_INVALID_LENGTH;
1527 }
1528
1529 struct pldm_get_sensor_reading_req *request =
1530 (struct pldm_get_sensor_reading_req *)msg->payload;
1531
1532 *sensor_id = le16toh(request->sensor_id);
1533 *rearm_event_state = request->rearm_event_state;
1534
1535 return PLDM_SUCCESS;
1536}