blob: eae38c1027566c3eb08ebe23326569382997c556 [file] [log] [blame]
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301#include "msgbuf/platform.h"
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05302#include "base.h"
Andrew Jeffery7992eb82023-04-06 16:13:53 +09303#include "msgbuf.h"
4#include "platform.h"
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05305#include "pldm_types.h"
Andrew Jeffery9c766792022-08-10 23:12:49 +09306#include <endian.h>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05307#include <stdint.h>
Thu Nguyen159a98b2022-11-02 10:00:10 +07008#include <stdlib.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +09309#include <string.h>
10
Andrew Jeffery7992eb82023-04-06 16:13:53 +093011static int pldm_platform_pdr_hdr_validate(struct pldm_value_pdr_hdr *ctx,
12 size_t lower, size_t upper)
13{
14 if (ctx->length + sizeof(*ctx) < lower) {
15 return PLDM_ERROR_INVALID_LENGTH;
16 }
17
18 if (ctx->length > upper) {
19 return PLDM_ERROR_INVALID_LENGTH;
20 }
21
22 return PLDM_SUCCESS;
23}
Andrew Jeffery9c766792022-08-10 23:12:49 +093024
25int encode_state_effecter_pdr(
26 struct pldm_state_effecter_pdr *const effecter,
27 const size_t allocation_size,
28 const struct state_effecter_possible_states *const possible_states,
29 const size_t possible_states_size, size_t *const actual_size)
30{
31 // Encode possible states
32
33 size_t calculated_possible_states_size = 0;
34
35 {
36 char *states_ptr = (char *)possible_states;
37 char *const begin_states_ptr = states_ptr;
38
39 for (int i = 0; i < effecter->composite_effecter_count; ++i) {
40 struct state_effecter_possible_states *states =
41 (struct state_effecter_possible_states *)states_ptr;
42
43 HTOLE16(states->state_set_id);
44
45 states_ptr +=
46 (sizeof(*states) - sizeof(states->states) +
47 states->possible_states_size);
48 }
49
50 calculated_possible_states_size = states_ptr - begin_states_ptr;
51 }
52
53 // Check lengths
54
55 if (possible_states_size != calculated_possible_states_size) {
56 *actual_size = 0;
57 return PLDM_ERROR;
58 }
59
60 *actual_size =
61 (sizeof(struct pldm_state_effecter_pdr) + possible_states_size -
62 sizeof(effecter->possible_states));
63
64 if (allocation_size < *actual_size) {
65 *actual_size = 0;
66 return PLDM_ERROR_INVALID_LENGTH;
67 }
68
69 // Encode rest of PDR
70
71 effecter->hdr.version = 1;
72 effecter->hdr.type = PLDM_STATE_EFFECTER_PDR;
73 effecter->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
74
75 memcpy(effecter->possible_states, possible_states,
76 possible_states_size);
77
78 // Convert effecter PDR body
79 HTOLE16(effecter->terminus_handle);
80 HTOLE16(effecter->effecter_id);
81 HTOLE16(effecter->entity_type);
82 HTOLE16(effecter->entity_instance);
83 HTOLE16(effecter->container_id);
84 HTOLE16(effecter->effecter_semantic_id);
85
86 // Convert header
87 HTOLE32(effecter->hdr.record_handle);
88 HTOLE16(effecter->hdr.record_change_num);
89 HTOLE16(effecter->hdr.length);
90
91 return PLDM_SUCCESS;
92}
93
94int encode_state_sensor_pdr(
95 struct pldm_state_sensor_pdr *const sensor, const size_t allocation_size,
96 const struct state_sensor_possible_states *const possible_states,
97 const size_t possible_states_size, size_t *const actual_size)
98{
99 // Encode possible states
100
101 size_t calculated_possible_states_size = 0;
102
103 {
Andrew Jefferyfbe61d72023-04-05 20:28:23 +0930104 char *states_ptr = (char *)possible_states;
105 char *const begin_states_ptr = states_ptr;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930106
107 for (int i = 0; i < sensor->composite_sensor_count; ++i) {
108 struct state_sensor_possible_states *states =
109 (struct state_sensor_possible_states *)states_ptr;
110
111 HTOLE16(states->state_set_id);
112
113 states_ptr +=
114 (sizeof(*states) - sizeof(states->states) +
115 states->possible_states_size);
116 }
117
118 calculated_possible_states_size = states_ptr - begin_states_ptr;
119 }
120
121 // Check lengths
122
123 if (possible_states_size != calculated_possible_states_size) {
124 *actual_size = 0;
125 return PLDM_ERROR;
126 }
127
128 *actual_size = (sizeof(struct pldm_state_sensor_pdr) +
129 possible_states_size - sizeof(sensor->possible_states));
130
131 if (allocation_size < *actual_size) {
132 *actual_size = 0;
133 return PLDM_ERROR_INVALID_LENGTH;
134 }
135
136 // Encode rest of PDR
137
138 sensor->hdr.version = 1;
139 sensor->hdr.type = PLDM_STATE_SENSOR_PDR;
140 sensor->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
141
142 memcpy(sensor->possible_states, possible_states, possible_states_size);
143
144 // Convert sensor PDR body
145 HTOLE16(sensor->terminus_handle);
146 HTOLE16(sensor->sensor_id);
147 HTOLE16(sensor->entity_type);
148 HTOLE16(sensor->entity_instance);
149 HTOLE16(sensor->container_id);
150
151 // Convert header
152 HTOLE32(sensor->hdr.record_handle);
153 HTOLE16(sensor->hdr.record_change_num);
154 HTOLE16(sensor->hdr.length);
155
156 return PLDM_SUCCESS;
157}
158
159int encode_set_state_effecter_states_resp(uint8_t instance_id,
160 uint8_t completion_code,
161 struct pldm_msg *msg)
162{
163 if (msg == NULL) {
164 return PLDM_ERROR_INVALID_DATA;
165 }
166
167 struct pldm_header_info header = {0};
168 header.msg_type = PLDM_RESPONSE;
169 header.instance = instance_id;
170 header.pldm_type = PLDM_PLATFORM;
171 header.command = PLDM_SET_STATE_EFFECTER_STATES;
172
173 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
174 if (rc != PLDM_SUCCESS) {
175 return rc;
176 }
177
178 msg->payload[0] = completion_code;
179
180 return PLDM_SUCCESS;
181}
182
183int encode_set_state_effecter_states_req(uint8_t instance_id,
184 uint16_t effecter_id,
185 uint8_t comp_effecter_count,
186 set_effecter_state_field *field,
187 struct pldm_msg *msg)
188{
189 if (msg == NULL) {
190 return PLDM_ERROR_INVALID_DATA;
191 }
192
193 if (comp_effecter_count < 0x1 || comp_effecter_count > 0x8 ||
194 field == NULL) {
195 return PLDM_ERROR_INVALID_DATA;
196 }
197
198 struct pldm_header_info header = {0};
199 header.msg_type = PLDM_REQUEST;
200 header.instance = instance_id;
201 header.pldm_type = PLDM_PLATFORM;
202 header.command = PLDM_SET_STATE_EFFECTER_STATES;
203
204 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
205 if (rc != PLDM_SUCCESS) {
206 return rc;
207 }
208
209 struct pldm_set_state_effecter_states_req *request =
210 (struct pldm_set_state_effecter_states_req *)msg->payload;
211 effecter_id = htole16(effecter_id);
212 request->effecter_id = effecter_id;
213 request->comp_effecter_count = comp_effecter_count;
214 memcpy(request->field, field,
215 (sizeof(set_effecter_state_field) * comp_effecter_count));
216
217 return PLDM_SUCCESS;
218}
219
220int decode_set_state_effecter_states_resp(const struct pldm_msg *msg,
221 size_t payload_length,
222 uint8_t *completion_code)
223{
224 if (msg == NULL || completion_code == NULL) {
225 return PLDM_ERROR_INVALID_DATA;
226 }
227
228 *completion_code = msg->payload[0];
229 if (PLDM_SUCCESS != *completion_code) {
230 return PLDM_SUCCESS;
231 }
232
233 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES) {
234 return PLDM_ERROR_INVALID_LENGTH;
235 }
236
237 return PLDM_SUCCESS;
238}
239
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930240#define PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE 3
Andrew Jeffery9c766792022-08-10 23:12:49 +0930241int decode_set_state_effecter_states_req(const struct pldm_msg *msg,
242 size_t payload_length,
243 uint16_t *effecter_id,
244 uint8_t *comp_effecter_count,
245 set_effecter_state_field *field)
246{
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930247 struct pldm_msgbuf _buf;
248 struct pldm_msgbuf *buf = &_buf;
249 int rc;
250 int i;
251
Andrew Jeffery9c766792022-08-10 23:12:49 +0930252 if (msg == NULL || effecter_id == NULL || comp_effecter_count == NULL ||
253 field == NULL) {
254 return PLDM_ERROR_INVALID_DATA;
255 }
256
257 if (payload_length > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) {
258 return PLDM_ERROR_INVALID_LENGTH;
259 }
260
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930261 rc = pldm_msgbuf_init(buf, PLDM_SET_STATE_EFFECTER_STATES_MIN_SIZE,
262 msg->payload, payload_length);
263 if (rc) {
264 return rc;
265 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930266
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930267 pldm_msgbuf_extract(buf, effecter_id);
268 pldm_msgbuf_extract(buf, comp_effecter_count);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930269
Andrew Jeffery5d773b32023-04-04 10:52:57 +0930270 if (*comp_effecter_count > 8) {
271 return PLDM_ERROR_INVALID_DATA;
272 }
273
274 for (i = 0; i < *comp_effecter_count; i++) {
275 pldm_msgbuf_extract(buf, &field[i].set_request);
276 pldm_msgbuf_extract(buf, &field[i].effecter_state);
277 }
278
279 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930280}
281
282int decode_get_pdr_req(const struct pldm_msg *msg, size_t payload_length,
283 uint32_t *record_hndl, uint32_t *data_transfer_hndl,
284 uint8_t *transfer_op_flag, uint16_t *request_cnt,
285 uint16_t *record_chg_num)
286{
Andrew Jeffery891781e2023-04-04 11:04:18 +0930287 struct pldm_msgbuf _buf;
288 struct pldm_msgbuf *buf = &_buf;
289 int rc;
290
Andrew Jeffery9c766792022-08-10 23:12:49 +0930291 if (msg == NULL || record_hndl == NULL || data_transfer_hndl == NULL ||
292 transfer_op_flag == NULL || request_cnt == NULL ||
293 record_chg_num == NULL) {
294 return PLDM_ERROR_INVALID_DATA;
295 }
Andrew Jeffery891781e2023-04-04 11:04:18 +0930296
Andrew Jeffery9c766792022-08-10 23:12:49 +0930297 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
298 return PLDM_ERROR_INVALID_LENGTH;
299 }
300
Andrew Jeffery891781e2023-04-04 11:04:18 +0930301 rc = pldm_msgbuf_init(buf, PLDM_GET_PDR_REQ_BYTES, msg->payload,
302 payload_length);
303 if (rc) {
304 return rc;
305 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930306
Andrew Jeffery891781e2023-04-04 11:04:18 +0930307 pldm_msgbuf_extract(buf, record_hndl);
308 pldm_msgbuf_extract(buf, data_transfer_hndl);
309 pldm_msgbuf_extract(buf, transfer_op_flag);
310 pldm_msgbuf_extract(buf, request_cnt);
311 pldm_msgbuf_extract(buf, record_chg_num);
312
313 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930314}
315
316int encode_get_pdr_resp(uint8_t instance_id, uint8_t completion_code,
317 uint32_t next_record_hndl,
318 uint32_t next_data_transfer_hndl, uint8_t transfer_flag,
319 uint16_t resp_cnt, const uint8_t *record_data,
320 uint8_t transfer_crc, struct pldm_msg *msg)
321{
322 if (msg == NULL) {
323 return PLDM_ERROR_INVALID_DATA;
324 }
325
326 struct pldm_header_info header = {0};
327 header.msg_type = PLDM_RESPONSE;
328 header.instance = instance_id;
329 header.pldm_type = PLDM_PLATFORM;
330 header.command = PLDM_GET_PDR;
331
332 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
333 if (rc != PLDM_SUCCESS) {
334 return rc;
335 }
336
337 struct pldm_get_pdr_resp *response =
338 (struct pldm_get_pdr_resp *)msg->payload;
339 response->completion_code = completion_code;
340
341 if (response->completion_code == PLDM_SUCCESS) {
342 response->next_record_handle = htole32(next_record_hndl);
343 response->next_data_transfer_handle =
344 htole32(next_data_transfer_hndl);
345 response->transfer_flag = transfer_flag;
346 response->response_count = htole16(resp_cnt);
347 if (record_data != NULL && resp_cnt > 0) {
348 memcpy(response->record_data, record_data, resp_cnt);
349 }
350 if (transfer_flag == PLDM_END) {
351 uint8_t *dst = msg->payload;
352 dst +=
353 (sizeof(struct pldm_get_pdr_resp) - 1) + resp_cnt;
354 *dst = transfer_crc;
355 }
356 }
357
358 return PLDM_SUCCESS;
359}
360
361int encode_get_pdr_repository_info_resp(
362 uint8_t instance_id, uint8_t completion_code, uint8_t repository_state,
363 const uint8_t *update_time, const uint8_t *oem_update_time,
364 uint32_t record_count, uint32_t repository_size,
365 uint32_t largest_record_size, uint8_t data_transfer_handle_timeout,
366 struct pldm_msg *msg)
367{
368 if (msg == NULL) {
369 return PLDM_ERROR_INVALID_DATA;
370 }
371
372 struct pldm_header_info header = {0};
373 header.msg_type = PLDM_RESPONSE;
374 header.instance = instance_id;
375 header.pldm_type = PLDM_PLATFORM;
376 header.command = PLDM_GET_PDR_REPOSITORY_INFO;
377
378 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
379 if (rc != PLDM_SUCCESS) {
380 return rc;
381 }
382
383 struct pldm_pdr_repository_info_resp *response =
384 (struct pldm_pdr_repository_info_resp *)msg->payload;
385 response->completion_code = completion_code;
386
387 if (response->completion_code == PLDM_SUCCESS) {
388 response->repository_state = repository_state;
389 if (update_time != NULL) {
390 memcpy(response->update_time, update_time,
391 PLDM_TIMESTAMP104_SIZE);
392 }
393 if (oem_update_time != NULL) {
394 memcpy(response->oem_update_time, oem_update_time,
395 PLDM_TIMESTAMP104_SIZE);
396 }
397 response->record_count = htole32(record_count);
398 response->repository_size = htole32(repository_size);
399 response->largest_record_size = htole32(largest_record_size);
400 response->data_transfer_handle_timeout =
401 data_transfer_handle_timeout;
402 }
403
404 return PLDM_SUCCESS;
405}
406
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800407int decode_get_pdr_repository_info_resp(
408 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
409 uint8_t *repository_state, uint8_t *update_time, uint8_t *oem_update_time,
410 uint32_t *record_count, uint32_t *repository_size,
411 uint32_t *largest_record_size, uint8_t *data_transfer_handle_timeout)
412{
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930413 struct pldm_msgbuf _buf;
414 struct pldm_msgbuf *buf = &_buf;
415 int rc;
416
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800417 if (msg == NULL || completion_code == NULL ||
418 repository_state == NULL || update_time == NULL ||
419 oem_update_time == NULL || record_count == NULL ||
420 repository_size == NULL || largest_record_size == NULL ||
421 data_transfer_handle_timeout == NULL) {
422 return PLDM_ERROR_INVALID_DATA;
423 }
424
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930425 rc = pldm_msgbuf_init(buf, PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
426 msg->payload, payload_length);
427 if (rc) {
428 return rc;
429 }
430
431 pldm_msgbuf_extract(buf, completion_code);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800432 if (PLDM_SUCCESS != *completion_code) {
433 return PLDM_SUCCESS;
434 }
435
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930436 pldm_msgbuf_extract(buf, repository_state);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800437 if (*repository_state > PLDM_FAILED) {
438 return PLDM_ERROR_INVALID_DATA;
439 }
440
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930441 pldm_msgbuf_extract_array(buf, update_time, PLDM_TIMESTAMP104_SIZE);
442 pldm_msgbuf_extract_array(buf, oem_update_time, PLDM_TIMESTAMP104_SIZE);
443 pldm_msgbuf_extract(buf, record_count);
444 pldm_msgbuf_extract(buf, repository_size);
445 pldm_msgbuf_extract(buf, largest_record_size);
446 pldm_msgbuf_extract(buf, data_transfer_handle_timeout);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800447
Andrew Jeffery5c651b82023-04-04 11:37:56 +0930448 return pldm_msgbuf_destroy(buf);
Gilbert Chenb7c73e52022-11-10 11:29:52 +0800449}
450
Andrew Jeffery9c766792022-08-10 23:12:49 +0930451int encode_get_pdr_req(uint8_t instance_id, uint32_t record_hndl,
452 uint32_t data_transfer_hndl, uint8_t transfer_op_flag,
453 uint16_t request_cnt, uint16_t record_chg_num,
454 struct pldm_msg *msg, size_t payload_length)
455{
456 if (msg == NULL) {
457 return PLDM_ERROR_INVALID_DATA;
458 }
459
460 if (payload_length != PLDM_GET_PDR_REQ_BYTES) {
461 return PLDM_ERROR_INVALID_LENGTH;
462 }
463
464 struct pldm_header_info header = {0};
465 header.msg_type = PLDM_REQUEST;
466 header.instance = instance_id;
467 header.pldm_type = PLDM_PLATFORM;
468 header.command = PLDM_GET_PDR;
469
470 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
471 if (rc != PLDM_SUCCESS) {
472 return rc;
473 }
474
475 struct pldm_get_pdr_req *request =
476 (struct pldm_get_pdr_req *)msg->payload;
477 request->record_handle = htole32(record_hndl);
478 request->data_transfer_handle = htole32(data_transfer_hndl);
479 request->transfer_op_flag = transfer_op_flag;
480 request->request_count = htole16(request_cnt);
481 request->record_change_number = htole16(record_chg_num);
482
483 return PLDM_SUCCESS;
484}
485
486int decode_get_pdr_resp(const struct pldm_msg *msg, size_t payload_length,
487 uint8_t *completion_code, uint32_t *next_record_hndl,
488 uint32_t *next_data_transfer_hndl,
489 uint8_t *transfer_flag, uint16_t *resp_cnt,
490 uint8_t *record_data, size_t record_data_length,
491 uint8_t *transfer_crc)
492{
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930493 struct pldm_msgbuf _buf;
494 struct pldm_msgbuf *buf = &_buf;
495 int rc;
496
Andrew Jeffery9c766792022-08-10 23:12:49 +0930497 if (msg == NULL || completion_code == NULL ||
498 next_record_hndl == NULL || next_data_transfer_hndl == NULL ||
499 transfer_flag == NULL || resp_cnt == NULL || transfer_crc == NULL) {
500 return PLDM_ERROR_INVALID_DATA;
501 }
502
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930503 rc = pldm_msgbuf_init(buf, PLDM_GET_PDR_MIN_RESP_BYTES, msg->payload,
504 payload_length);
505 if (rc) {
506 return rc;
507 }
508
509 pldm_msgbuf_extract(buf, completion_code);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930510 if (PLDM_SUCCESS != *completion_code) {
511 return PLDM_SUCCESS;
512 }
513
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930514 pldm_msgbuf_extract(buf, next_record_hndl);
515 pldm_msgbuf_extract(buf, next_data_transfer_hndl);
516 pldm_msgbuf_extract(buf, transfer_flag);
517 rc = pldm_msgbuf_extract(buf, resp_cnt);
518 if (rc) {
519 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930520 }
521
522 if (*resp_cnt > 0 && record_data != NULL) {
523 if (record_data_length < *resp_cnt) {
524 return PLDM_ERROR_INVALID_LENGTH;
525 }
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930526 pldm_msgbuf_extract_array(buf, record_data, *resp_cnt);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930527 }
528
529 if (*transfer_flag == PLDM_END) {
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930530 pldm_msgbuf_extract(buf, transfer_crc);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930531 }
532
Andrew Jeffery4e5e8a22023-04-04 11:58:45 +0930533 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930534}
535
536int decode_set_numeric_effecter_value_req(const struct pldm_msg *msg,
537 size_t payload_length,
538 uint16_t *effecter_id,
539 uint8_t *effecter_data_size,
Andrew Jeffery3884c442023-04-12 11:13:24 +0930540 uint8_t effecter_value[4])
Andrew Jeffery9c766792022-08-10 23:12:49 +0930541{
Andrew Jeffery3884c442023-04-12 11:13:24 +0930542 struct pldm_msgbuf _buf;
543 struct pldm_msgbuf *buf = &_buf;
544 int rc;
545
Andrew Jeffery9c766792022-08-10 23:12:49 +0930546 if (msg == NULL || effecter_id == NULL || effecter_data_size == NULL ||
547 effecter_value == NULL) {
548 return PLDM_ERROR_INVALID_DATA;
549 }
550
Andrew Jeffery3884c442023-04-12 11:13:24 +0930551 rc =
552 pldm_msgbuf_init(buf, PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES,
553 msg->payload, payload_length);
554 if (rc) {
555 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930556 }
557
Andrew Jeffery3884c442023-04-12 11:13:24 +0930558 pldm_msgbuf_extract(buf, effecter_id);
559 rc = pldm_msgbuf_extract(buf, effecter_data_size);
560 if (rc) {
561 return PLDM_ERROR_INVALID_DATA;
562 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930563
564 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
565 return PLDM_ERROR_INVALID_DATA;
566 }
567
Andrew Jeffery3884c442023-04-12 11:13:24 +0930568 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
569 effecter_value);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930570
Andrew Jeffery3884c442023-04-12 11:13:24 +0930571 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930572}
573
574int encode_set_numeric_effecter_value_resp(uint8_t instance_id,
575 uint8_t completion_code,
576 struct pldm_msg *msg,
577 size_t payload_length)
578{
579 if (msg == NULL) {
580 return PLDM_ERROR_INVALID_DATA;
581 }
582
583 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
584 return PLDM_ERROR_INVALID_LENGTH;
585 }
586
587 struct pldm_header_info header = {0};
588 header.msg_type = PLDM_RESPONSE;
589 header.instance = instance_id;
590 header.pldm_type = PLDM_PLATFORM;
591 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
592
593 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
594 if (rc != PLDM_SUCCESS) {
595 return rc;
596 }
597
598 msg->payload[0] = completion_code;
599
600 return rc;
601}
602
603int encode_set_numeric_effecter_value_req(
604 uint8_t instance_id, uint16_t effecter_id, uint8_t effecter_data_size,
Andrew Jefferydebe6b32023-04-05 20:30:46 +0930605 const uint8_t *effecter_value, struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930606{
607 if (msg == NULL || effecter_value == NULL) {
608 return PLDM_ERROR_INVALID_DATA;
609 }
610
611 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
612 return PLDM_ERROR_INVALID_DATA;
613 }
614
615 struct pldm_header_info header = {0};
616 header.msg_type = PLDM_REQUEST;
617 header.instance = instance_id;
618 header.pldm_type = PLDM_PLATFORM;
619 header.command = PLDM_SET_NUMERIC_EFFECTER_VALUE;
620
621 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
622 if (rc != PLDM_SUCCESS) {
623 return rc;
624 }
625
626 struct pldm_set_numeric_effecter_value_req *request =
627 (struct pldm_set_numeric_effecter_value_req *)msg->payload;
628 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
629 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
630 if (payload_length !=
631 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES) {
632 return PLDM_ERROR_INVALID_LENGTH;
633 }
634 request->effecter_value[0] = *effecter_value;
635 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
636 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
637 if (payload_length !=
638 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 1) {
639 return PLDM_ERROR_INVALID_LENGTH;
640 }
641
642 uint16_t val = *(uint16_t *)(effecter_value);
643 val = htole16(val);
644 memcpy(request->effecter_value, &val, sizeof(uint16_t));
645
646 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
647 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
648 if (payload_length !=
649 PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES + 3) {
650 return PLDM_ERROR_INVALID_LENGTH;
651 }
652
653 uint32_t val = *(uint32_t *)(effecter_value);
654 val = htole32(val);
655 memcpy(request->effecter_value, &val, sizeof(uint32_t));
656 }
657
658 request->effecter_id = htole16(effecter_id);
659 request->effecter_data_size = effecter_data_size;
660
661 return PLDM_SUCCESS;
662}
663
664int decode_set_numeric_effecter_value_resp(const struct pldm_msg *msg,
665 size_t payload_length,
666 uint8_t *completion_code)
667{
668 if (msg == NULL || completion_code == NULL) {
669 return PLDM_ERROR_INVALID_DATA;
670 }
671
672 if (payload_length != PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES) {
673 return PLDM_ERROR_INVALID_LENGTH;
674 }
675
676 *completion_code = msg->payload[0];
677
678 return PLDM_SUCCESS;
679}
680
681int encode_get_state_sensor_readings_resp(uint8_t instance_id,
682 uint8_t completion_code,
683 uint8_t comp_sensor_count,
684 get_sensor_state_field *field,
685 struct pldm_msg *msg)
686{
687 if (msg == NULL) {
688 return PLDM_ERROR_INVALID_DATA;
689 }
690
691 if (comp_sensor_count < 0x1 || comp_sensor_count > 0x8) {
692 return PLDM_ERROR_INVALID_DATA;
693 }
694
695 struct pldm_header_info header = {0};
696 header.msg_type = PLDM_RESPONSE;
697 header.instance = instance_id;
698 header.pldm_type = PLDM_PLATFORM;
699 header.command = PLDM_GET_STATE_SENSOR_READINGS;
700
701 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
702 if (rc != PLDM_SUCCESS) {
703 return rc;
704 }
705
706 struct pldm_get_state_sensor_readings_resp *response =
707 (struct pldm_get_state_sensor_readings_resp *)msg->payload;
708
709 response->completion_code = completion_code;
710 response->comp_sensor_count = comp_sensor_count;
711 memcpy(response->field, field,
712 (sizeof(get_sensor_state_field) * comp_sensor_count));
713
714 return PLDM_SUCCESS;
715}
716
717int encode_get_state_sensor_readings_req(uint8_t instance_id,
718 uint16_t sensor_id,
719 bitfield8_t sensor_rearm,
720 uint8_t reserved, struct pldm_msg *msg)
721{
722 if (msg == NULL) {
723 return PLDM_ERROR_INVALID_DATA;
724 }
725
726 struct pldm_header_info header = {0};
727 header.msg_type = PLDM_REQUEST;
728 header.instance = instance_id;
729 header.pldm_type = PLDM_PLATFORM;
730 header.command = PLDM_GET_STATE_SENSOR_READINGS;
731
732 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
733 if (rc != PLDM_SUCCESS) {
734 return rc;
735 }
736
737 struct pldm_get_state_sensor_readings_req *request =
738 (struct pldm_get_state_sensor_readings_req *)msg->payload;
739
740 request->sensor_id = htole16(sensor_id);
741 request->reserved = reserved;
742 request->sensor_rearm = sensor_rearm;
743
744 return PLDM_SUCCESS;
745}
746
747int decode_get_state_sensor_readings_resp(const struct pldm_msg *msg,
748 size_t payload_length,
749 uint8_t *completion_code,
750 uint8_t *comp_sensor_count,
751 get_sensor_state_field *field)
752{
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930753 struct pldm_msgbuf _buf;
754 struct pldm_msgbuf *buf = &_buf;
755 uint8_t i;
756 int rc;
757
Andrew Jeffery9c766792022-08-10 23:12:49 +0930758 if (msg == NULL || completion_code == NULL ||
759 comp_sensor_count == NULL || field == NULL) {
760 return PLDM_ERROR_INVALID_DATA;
761 }
762
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930763 rc =
764 pldm_msgbuf_init(buf, PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES,
765 msg->payload, payload_length);
766 if (rc) {
767 return rc;
768 }
769
770 rc = pldm_msgbuf_extract(buf, completion_code);
771 if (rc) {
772 return rc;
773 }
774
Andrew Jeffery9c766792022-08-10 23:12:49 +0930775 if (PLDM_SUCCESS != *completion_code) {
776 return PLDM_SUCCESS;
777 }
778
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930779 rc = pldm_msgbuf_extract(buf, comp_sensor_count);
780 if (rc) {
781 return rc;
782 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930783
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930784 if (*comp_sensor_count < 0x1 || *comp_sensor_count > 0x8) {
Andrew Jeffery9c766792022-08-10 23:12:49 +0930785 return PLDM_ERROR_INVALID_DATA;
786 }
787
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930788 for (i = 0; i < *comp_sensor_count; i++) {
789 pldm_msgbuf_extract(buf, &field[i].sensor_op_state);
790 pldm_msgbuf_extract(buf, &field[i].present_state);
791 pldm_msgbuf_extract(buf, &field[i].previous_state);
792 pldm_msgbuf_extract(buf, &field[i].event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930793 }
794
Andrew Jefferyb0e22a72023-04-12 23:14:36 +0930795 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930796}
797
798int decode_get_state_sensor_readings_req(const struct pldm_msg *msg,
799 size_t payload_length,
800 uint16_t *sensor_id,
801 bitfield8_t *sensor_rearm,
802 uint8_t *reserved)
803{
Andrew Jefferyf75aca62023-04-13 11:27:07 +0930804 struct pldm_msgbuf _buf;
805 struct pldm_msgbuf *buf = &_buf;
806 int rc;
807
Andrew Jeffery9c766792022-08-10 23:12:49 +0930808 if (msg == NULL || sensor_id == NULL || sensor_rearm == NULL) {
809 return PLDM_ERROR_INVALID_DATA;
810 }
811
Andrew Jefferyf75aca62023-04-13 11:27:07 +0930812 rc = pldm_msgbuf_init(buf, PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES,
813 msg->payload, payload_length);
814 if (rc) {
815 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930816 }
817
Andrew Jefferyf75aca62023-04-13 11:27:07 +0930818 pldm_msgbuf_extract(buf, sensor_id);
819 pldm_msgbuf_extract(buf, &sensor_rearm->byte);
820 pldm_msgbuf_extract(buf, reserved);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930821
Andrew Jefferyf75aca62023-04-13 11:27:07 +0930822 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930823}
824
825int encode_sensor_event_data(
826 struct pldm_sensor_event_data *const event_data,
827 const size_t event_data_size, const uint16_t sensor_id,
828 const enum sensor_event_class_states sensor_event_class,
829 const uint8_t sensor_offset, const uint8_t event_state,
830 const uint8_t previous_event_state, size_t *const actual_event_data_size)
831{
832 *actual_event_data_size =
833 (sizeof(*event_data) - sizeof(event_data->event_class) +
834 sizeof(struct pldm_sensor_event_state_sensor_state));
835
836 if (!event_data) {
837 return PLDM_SUCCESS;
838 }
839
840 if (event_data_size < *actual_event_data_size) {
841 *actual_event_data_size = 0;
842 return PLDM_ERROR_INVALID_LENGTH;
843 }
844
845 event_data->sensor_id = htole16(sensor_id);
846 event_data->sensor_event_class_type = sensor_event_class;
847
848 struct pldm_sensor_event_state_sensor_state *const state_data =
849 (struct pldm_sensor_event_state_sensor_state *)
850 event_data->event_class;
851
852 state_data->sensor_offset = sensor_offset;
853 state_data->event_state = event_state;
854 state_data->previous_event_state = previous_event_state;
855
856 return PLDM_SUCCESS;
857}
858
859int decode_platform_event_message_req(const struct pldm_msg *msg,
860 size_t payload_length,
861 uint8_t *format_version, uint8_t *tid,
862 uint8_t *event_class,
863 size_t *event_data_offset)
864{
Andrew Jefferydc48ce32023-04-13 12:01:42 +0930865 struct pldm_msgbuf _buf;
866 struct pldm_msgbuf *buf = &_buf;
867 int rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930868
869 if (msg == NULL || format_version == NULL || tid == NULL ||
870 event_class == NULL || event_data_offset == NULL) {
871 return PLDM_ERROR_INVALID_DATA;
872 }
873
Andrew Jefferydc48ce32023-04-13 12:01:42 +0930874 rc = pldm_msgbuf_init(buf, PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES,
875 msg->payload, payload_length);
876 if (rc) {
877 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930878 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930879
Andrew Jefferydc48ce32023-04-13 12:01:42 +0930880 pldm_msgbuf_extract(buf, format_version);
881 pldm_msgbuf_extract(buf, tid);
882 pldm_msgbuf_extract(buf, event_class);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930883 *event_data_offset =
884 sizeof(*format_version) + sizeof(*tid) + sizeof(*event_class);
885
Andrew Jefferydc48ce32023-04-13 12:01:42 +0930886 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930887}
888
889int encode_platform_event_message_resp(uint8_t instance_id,
890 uint8_t completion_code,
891 uint8_t platform_event_status,
892 struct pldm_msg *msg)
893{
894 if (msg == NULL) {
895 return PLDM_ERROR_INVALID_DATA;
896 }
897
898 if (platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
899 return PLDM_ERROR_INVALID_DATA;
900 }
901
902 struct pldm_header_info header = {0};
903 header.msg_type = PLDM_RESPONSE;
904 header.instance = instance_id;
905 header.pldm_type = PLDM_PLATFORM;
906 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
907
908 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
909 if (rc != PLDM_SUCCESS) {
910 return rc;
911 }
912
913 struct pldm_platform_event_message_resp *response =
914 (struct pldm_platform_event_message_resp *)msg->payload;
915 response->completion_code = completion_code;
916 response->platform_event_status = platform_event_status;
917
918 return PLDM_SUCCESS;
919}
920
921int encode_platform_event_message_req(
922 uint8_t instance_id, uint8_t format_version, uint8_t tid,
923 uint8_t event_class, const uint8_t *event_data, size_t event_data_length,
924 struct pldm_msg *msg, size_t payload_length)
925
926{
927 if (format_version != 1) {
928 return PLDM_ERROR_INVALID_DATA;
929 }
930
931 if (msg == NULL || event_data == NULL) {
932 return PLDM_ERROR_INVALID_DATA;
933 }
934
935 if (event_data_length == 0) {
936 return PLDM_ERROR_INVALID_DATA;
937 }
938
939 if (payload_length !=
940 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + event_data_length) {
941 return PLDM_ERROR_INVALID_LENGTH;
942 }
943
944 if (event_class > PLDM_HEARTBEAT_TIMER_ELAPSED_EVENT &&
945 !(event_class >= 0xF0 && event_class <= 0xFE)) {
946 return PLDM_ERROR_INVALID_DATA;
947 }
948
949 struct pldm_header_info header = {0};
950 header.msg_type = PLDM_REQUEST;
951 header.instance = instance_id;
952 header.pldm_type = PLDM_PLATFORM;
953 header.command = PLDM_PLATFORM_EVENT_MESSAGE;
954
955 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
956 if (rc != PLDM_SUCCESS) {
957 return rc;
958 }
959
960 struct pldm_platform_event_message_req *request =
961 (struct pldm_platform_event_message_req *)msg->payload;
962 request->format_version = format_version;
963 request->tid = tid;
964 request->event_class = event_class;
965 memcpy(request->event_data, event_data, event_data_length);
966
967 return PLDM_SUCCESS;
968}
969
970int decode_platform_event_message_resp(const struct pldm_msg *msg,
971 size_t payload_length,
972 uint8_t *completion_code,
973 uint8_t *platform_event_status)
974{
Andrew Jefferye5011772023-04-13 12:06:22 +0930975 struct pldm_msgbuf _buf;
976 struct pldm_msgbuf *buf = &_buf;
977 int rc;
978
Andrew Jeffery9c766792022-08-10 23:12:49 +0930979 if (msg == NULL || completion_code == NULL ||
980 platform_event_status == NULL) {
981 return PLDM_ERROR_INVALID_DATA;
982 }
983
Andrew Jefferye5011772023-04-13 12:06:22 +0930984 rc = pldm_msgbuf_init(buf, PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES,
985 msg->payload, payload_length);
986 if (rc) {
987 return rc;
988 }
989
990 rc = pldm_msgbuf_extract(buf, completion_code);
991 if (rc) {
992 return rc;
993 }
994
Andrew Jeffery9c766792022-08-10 23:12:49 +0930995 if (PLDM_SUCCESS != *completion_code) {
996 return PLDM_SUCCESS;
997 }
Andrew Jeffery9c766792022-08-10 23:12:49 +0930998
Andrew Jefferye5011772023-04-13 12:06:22 +0930999 rc = pldm_msgbuf_extract(buf, platform_event_status);
1000 if (rc) {
1001 return rc;
1002 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301003
1004 if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
1005 return PLDM_ERROR_INVALID_DATA;
1006 }
1007
Andrew Jefferye5011772023-04-13 12:06:22 +09301008 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301009}
1010
Dung Caod6ae8982022-11-02 10:00:10 +07001011int encode_event_message_buffer_size_req(
1012 uint8_t instance_id, uint16_t event_receiver_max_buffer_size,
1013 struct pldm_msg *msg)
1014{
1015 struct pldm_header_info header = {0};
1016 header.msg_type = PLDM_REQUEST;
1017 header.instance = instance_id;
1018 header.pldm_type = PLDM_PLATFORM;
1019 header.command = PLDM_EVENT_MESSAGE_BUFFER_SIZE;
1020
1021 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1022 if (rc != PLDM_SUCCESS) {
1023 return rc;
1024 }
1025
1026 struct pldm_event_message_buffer_size_req *request =
1027 (struct pldm_event_message_buffer_size_req *)msg->payload;
1028 request->event_receiver_max_buffer_size =
1029 event_receiver_max_buffer_size;
1030
1031 return PLDM_SUCCESS;
1032}
1033
1034int decode_event_message_buffer_size_resp(const struct pldm_msg *msg,
1035 size_t payload_length,
1036 uint8_t *completion_code,
1037 uint16_t *terminus_max_buffer_size)
1038{
Andrew Jeffery11126902023-04-13 12:12:10 +09301039 struct pldm_msgbuf _buf;
1040 struct pldm_msgbuf *buf = &_buf;
1041 int rc;
1042
Dung Caod6ae8982022-11-02 10:00:10 +07001043 if (msg == NULL || completion_code == NULL ||
1044 terminus_max_buffer_size == NULL) {
1045 return PLDM_ERROR_INVALID_DATA;
1046 }
1047
Andrew Jeffery11126902023-04-13 12:12:10 +09301048 rc = pldm_msgbuf_init(buf, PLDM_EVENT_MESSAGE_BUFFER_SIZE_RESP_BYTES,
1049 msg->payload, payload_length);
1050 if (rc) {
1051 return rc;
1052 }
1053
1054 rc = pldm_msgbuf_extract(buf, completion_code);
1055 if (rc) {
1056 return rc;
1057 }
1058
Dung Caod6ae8982022-11-02 10:00:10 +07001059 if (PLDM_SUCCESS != *completion_code) {
1060 return PLDM_SUCCESS;
1061 }
Dung Caod6ae8982022-11-02 10:00:10 +07001062
Andrew Jeffery11126902023-04-13 12:12:10 +09301063 pldm_msgbuf_extract(buf, terminus_max_buffer_size);
Dung Caod6ae8982022-11-02 10:00:10 +07001064
Andrew Jeffery11126902023-04-13 12:12:10 +09301065 return pldm_msgbuf_destroy_consumed(buf);
Dung Caod6ae8982022-11-02 10:00:10 +07001066}
1067
Dung Cao1bf8c872022-11-29 05:32:58 +07001068int encode_event_message_supported_req(uint8_t instance_id,
1069 uint8_t format_version,
1070 struct pldm_msg *msg)
1071{
1072 if (format_version != 1) {
1073 return PLDM_ERROR_INVALID_DATA;
1074 }
1075
1076 if (msg == NULL) {
1077 return PLDM_ERROR_INVALID_DATA;
1078 }
1079
1080 struct pldm_header_info header = {0};
1081 header.msg_type = PLDM_REQUEST;
1082 header.instance = instance_id;
1083 header.pldm_type = PLDM_PLATFORM;
1084 header.command = PLDM_EVENT_MESSAGE_SUPPORTED;
1085
1086 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1087 if (rc != PLDM_SUCCESS) {
1088 return rc;
1089 }
1090
1091 struct pldm_event_message_supported_req *request =
1092 (struct pldm_event_message_supported_req *)msg->payload;
1093 request->format_version = format_version;
1094
1095 return PLDM_SUCCESS;
1096}
1097
1098int decode_event_message_supported_resp(
1099 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
1100 uint8_t *synchrony_config, bitfield8_t *synchrony_config_support,
1101 uint8_t *number_event_class_returned, uint8_t *event_class,
1102 uint8_t event_class_count)
1103{
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301104 struct pldm_msgbuf _buf;
1105 struct pldm_msgbuf *buf = &_buf;
1106 int i;
1107 int rc;
1108
Dung Cao1bf8c872022-11-29 05:32:58 +07001109 if (msg == NULL || completion_code == NULL ||
1110 synchrony_config == NULL || synchrony_config_support == NULL ||
1111 number_event_class_returned == NULL || event_class == NULL) {
1112 return PLDM_ERROR_INVALID_DATA;
1113 }
1114
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301115 rc = pldm_msgbuf_init(buf, PLDM_EVENT_MESSAGE_SUPPORTED_MIN_RESP_BYTES,
1116 msg->payload, payload_length);
1117 if (rc) {
1118 return rc;
1119 }
1120
1121 rc = pldm_msgbuf_extract(buf, completion_code);
1122 if (rc) {
1123 return rc;
1124 }
1125
Dung Cao1bf8c872022-11-29 05:32:58 +07001126 if (PLDM_SUCCESS != *completion_code) {
1127 return PLDM_SUCCESS;
1128 }
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301129
1130 rc = pldm_msgbuf_extract(buf, synchrony_config);
1131 if (rc) {
1132 return rc;
Dung Cao1bf8c872022-11-29 05:32:58 +07001133 }
1134
Dung Cao1bf8c872022-11-29 05:32:58 +07001135 if (*synchrony_config > PLDM_MESSAGE_TYPE_ASYNCHRONOUS_WITH_HEARTBEAT) {
1136 return PLDM_ERROR_INVALID_DATA;
1137 }
1138
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301139 pldm_msgbuf_extract(buf, &synchrony_config_support->byte);
Dung Cao1bf8c872022-11-29 05:32:58 +07001140
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301141 rc = pldm_msgbuf_extract(buf, number_event_class_returned);
1142 if (rc) {
1143 return rc;
Dung Cao1bf8c872022-11-29 05:32:58 +07001144 }
1145
Andrew Jeffery2d00ff82023-04-13 12:34:27 +09301146 if (*number_event_class_returned == 0) {
1147 return pldm_msgbuf_destroy(buf);
1148 }
1149
1150 if (event_class_count < *number_event_class_returned) {
1151 return PLDM_ERROR_INVALID_LENGTH;
1152 }
1153
1154 for (i = 0; i < *number_event_class_returned; i++) {
1155 pldm_msgbuf_extract(buf, &event_class[i]);
1156 }
1157
1158 return pldm_msgbuf_destroy_consumed(buf);
Dung Cao1bf8c872022-11-29 05:32:58 +07001159}
1160
Andrew Jeffery9c766792022-08-10 23:12:49 +09301161int decode_sensor_event_data(const uint8_t *event_data,
1162 size_t event_data_length, uint16_t *sensor_id,
1163 uint8_t *sensor_event_class_type,
1164 size_t *event_class_data_offset)
1165{
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301166 struct pldm_msgbuf _buf;
1167 struct pldm_msgbuf *buf = &_buf;
1168 int rc;
1169
1170 rc = pldm_msgbuf_init(buf, PLDM_SENSOR_EVENT_DATA_MIN_LENGTH,
1171 event_data, event_data_length);
1172 if (rc) {
1173 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301174 }
1175
1176 size_t event_class_data_length =
1177 event_data_length - PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES;
1178
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301179 pldm_msgbuf_extract(buf, sensor_id);
1180 rc = pldm_msgbuf_extract(buf, sensor_event_class_type);
1181 if (rc) {
1182 return rc;
1183 }
1184
1185 if (*sensor_event_class_type == PLDM_SENSOR_OP_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301186 if (event_class_data_length !=
1187 PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
1188 return PLDM_ERROR_INVALID_LENGTH;
1189 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301190 } else if (*sensor_event_class_type == PLDM_STATE_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301191 if (event_class_data_length !=
1192 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
1193 return PLDM_ERROR_INVALID_LENGTH;
1194 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301195 } else if (*sensor_event_class_type == PLDM_NUMERIC_SENSOR_STATE) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301196 if (event_class_data_length <
1197 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
1198 event_class_data_length >
1199 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
1200 return PLDM_ERROR_INVALID_LENGTH;
1201 }
1202 } else {
1203 return PLDM_ERROR_INVALID_DATA;
1204 }
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301205
Andrew Jeffery9c766792022-08-10 23:12:49 +09301206 *event_class_data_offset =
1207 sizeof(*sensor_id) + sizeof(*sensor_event_class_type);
Andrew Jeffery4fd45952023-04-13 13:01:45 +09301208
1209 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301210}
1211
1212int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length,
1213 uint8_t *present_op_state, uint8_t *previous_op_state)
1214{
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301215 struct pldm_msgbuf _buf;
1216 struct pldm_msgbuf *buf = &_buf;
1217 int rc;
1218
1219 if (present_op_state == NULL || previous_op_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301220 return PLDM_ERROR_INVALID_DATA;
1221 }
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301222
1223 rc =
1224 pldm_msgbuf_init(buf, PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH,
1225 sensor_data, sensor_data_length);
1226 if (rc) {
1227 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301228 }
1229
Andrew Jeffery4888ee52023-04-13 13:14:05 +09301230 pldm_msgbuf_extract(buf, present_op_state);
1231 pldm_msgbuf_extract(buf, previous_op_state);
1232
1233 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301234}
1235
1236int decode_state_sensor_data(const uint8_t *sensor_data,
1237 size_t sensor_data_length, uint8_t *sensor_offset,
1238 uint8_t *event_state,
1239 uint8_t *previous_event_state)
1240{
Andrew Jeffery422790b2023-04-13 15:03:47 +09301241 struct pldm_msgbuf _buf;
1242 struct pldm_msgbuf *buf = &_buf;
1243 int rc;
1244
1245 if (sensor_offset == NULL || event_state == NULL ||
1246 previous_event_state == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301247 return PLDM_ERROR_INVALID_DATA;
1248 }
Andrew Jeffery422790b2023-04-13 15:03:47 +09301249
1250 rc = pldm_msgbuf_init(buf,
1251 PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH,
1252 sensor_data, sensor_data_length);
1253 if (rc) {
1254 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301255 }
1256
Andrew Jeffery422790b2023-04-13 15:03:47 +09301257 pldm_msgbuf_extract(buf, sensor_offset);
1258 pldm_msgbuf_extract(buf, event_state);
1259 pldm_msgbuf_extract(buf, previous_event_state);
1260
1261 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301262}
1263
1264int decode_numeric_sensor_data(const uint8_t *sensor_data,
1265 size_t sensor_data_length, uint8_t *event_state,
1266 uint8_t *previous_event_state,
1267 uint8_t *sensor_data_size,
1268 uint32_t *present_reading)
1269{
Andrew Jeffery155317e2023-04-13 18:36:51 +09301270 struct pldm_msgbuf _buf;
1271 struct pldm_msgbuf *buf = &_buf;
1272 int rc;
1273
1274 if (sensor_data_size == NULL || event_state == NULL ||
1275 previous_event_state == NULL || present_reading == NULL) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301276 return PLDM_ERROR_INVALID_DATA;
1277 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301278
1279 if (sensor_data_length >
1280 PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301281 return PLDM_ERROR_INVALID_LENGTH;
1282 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301283
Andrew Jeffery155317e2023-04-13 18:36:51 +09301284 rc = pldm_msgbuf_init(
1285 buf, PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH,
1286 sensor_data, sensor_data_length);
1287 if (rc) {
1288 return rc;
1289 }
1290
1291 pldm_msgbuf_extract(buf, event_state);
1292 pldm_msgbuf_extract(buf, previous_event_state);
1293 rc = pldm_msgbuf_extract(buf, sensor_data_size);
1294 if (rc) {
1295 return rc;
1296 }
1297
1298 /*
1299 * The implementation below is bonkers, but it's because the function
1300 * prototype is bonkers. The `present_reading` argument should have been
1301 * a tagged union.
1302 */
Andrew Jeffery9c766792022-08-10 23:12:49 +09301303 switch (*sensor_data_size) {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301304 case PLDM_SENSOR_DATA_SIZE_UINT8: {
1305 uint8_t val;
1306 if (!pldm_msgbuf_extract(buf, &val)) {
1307 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301308 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301309 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301310 }
1311 case PLDM_SENSOR_DATA_SIZE_SINT8: {
1312 int8_t val;
1313 if (!pldm_msgbuf_extract(buf, &val)) {
1314 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301315 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301316 break;
Andrew Jeffery155317e2023-04-13 18:36:51 +09301317 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301318 case PLDM_SENSOR_DATA_SIZE_UINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301319 uint16_t val;
1320 if (!pldm_msgbuf_extract(buf, &val)) {
1321 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301322 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301323 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301324 }
1325 case PLDM_SENSOR_DATA_SIZE_SINT16: {
Andrew Jeffery155317e2023-04-13 18:36:51 +09301326 int16_t val;
1327 if (!pldm_msgbuf_extract(buf, &val)) {
1328 *present_reading = (uint32_t)(int32_t)val;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301329 }
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301330 break;
1331 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301332 case PLDM_SENSOR_DATA_SIZE_UINT32: {
1333 uint32_t val;
1334 if (!pldm_msgbuf_extract(buf, &val)) {
1335 *present_reading = (uint32_t)val;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301336 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301337 break;
1338 }
1339 case PLDM_SENSOR_DATA_SIZE_SINT32: {
1340 int32_t val;
1341 if (!pldm_msgbuf_extract(buf, &val)) {
1342 *present_reading = (uint32_t)val;
1343 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301344 break;
Andrew Jeffery92f6c3c2023-04-13 15:50:10 +09301345 }
Andrew Jeffery9c766792022-08-10 23:12:49 +09301346 default:
1347 return PLDM_ERROR_INVALID_DATA;
1348 }
Andrew Jeffery155317e2023-04-13 18:36:51 +09301349
1350 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301351}
1352
Andrew Jeffery7992eb82023-04-06 16:13:53 +09301353#define PLDM_NUMERIC_SENSOR_VALUE_PDR_MIN_SIZE 69
1354int decode_numeric_sensor_pdr_data(
1355 const void *pdr_data, size_t pdr_data_length,
1356 struct pldm_numeric_sensor_value_pdr *pdr_value)
1357{
1358 struct pldm_msgbuf _buf;
1359 struct pldm_msgbuf *buf = &_buf;
1360 int rc;
1361
1362 rc = pldm_msgbuf_init(buf, PLDM_NUMERIC_SENSOR_VALUE_PDR_MIN_SIZE,
1363 pdr_data, pdr_data_length);
1364 if (rc) {
1365 return rc;
1366 }
1367
1368 rc = pldm_msgbuf_extract_value_pdr_hdr(buf, &pdr_value->hdr);
1369 if (rc) {
1370 return rc;
1371 }
1372
1373 rc = pldm_platform_pdr_hdr_validate(
1374 &pdr_value->hdr, PLDM_NUMERIC_SENSOR_VALUE_PDR_MIN_SIZE,
1375 pdr_data_length);
1376 if (rc) {
1377 return rc;
1378 }
1379
1380 pldm_msgbuf_extract(buf, &pdr_value->terminus_handle);
1381 pldm_msgbuf_extract(buf, &pdr_value->sensor_id);
1382 pldm_msgbuf_extract(buf, &pdr_value->entity_type);
1383 pldm_msgbuf_extract(buf, &pdr_value->entity_instance_num);
1384 pldm_msgbuf_extract(buf, &pdr_value->container_id);
1385 pldm_msgbuf_extract(buf, &pdr_value->sensor_init);
1386 pldm_msgbuf_extract(buf, &pdr_value->sensor_auxiliary_names_pdr);
1387 pldm_msgbuf_extract(buf, &pdr_value->base_unit);
1388 pldm_msgbuf_extract(buf, &pdr_value->unit_modifier);
1389 pldm_msgbuf_extract(buf, &pdr_value->rate_unit);
1390 pldm_msgbuf_extract(buf, &pdr_value->base_oem_unit_handle);
1391 pldm_msgbuf_extract(buf, &pdr_value->aux_unit);
1392 pldm_msgbuf_extract(buf, &pdr_value->aux_unit_modifier);
1393 pldm_msgbuf_extract(buf, &pdr_value->aux_rate_unit);
1394 pldm_msgbuf_extract(buf, &pdr_value->rel);
1395 pldm_msgbuf_extract(buf, &pdr_value->aux_oem_unit_handle);
1396 pldm_msgbuf_extract(buf, &pdr_value->is_linear);
1397
1398 rc = pldm_msgbuf_extract(buf, &pdr_value->sensor_data_size);
1399 if (rc) {
1400 return rc;
1401 }
1402 if (pdr_value->sensor_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
1403 return PLDM_ERROR_INVALID_DATA;
1404 }
1405
1406 pldm_msgbuf_extract(buf, &pdr_value->resolution);
1407 pldm_msgbuf_extract(buf, &pdr_value->offset);
1408 pldm_msgbuf_extract(buf, &pdr_value->accuracy);
1409 pldm_msgbuf_extract(buf, &pdr_value->plus_tolerance);
1410 pldm_msgbuf_extract(buf, &pdr_value->minus_tolerance);
1411 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1412 &pdr_value->hysteresis);
1413 pldm_msgbuf_extract(buf, &pdr_value->supported_thresholds.byte);
1414 pldm_msgbuf_extract(
1415 buf, &pdr_value->threshold_and_hysteresis_volatility.byte);
1416 pldm_msgbuf_extract(buf, &pdr_value->state_transition_interval);
1417 pldm_msgbuf_extract(buf, &pdr_value->update_interval);
1418 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1419 &pdr_value->max_readable);
1420 pldm_msgbuf_extract_sensor_data(buf, pdr_value->sensor_data_size,
1421 &pdr_value->min_readable);
1422
1423 rc = pldm_msgbuf_extract(buf, &pdr_value->range_field_format);
1424 if (rc) {
1425 return rc;
1426 }
1427 if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
1428 return PLDM_ERROR_INVALID_DATA;
1429 }
1430
1431 pldm_msgbuf_extract(buf, &pdr_value->range_field_support.byte);
1432 pldm_msgbuf_extract_range_field_format(
1433 buf, pdr_value->range_field_format, &pdr_value->nominal_value);
1434 pldm_msgbuf_extract_range_field_format(
1435 buf, pdr_value->range_field_format, &pdr_value->normal_max);
1436 pldm_msgbuf_extract_range_field_format(
1437 buf, pdr_value->range_field_format, &pdr_value->normal_min);
1438 pldm_msgbuf_extract_range_field_format(
1439 buf, pdr_value->range_field_format, &pdr_value->warning_high);
1440 pldm_msgbuf_extract_range_field_format(
1441 buf, pdr_value->range_field_format, &pdr_value->warning_low);
1442 pldm_msgbuf_extract_range_field_format(
1443 buf, pdr_value->range_field_format, &pdr_value->critical_high);
1444 pldm_msgbuf_extract_range_field_format(
1445 buf, pdr_value->range_field_format, &pdr_value->critical_low);
1446 pldm_msgbuf_extract_range_field_format(
1447 buf, pdr_value->range_field_format, &pdr_value->fatal_high);
1448 pldm_msgbuf_extract_range_field_format(
1449 buf, pdr_value->range_field_format, &pdr_value->fatal_low);
1450
1451 return pldm_msgbuf_destroy(buf);
1452}
1453
Andrew Jeffery9c766792022-08-10 23:12:49 +09301454int encode_get_numeric_effecter_value_req(uint8_t instance_id,
1455 uint16_t effecter_id,
1456 struct pldm_msg *msg)
1457{
1458 if (msg == NULL) {
1459 return PLDM_ERROR_INVALID_DATA;
1460 }
1461
1462 struct pldm_header_info header = {0};
1463 header.msg_type = PLDM_REQUEST;
1464 header.instance = instance_id;
1465 header.pldm_type = PLDM_PLATFORM;
1466 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1467
1468 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1469 if (rc != PLDM_SUCCESS) {
1470 return rc;
1471 }
1472
1473 struct pldm_get_numeric_effecter_value_req *request =
1474 (struct pldm_get_numeric_effecter_value_req *)msg->payload;
1475 request->effecter_id = htole16(effecter_id);
1476
1477 return PLDM_SUCCESS;
1478}
1479
1480int encode_get_numeric_effecter_value_resp(
1481 uint8_t instance_id, uint8_t completion_code, uint8_t effecter_data_size,
Andrew Jefferydebe6b32023-04-05 20:30:46 +09301482 uint8_t effecter_oper_state, const uint8_t *pending_value,
1483 const uint8_t *present_value, struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301484{
1485 if (msg == NULL || pending_value == NULL || present_value == NULL) {
1486 return PLDM_ERROR_INVALID_DATA;
1487 }
1488
1489 if (effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1490 return PLDM_ERROR_INVALID_DATA;
1491 }
1492
1493 if (effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1494 return PLDM_ERROR_INVALID_DATA;
1495 }
1496
1497 struct pldm_header_info header = {0};
1498 header.msg_type = PLDM_RESPONSE;
1499 header.instance = instance_id;
1500 header.pldm_type = PLDM_PLATFORM;
1501 header.command = PLDM_GET_NUMERIC_EFFECTER_VALUE;
1502
1503 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1504 if (rc != PLDM_SUCCESS) {
1505 return rc;
1506 }
1507
1508 struct pldm_get_numeric_effecter_value_resp *response =
1509 (struct pldm_get_numeric_effecter_value_resp *)msg->payload;
1510
1511 response->completion_code = completion_code;
1512 response->effecter_data_size = effecter_data_size;
1513 response->effecter_oper_state = effecter_oper_state;
1514
1515 if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1516 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1517 if (payload_length !=
1518 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES) {
1519 return PLDM_ERROR_INVALID_LENGTH;
1520 }
1521 response->pending_and_present_values[0] = *pending_value;
1522 response->pending_and_present_values[1] = *present_value;
1523
1524 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1525 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1526 if (payload_length !=
1527 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 2) {
1528 return PLDM_ERROR_INVALID_LENGTH;
1529 }
1530 uint16_t val_pending = *(uint16_t *)pending_value;
1531 val_pending = htole16(val_pending);
1532 memcpy(response->pending_and_present_values, &val_pending,
1533 sizeof(uint16_t));
1534 uint16_t val_present = *(uint16_t *)present_value;
1535 val_present = htole16(val_present);
1536 memcpy(
1537 (response->pending_and_present_values + sizeof(uint16_t)),
1538 &val_present, sizeof(uint16_t));
1539
1540 } else if (effecter_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1541 effecter_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1542 if (payload_length !=
1543 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES + 6) {
1544 return PLDM_ERROR_INVALID_LENGTH;
1545 }
1546 uint32_t val_pending = *(uint32_t *)pending_value;
1547 val_pending = htole32(val_pending);
1548 memcpy(response->pending_and_present_values, &val_pending,
1549 sizeof(uint32_t));
1550 uint32_t val_present = *(uint32_t *)present_value;
1551 val_present = htole32(val_present);
1552 memcpy(
1553 (response->pending_and_present_values + sizeof(uint32_t)),
1554 &val_present, sizeof(uint32_t));
1555 }
1556 return PLDM_SUCCESS;
1557}
1558
1559int decode_get_numeric_effecter_value_req(const struct pldm_msg *msg,
1560 size_t payload_length,
1561 uint16_t *effecter_id)
1562{
Andrew Jefferydd265822023-04-13 22:42:44 +09301563 struct pldm_msgbuf _buf;
1564 struct pldm_msgbuf *buf = &_buf;
1565 int rc;
1566
Andrew Jeffery9c766792022-08-10 23:12:49 +09301567 if (msg == NULL || effecter_id == NULL) {
1568 return PLDM_ERROR_INVALID_DATA;
1569 }
1570
Andrew Jefferydd265822023-04-13 22:42:44 +09301571 rc = pldm_msgbuf_init(buf, PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES,
1572 msg->payload, payload_length);
1573 if (rc) {
1574 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301575 }
1576
Andrew Jefferydd265822023-04-13 22:42:44 +09301577 pldm_msgbuf_extract(buf, effecter_id);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301578
Andrew Jefferydd265822023-04-13 22:42:44 +09301579 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301580}
1581
1582int decode_get_numeric_effecter_value_resp(
1583 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
1584 uint8_t *effecter_data_size, uint8_t *effecter_oper_state,
1585 uint8_t *pending_value, uint8_t *present_value)
1586{
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301587 struct pldm_msgbuf _buf;
1588 struct pldm_msgbuf *buf = &_buf;
1589 int rc;
1590
Andrew Jeffery9c766792022-08-10 23:12:49 +09301591 if (msg == NULL || effecter_data_size == NULL ||
1592 effecter_oper_state == NULL || pending_value == NULL ||
1593 present_value == NULL) {
1594 return PLDM_ERROR_INVALID_DATA;
1595 }
1596
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301597 rc = pldm_msgbuf_init(buf,
1598 PLDM_GET_NUMERIC_EFFECTER_VALUE_MIN_RESP_BYTES,
1599 msg->payload, payload_length);
1600 if (rc) {
1601 return rc;
1602 }
1603
1604 rc = pldm_msgbuf_extract(buf, completion_code);
1605 if (rc) {
1606 return rc;
1607 }
1608
Andrew Jeffery9c766792022-08-10 23:12:49 +09301609 if (PLDM_SUCCESS != *completion_code) {
1610 return PLDM_SUCCESS;
1611 }
1612
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301613 rc = pldm_msgbuf_extract(buf, effecter_data_size);
1614 if (rc) {
1615 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301616 }
1617
Andrew Jeffery9c766792022-08-10 23:12:49 +09301618 if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1619 return PLDM_ERROR_INVALID_DATA;
1620 }
1621
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301622 rc = pldm_msgbuf_extract(buf, effecter_oper_state);
1623 if (rc) {
1624 return rc;
1625 }
1626
Andrew Jeffery9c766792022-08-10 23:12:49 +09301627 if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
1628 return PLDM_ERROR_INVALID_DATA;
1629 }
1630
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301631 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
1632 pending_value);
1633 pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
1634 present_value);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301635
Andrew Jeffery99c03f32023-04-13 22:45:30 +09301636 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301637}
1638
1639int encode_pldm_pdr_repository_chg_event_data(
1640 uint8_t event_data_format, uint8_t number_of_change_records,
1641 const uint8_t *event_data_operations,
1642 const uint8_t *numbers_of_change_entries,
1643 const uint32_t *const *change_entries,
1644 struct pldm_pdr_repository_chg_event_data *event_data,
1645 size_t *actual_change_records_size, size_t max_change_records_size)
1646{
1647 if (event_data_operations == NULL ||
1648 numbers_of_change_entries == NULL || change_entries == NULL) {
1649 return PLDM_ERROR_INVALID_DATA;
1650 }
1651
1652 size_t expected_size =
1653 sizeof(event_data_format) + sizeof(number_of_change_records);
1654
1655 expected_size +=
1656 sizeof(*event_data_operations) * number_of_change_records;
1657 expected_size +=
1658 sizeof(*numbers_of_change_entries) * number_of_change_records;
1659
1660 for (uint8_t i = 0; i < number_of_change_records; ++i) {
1661 expected_size +=
1662 sizeof(*change_entries[0]) * numbers_of_change_entries[i];
1663 }
1664
1665 *actual_change_records_size = expected_size;
1666
1667 if (event_data == NULL) {
1668 return PLDM_SUCCESS;
1669 }
1670
1671 if (max_change_records_size < expected_size) {
1672 return PLDM_ERROR_INVALID_LENGTH;
1673 }
1674
1675 event_data->event_data_format = event_data_format;
1676 event_data->number_of_change_records = number_of_change_records;
1677
1678 struct pldm_pdr_repository_change_record_data *record_data =
1679 (struct pldm_pdr_repository_change_record_data *)
1680 event_data->change_records;
1681
1682 for (uint8_t i = 0; i < number_of_change_records; ++i) {
1683 record_data->event_data_operation = event_data_operations[i];
1684 record_data->number_of_change_entries =
1685 numbers_of_change_entries[i];
1686
1687 for (uint8_t j = 0; j < record_data->number_of_change_entries;
1688 ++j) {
1689 record_data->change_entry[j] =
1690 htole32(change_entries[i][j]);
1691 }
1692
1693 record_data = (struct pldm_pdr_repository_change_record_data
1694 *)(record_data->change_entry +
1695 record_data->number_of_change_entries);
1696 }
1697
1698 return PLDM_SUCCESS;
1699}
1700
1701int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data,
1702 size_t event_data_size,
1703 uint8_t *event_data_format,
1704 uint8_t *number_of_change_records,
1705 size_t *change_record_data_offset)
1706{
Andrew Jeffery2fe70122023-04-13 23:21:31 +09301707 struct pldm_msgbuf _buf;
1708 struct pldm_msgbuf *buf = &_buf;
1709 int rc;
1710
1711 if (event_data_format == NULL || number_of_change_records == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09301712 change_record_data_offset == NULL) {
1713 return PLDM_ERROR_INVALID_DATA;
1714 }
Andrew Jeffery2fe70122023-04-13 23:21:31 +09301715
1716 rc = pldm_msgbuf_init(buf, PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH,
1717 event_data, event_data_size);
1718 if (rc) {
1719 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301720 }
1721
Andrew Jeffery2fe70122023-04-13 23:21:31 +09301722 pldm_msgbuf_extract(buf, event_data_format);
1723 pldm_msgbuf_extract(buf, number_of_change_records);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301724
Andrew Jeffery9c766792022-08-10 23:12:49 +09301725 *change_record_data_offset =
1726 sizeof(*event_data_format) + sizeof(*number_of_change_records);
1727
Andrew Jeffery2fe70122023-04-13 23:21:31 +09301728 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301729}
1730
1731int decode_pldm_pdr_repository_change_record_data(
1732 const uint8_t *change_record_data, size_t change_record_data_size,
1733 uint8_t *event_data_operation, uint8_t *number_of_change_entries,
1734 size_t *change_entry_data_offset)
1735{
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09301736 struct pldm_msgbuf _buf;
1737 struct pldm_msgbuf *buf = &_buf;
1738 int rc;
1739
1740 if (event_data_operation == NULL || number_of_change_entries == NULL ||
Andrew Jeffery9c766792022-08-10 23:12:49 +09301741 change_entry_data_offset == NULL) {
1742 return PLDM_ERROR_INVALID_DATA;
1743 }
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09301744
1745 rc = pldm_msgbuf_init(buf, PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH,
1746 change_record_data, change_record_data_size);
1747 if (rc) {
1748 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301749 }
1750
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09301751 pldm_msgbuf_extract(buf, event_data_operation);
1752 pldm_msgbuf_extract(buf, number_of_change_entries);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301753
Andrew Jeffery9c766792022-08-10 23:12:49 +09301754 *change_entry_data_offset =
1755 sizeof(*event_data_operation) + sizeof(*number_of_change_entries);
1756
Andrew Jeffery61cab6f2023-04-13 23:28:48 +09301757 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301758}
1759
1760int encode_get_sensor_reading_req(uint8_t instance_id, uint16_t sensor_id,
1761 uint8_t rearm_event_state,
1762 struct pldm_msg *msg)
1763{
1764 if (msg == NULL) {
1765 return PLDM_ERROR_INVALID_DATA;
1766 }
1767
1768 struct pldm_header_info header = {0};
1769 header.msg_type = PLDM_REQUEST;
1770 header.instance = instance_id;
1771 header.pldm_type = PLDM_PLATFORM;
1772 header.command = PLDM_GET_SENSOR_READING;
1773
1774 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1775 if (rc != PLDM_SUCCESS) {
1776 return rc;
1777 }
1778
1779 struct pldm_get_sensor_reading_req *request =
1780 (struct pldm_get_sensor_reading_req *)msg->payload;
1781
1782 request->sensor_id = htole16(sensor_id);
1783 request->rearm_event_state = rearm_event_state;
1784
1785 return PLDM_SUCCESS;
1786}
1787
1788int decode_get_sensor_reading_resp(
1789 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
1790 uint8_t *sensor_data_size, uint8_t *sensor_operational_state,
1791 uint8_t *sensor_event_message_enable, uint8_t *present_state,
1792 uint8_t *previous_state, uint8_t *event_state, uint8_t *present_reading)
1793{
Andrew Jeffery840b1402023-04-13 23:54:44 +09301794 struct pldm_msgbuf _buf;
1795 struct pldm_msgbuf *buf = &_buf;
1796 int rc;
1797
Andrew Jeffery9c766792022-08-10 23:12:49 +09301798 if (msg == NULL || completion_code == NULL ||
1799 sensor_data_size == NULL || sensor_operational_state == NULL ||
1800 sensor_event_message_enable == NULL || present_state == NULL ||
1801 previous_state == NULL || event_state == NULL ||
1802 present_reading == NULL) {
1803 return PLDM_ERROR_INVALID_DATA;
1804 }
1805
Andrew Jeffery840b1402023-04-13 23:54:44 +09301806 rc = pldm_msgbuf_init(buf, PLDM_GET_SENSOR_READING_MIN_RESP_BYTES,
1807 msg->payload, payload_length);
1808 if (rc) {
1809 return rc;
1810 }
1811
1812 rc = pldm_msgbuf_extract(buf, completion_code);
1813 if (rc) {
1814 return rc;
1815 }
1816
Andrew Jeffery9c766792022-08-10 23:12:49 +09301817 if (PLDM_SUCCESS != *completion_code) {
1818 return PLDM_SUCCESS;
1819 }
1820
Andrew Jeffery840b1402023-04-13 23:54:44 +09301821 rc = pldm_msgbuf_extract(buf, sensor_data_size);
1822 if (rc) {
1823 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301824 }
1825
Andrew Jeffery840b1402023-04-13 23:54:44 +09301826 if (*sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) {
Andrew Jeffery9c766792022-08-10 23:12:49 +09301827 return PLDM_ERROR_INVALID_DATA;
1828 }
1829
Andrew Jeffery840b1402023-04-13 23:54:44 +09301830 pldm_msgbuf_extract(buf, sensor_operational_state);
1831 pldm_msgbuf_extract(buf, sensor_event_message_enable);
1832 pldm_msgbuf_extract(buf, present_state);
1833 pldm_msgbuf_extract(buf, previous_state);
1834 pldm_msgbuf_extract(buf, event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301835
Andrew Jeffery840b1402023-04-13 23:54:44 +09301836 pldm_msgbuf_extract_sensor_value(buf, *sensor_data_size,
1837 present_reading);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301838
Andrew Jeffery840b1402023-04-13 23:54:44 +09301839 return pldm_msgbuf_destroy_consumed(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301840}
1841
1842int encode_get_sensor_reading_resp(
1843 uint8_t instance_id, uint8_t completion_code, uint8_t sensor_data_size,
1844 uint8_t sensor_operational_state, uint8_t sensor_event_message_enable,
1845 uint8_t present_state, uint8_t previous_state, uint8_t event_state,
Andrew Jefferydebe6b32023-04-05 20:30:46 +09301846 const uint8_t *present_reading, struct pldm_msg *msg, size_t payload_length)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301847{
1848 if (msg == NULL || present_reading == NULL) {
1849 return PLDM_ERROR_INVALID_DATA;
1850 }
1851
1852 if (sensor_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
1853 return PLDM_ERROR_INVALID_DATA;
1854 }
1855
1856 struct pldm_header_info header = {0};
1857 header.msg_type = PLDM_RESPONSE;
1858 header.instance = instance_id;
1859 header.pldm_type = PLDM_PLATFORM;
1860 header.command = PLDM_GET_SENSOR_READING;
1861
1862 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1863 if (rc != PLDM_SUCCESS) {
1864 return rc;
1865 }
1866
1867 struct pldm_get_sensor_reading_resp *response =
1868 (struct pldm_get_sensor_reading_resp *)msg->payload;
1869
1870 response->completion_code = completion_code;
1871 response->sensor_data_size = sensor_data_size;
1872 response->sensor_operational_state = sensor_operational_state;
1873 response->sensor_event_message_enable = sensor_event_message_enable;
1874 response->present_state = present_state;
1875 response->previous_state = previous_state;
1876 response->event_state = event_state;
1877
1878 if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT8 ||
1879 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT8) {
1880 if (payload_length != PLDM_GET_SENSOR_READING_MIN_RESP_BYTES) {
1881 return PLDM_ERROR_INVALID_LENGTH;
1882 }
1883 response->present_reading[0] = *present_reading;
1884
1885 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT16 ||
1886 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT16) {
1887 if (payload_length !=
1888 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 1) {
1889 return PLDM_ERROR_INVALID_LENGTH;
1890 }
1891 uint16_t val = *(uint16_t *)present_reading;
1892 val = htole16(val);
1893 memcpy(response->present_reading, &val, 2);
1894
1895 } else if (sensor_data_size == PLDM_EFFECTER_DATA_SIZE_UINT32 ||
1896 sensor_data_size == PLDM_EFFECTER_DATA_SIZE_SINT32) {
1897 if (payload_length !=
1898 PLDM_GET_SENSOR_READING_MIN_RESP_BYTES + 3) {
1899 return PLDM_ERROR_INVALID_LENGTH;
1900 }
1901 uint32_t val = *(uint32_t *)present_reading;
1902 val = htole32(val);
1903 memcpy(response->present_reading, &val, 4);
1904 }
1905
1906 return PLDM_SUCCESS;
1907}
1908
1909int decode_get_sensor_reading_req(const struct pldm_msg *msg,
1910 size_t payload_length, uint16_t *sensor_id,
1911 uint8_t *rearm_event_state)
1912{
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09301913 struct pldm_msgbuf _buf;
1914 struct pldm_msgbuf *buf = &_buf;
1915 int rc;
1916
Andrew Jeffery9c766792022-08-10 23:12:49 +09301917 if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) {
1918 return PLDM_ERROR_INVALID_DATA;
1919 }
1920
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09301921 rc = pldm_msgbuf_init(buf, PLDM_GET_SENSOR_READING_REQ_BYTES,
1922 msg->payload, payload_length);
1923 if (rc) {
1924 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301925 }
1926
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09301927 pldm_msgbuf_extract(buf, sensor_id);
1928 pldm_msgbuf_extract(buf, rearm_event_state);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301929
Andrew Jeffery2d1d1bd2023-04-13 23:58:05 +09301930 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301931}
1932
1933int encode_set_event_receiver_req(uint8_t instance_id,
1934 uint8_t event_message_global_enable,
1935 uint8_t transport_protocol_type,
1936 uint8_t event_receiver_address_info,
1937 uint16_t heartbeat_timer,
1938 struct pldm_msg *msg)
1939{
1940 if (msg == NULL) {
1941 return PLDM_ERROR_INVALID_DATA;
1942 }
1943
1944 if (transport_protocol_type != PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
1945 return PLDM_ERROR_INVALID_DATA;
1946 }
1947
1948 struct pldm_header_info header = {0};
1949 header.msg_type = PLDM_REQUEST;
1950 header.instance = instance_id;
1951 header.pldm_type = PLDM_PLATFORM;
1952 header.command = PLDM_SET_EVENT_RECEIVER;
1953
1954 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
1955 if (rc != PLDM_SUCCESS) {
1956 return rc;
1957 }
1958
1959 struct pldm_set_event_receiver_req *request =
1960 (struct pldm_set_event_receiver_req *)msg->payload;
1961 request->event_message_global_enable = event_message_global_enable;
1962
1963 request->transport_protocol_type = transport_protocol_type;
1964 request->event_receiver_address_info = event_receiver_address_info;
1965
1966 if (event_message_global_enable ==
1967 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) {
1968 if (heartbeat_timer == 0) {
1969 return PLDM_ERROR_INVALID_DATA;
1970 }
1971 request->heartbeat_timer = htole16(heartbeat_timer);
1972 }
1973
1974 return PLDM_SUCCESS;
1975}
1976
1977int decode_set_event_receiver_resp(const struct pldm_msg *msg,
1978 size_t payload_length,
1979 uint8_t *completion_code)
1980{
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09301981 struct pldm_msgbuf _buf;
1982 struct pldm_msgbuf *buf = &_buf;
1983 int rc;
1984
Andrew Jeffery9c766792022-08-10 23:12:49 +09301985 if (msg == NULL || completion_code == NULL) {
1986 return PLDM_ERROR_INVALID_DATA;
1987 }
1988
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09301989 rc = pldm_msgbuf_init(buf, PLDM_SET_EVENT_RECEIVER_RESP_BYTES,
1990 msg->payload, payload_length);
1991 if (rc) {
1992 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301993 }
1994
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09301995 pldm_msgbuf_extract(buf, completion_code);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301996
Andrew Jeffery42dd4e52023-04-14 00:04:38 +09301997 return pldm_msgbuf_destroy(buf);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301998}
1999
2000int decode_set_event_receiver_req(const struct pldm_msg *msg,
2001 size_t payload_length,
2002 uint8_t *event_message_global_enable,
2003 uint8_t *transport_protocol_type,
2004 uint8_t *event_receiver_address_info,
2005 uint16_t *heartbeat_timer)
2006
2007{
Andrew Jeffery9667f582023-04-14 00:39:21 +09302008 struct pldm_msgbuf _buf;
2009 struct pldm_msgbuf *buf = &_buf;
2010 int rc;
2011
Andrew Jeffery9c766792022-08-10 23:12:49 +09302012 if (msg == NULL || event_message_global_enable == NULL ||
2013 transport_protocol_type == NULL ||
2014 event_receiver_address_info == NULL || heartbeat_timer == NULL) {
2015 return PLDM_ERROR_INVALID_DATA;
2016 }
2017
Andrew Jeffery9667f582023-04-14 00:39:21 +09302018 rc = pldm_msgbuf_init(buf, PLDM_SET_EVENT_RECEIVER_REQ_BYTES,
2019 msg->payload, payload_length);
2020 if (rc) {
2021 return rc;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302022 }
2023
Andrew Jeffery9667f582023-04-14 00:39:21 +09302024 pldm_msgbuf_extract(buf, event_message_global_enable);
2025 pldm_msgbuf_extract(buf, transport_protocol_type);
2026 pldm_msgbuf_extract(buf, event_receiver_address_info);
2027 pldm_msgbuf_extract(buf, heartbeat_timer);
Andrew Jeffery9c766792022-08-10 23:12:49 +09302028
Andrew Jeffery9667f582023-04-14 00:39:21 +09302029 rc = pldm_msgbuf_destroy(buf);
2030 if (rc) {
2031 return rc;
2032 }
Andrew Jeffery6ef2aa92023-04-14 00:21:27 +09302033
Andrew Jeffery9c766792022-08-10 23:12:49 +09302034 if ((*event_message_global_enable ==
2035 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE) &&
2036 (*heartbeat_timer == 0)) {
2037 return PLDM_ERROR_INVALID_DATA;
2038 }
2039
Andrew Jeffery9c766792022-08-10 23:12:49 +09302040 return PLDM_SUCCESS;
2041}
2042
2043int encode_set_event_receiver_resp(uint8_t instance_id, uint8_t completion_code,
2044 struct pldm_msg *msg)
2045
2046{
2047 if (msg == NULL) {
2048 return PLDM_ERROR_INVALID_DATA;
2049 }
2050
2051 struct pldm_header_info header = {0};
2052 header.instance = instance_id;
2053 header.msg_type = PLDM_RESPONSE;
2054 header.pldm_type = PLDM_PLATFORM;
2055 header.command = PLDM_SET_EVENT_RECEIVER;
2056
2057 uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
2058 if (rc != PLDM_SUCCESS) {
2059 return rc;
2060 }
2061
2062 msg->payload[0] = completion_code;
2063
2064 return PLDM_SUCCESS;
2065}
Thu Nguyen159a98b2022-11-02 10:00:10 +07002066
2067int encode_poll_for_platform_event_message_req(uint8_t instance_id,
2068 uint8_t format_version,
2069 uint8_t transfer_operation_flag,
2070 uint32_t data_transfer_handle,
2071 uint16_t event_id_to_acknowledge,
2072 struct pldm_msg *msg,
2073 size_t payload_length)
2074{
2075 struct pldm_msgbuf _buf;
2076 struct pldm_msgbuf *buf = &_buf;
2077 int rc;
2078
2079 if (msg == NULL) {
2080 return PLDM_ERROR_INVALID_DATA;
2081 }
2082
2083 struct pldm_header_info header = {0};
2084 header.msg_type = PLDM_REQUEST;
2085 header.instance = instance_id;
2086 header.pldm_type = PLDM_PLATFORM;
2087 header.command = PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE;
2088
2089 rc = pack_pldm_header(&header, &(msg->hdr));
2090 if (rc != PLDM_SUCCESS) {
2091 return rc;
2092 }
2093
2094 rc = pldm_msgbuf_init(
2095 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2096 msg->payload, payload_length);
2097 if (rc) {
2098 return rc;
2099 }
2100
2101 pldm_msgbuf_insert(buf, format_version);
2102 pldm_msgbuf_insert(buf, transfer_operation_flag);
2103 pldm_msgbuf_insert(buf, data_transfer_handle);
2104 pldm_msgbuf_insert(buf, event_id_to_acknowledge);
2105
2106 return pldm_msgbuf_destroy(buf);
2107}
2108
2109int decode_poll_for_platform_event_message_resp(
2110 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
2111 uint8_t *tid, uint16_t *event_id, uint32_t *next_data_transfer_handle,
2112 uint8_t *transfer_flag, uint8_t *event_class, uint32_t *event_data_size,
2113 void **event_data, uint32_t *event_data_integrity_checksum)
2114{
2115 struct pldm_msgbuf _buf;
2116 struct pldm_msgbuf *buf = &_buf;
2117 int rc;
2118
2119 if (msg == NULL || completion_code == NULL || tid == NULL ||
2120 event_id == NULL || next_data_transfer_handle == NULL ||
2121 transfer_flag == NULL || event_class == NULL ||
2122 event_data_size == NULL || event_data == NULL ||
2123 event_data_integrity_checksum == NULL) {
2124 return PLDM_ERROR_INVALID_DATA;
2125 }
2126
2127 rc = pldm_msgbuf_init(
2128 buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
2129 msg->payload, payload_length);
2130 if (rc) {
2131 return rc;
2132 }
2133
2134 rc = pldm_msgbuf_extract(buf, completion_code);
2135 if (rc) {
2136 return rc;
2137 }
2138 if (PLDM_SUCCESS != *completion_code) {
2139 return *completion_code;
2140 }
2141
2142 pldm_msgbuf_extract(buf, tid);
2143 rc = pldm_msgbuf_extract(buf, event_id);
2144 if (rc) {
2145 return rc;
2146 }
2147 if ((*event_id == 0) || (*event_id == 0xffff)) {
2148 return PLDM_SUCCESS;
2149 }
2150
2151 pldm_msgbuf_extract(buf, next_data_transfer_handle);
2152 rc = pldm_msgbuf_extract(buf, transfer_flag);
2153 if (rc) {
2154 return rc;
2155 }
2156
2157 pldm_msgbuf_extract(buf, event_class);
2158 rc = pldm_msgbuf_extract(buf, event_data_size);
2159 if (rc) {
2160 return rc;
2161 }
2162 if (*event_data_size > payload_length) {
2163 return PLDM_ERROR_INVALID_DATA;
2164 }
2165
2166 if (*event_data_size > 0) {
2167 pldm_msgbuf_span_required(buf, *event_data_size, event_data);
2168 }
2169
2170 if (*transfer_flag == PLDM_END ||
2171 *transfer_flag == PLDM_START_AND_END) {
2172 pldm_msgbuf_extract(buf, event_data_integrity_checksum);
2173 }
2174
2175 return pldm_msgbuf_destroy_consumed(buf);
2176}